Skip to content
Snippets Groups Projects
Commit 03dbb067 authored by Alexander Rose's avatar Alexander Rose
Browse files

wip, canvas example

parent fd6b900a
No related branches found
No related tags found
No related merge requests found
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
import * as React from 'react' import * as React from 'react'
import { StructureRepresentation, StructureProps } from 'mol-geo/representation/structure'; import { StructureRepresentation, StructureProps } from 'mol-geo/representation/structure';
import Viewer from 'mol-view/viewer'; import Viewer from 'mol-view/viewer';
import { VisualQuality } from 'mol-geo/representation/util';
export interface StructureRepresentationComponentProps { export interface StructureRepresentationComponentProps {
viewer: Viewer viewer: Viewer
...@@ -16,12 +17,14 @@ export interface StructureRepresentationComponentProps { ...@@ -16,12 +17,14 @@ export interface StructureRepresentationComponentProps {
export interface StructureRepresentationComponentState { export interface StructureRepresentationComponentState {
label: string label: string
visible: boolean visible: boolean
quality: VisualQuality
} }
export class StructureRepresentationComponent extends React.Component<StructureRepresentationComponentProps, StructureRepresentationComponentState> { export class StructureRepresentationComponent extends React.Component<StructureRepresentationComponentProps, StructureRepresentationComponentState> {
state = { state = {
label: this.props.representation.label, label: this.props.representation.label,
visible: this.props.representation.props.visible, visible: this.props.representation.props.visible,
quality: this.props.representation.props.quality,
} }
componentWillMount() { componentWillMount() {
...@@ -31,27 +34,31 @@ export class StructureRepresentationComponent extends React.Component<StructureR ...@@ -31,27 +34,31 @@ export class StructureRepresentationComponent extends React.Component<StructureR
...this.state, ...this.state,
label: repr.label, label: repr.label,
visible: repr.props.visible, visible: repr.props.visible,
quality: repr.props.quality,
}) })
} }
async update(state: Partial<StructureRepresentationComponentState>) { async update(state: Partial<StructureRepresentationComponentState>) {
const repr = this.props.representation const repr = this.props.representation
const props: Partial<StructureProps> = {}
if (state.visible !== undefined) { if (state.visible !== undefined) props.visible = state.visible
await repr.createOrUpdate({ visible: state.visible }).run() if (state.quality !== undefined) props.quality = state.quality
// this.props.viewer.add(repr)
this.props.viewer.requestDraw() await repr.createOrUpdate(props).run()
} this.props.viewer.add(repr)
this.props.viewer.requestDraw()
const newState = { const newState = {
...this.state, ...this.state,
visible: repr.props.visible, visible: repr.props.visible,
quality: repr.props.quality
} }
this.setState(newState) this.setState(newState)
} }
render() { render() {
const { label, visible } = this.state const { label, visible, quality } = this.state
return <div> return <div>
<div> <div>
...@@ -64,6 +71,17 @@ export class StructureRepresentationComponent extends React.Component<StructureR ...@@ -64,6 +71,17 @@ export class StructureRepresentationComponent extends React.Component<StructureR
{visible ? 'Hide' : 'Show'} {visible ? 'Hide' : 'Show'}
</button> </button>
</div> </div>
<div>
<span>Quality</span>
<select value={quality} onChange={(e) => this.update({ quality: e.target.value as VisualQuality }) }>
<option value='auto'>auto</option>
<option value='lowest'>lowest</option>
<option value='low'>low</option>
<option value='medium'>medium</option>
<option value='high'>high</option>
<option value='highest'>highest</option>
</select>
</div>
</div> </div>
</div>; </div>;
} }
......
...@@ -33,7 +33,8 @@ export interface StructureViewComponentState { ...@@ -33,7 +33,8 @@ export interface StructureViewComponentState {
symmetryFeatureId: number symmetryFeatureId: number
symmetryFeatureIds: { id: number, label: string }[] symmetryFeatureIds: { id: number, label: string }[]
structureRepresentations: StructureRepresentation<any>[] active: { [k: string]: boolean }
structureRepresentations: { [k: string]: StructureRepresentation<any> }
} }
export class StructureViewComponent extends React.Component<StructureViewComponentProps, StructureViewComponentState> { export class StructureViewComponent extends React.Component<StructureViewComponentProps, StructureViewComponentState> {
...@@ -46,6 +47,7 @@ export class StructureViewComponent extends React.Component<StructureViewCompone ...@@ -46,6 +47,7 @@ export class StructureViewComponent extends React.Component<StructureViewCompone
symmetryFeatureId: this.props.structureView.symmetryFeatureId, symmetryFeatureId: this.props.structureView.symmetryFeatureId,
symmetryFeatureIds: this.props.structureView.getSymmetryFeatureIds(), symmetryFeatureIds: this.props.structureView.getSymmetryFeatureIds(),
active: this.props.structureView.active,
structureRepresentations: this.props.structureView.structureRepresentations structureRepresentations: this.props.structureView.structureRepresentations
} }
...@@ -62,19 +64,25 @@ export class StructureViewComponent extends React.Component<StructureViewCompone ...@@ -62,19 +64,25 @@ export class StructureViewComponent extends React.Component<StructureViewCompone
symmetryFeatureId: sv.symmetryFeatureId, symmetryFeatureId: sv.symmetryFeatureId,
symmetryFeatureIds: sv.getSymmetryFeatureIds(), symmetryFeatureIds: sv.getSymmetryFeatureIds(),
active: sv.active,
structureRepresentations: sv.structureRepresentations structureRepresentations: sv.structureRepresentations
}) })
} }
componentDidMount() { componentDidMount() {
this.props.structureView.structureRepresentationsUpdated.subscribe(() => this.setState({ const sv = this.props.structureView
structureRepresentations: this.props.structureView.structureRepresentations
this.props.structureView.updated.subscribe(() => this.setState({
symmetryFeatureIds: sv.getSymmetryFeatureIds(),
structureRepresentations: sv.structureRepresentations
})) }))
} }
async update(state: Partial<StructureViewComponentState>) { async update(state: Partial<StructureViewComponentState>) {
const sv = this.props.structureView const sv = this.props.structureView
console.log(state)
if (state.modelId !== undefined) await sv.setModel(state.modelId) if (state.modelId !== undefined) await sv.setModel(state.modelId)
if (state.assemblyId !== undefined) await sv.setAssembly(state.assemblyId) if (state.assemblyId !== undefined) await sv.setAssembly(state.assemblyId)
if (state.symmetryFeatureId !== undefined) await sv.setSymmetryFeature(state.symmetryFeatureId) if (state.symmetryFeatureId !== undefined) await sv.setSymmetryFeature(state.symmetryFeatureId)
...@@ -89,13 +97,14 @@ export class StructureViewComponent extends React.Component<StructureViewCompone ...@@ -89,13 +97,14 @@ export class StructureViewComponent extends React.Component<StructureViewCompone
symmetryFeatureId: sv.symmetryFeatureId, symmetryFeatureId: sv.symmetryFeatureId,
symmetryFeatureIds: sv.getSymmetryFeatureIds(), symmetryFeatureIds: sv.getSymmetryFeatureIds(),
active: sv.active,
structureRepresentations: sv.structureRepresentations structureRepresentations: sv.structureRepresentations
} }
this.setState(newState) this.setState(newState)
} }
render() { render() {
const { label, modelIds, assemblyIds, symmetryFeatureIds, structureRepresentations } = this.state const { label, modelIds, assemblyIds, symmetryFeatureIds, active, structureRepresentations } = this.state
const modelIdOptions = modelIds.map(m => { const modelIdOptions = modelIds.map(m => {
return <option key={m.id} value={m.id}>{m.label}</option> return <option key={m.id} value={m.id}>{m.label}</option>
...@@ -122,6 +131,16 @@ export class StructureViewComponent extends React.Component<StructureViewCompone ...@@ -122,6 +131,16 @@ export class StructureViewComponent extends React.Component<StructureViewCompone
> >
{modelIdOptions} {modelIdOptions}
</select> </select>
<input type='range'
value={this.state.modelId}
min={Math.min(...modelIds.map(m => m.id))}
max={Math.max(...modelIds.map(m => m.id))}
step='1'
onInput={(e) => {
this.update({ modelId: parseInt(e.currentTarget.value) })
}}
>
</input>
</div> </div>
<div> <div>
<span>Assembly</span> <span>Assembly</span>
...@@ -145,15 +164,39 @@ export class StructureViewComponent extends React.Component<StructureViewCompone ...@@ -145,15 +164,39 @@ export class StructureViewComponent extends React.Component<StructureViewCompone
{symmetryFeatureIdOptions} {symmetryFeatureIdOptions}
</select> </select>
</div> </div>
<div>
<h4>Active</h4>
{ Object.keys(active).map((k, i) => {
return <div key={i}>
<input
type='checkbox'
checked={active[k]}
onChange={(e) => {
const sv = this.props.structureView
if (k === 'symmetryAxes') {
sv.setSymmetryAxes(e.target.checked)
} else if (Object.keys(sv.structureRepresentations).includes(k)) {
sv.setStructureRepresentation(k, e.target.checked)
}
}}
/> {k}
</div>
} ) }
</div>
<div> <div>
<h3>Structure Representations</h3> <h3>Structure Representations</h3>
{ structureRepresentations ? structureRepresentations.map((r, i) => { Object.keys(structureRepresentations).map((k, i) => {
<div key={i}> if (active[k]) {
<StructureRepresentationComponent return <div key={i}>
representation={r} <StructureRepresentationComponent
viewer={this.props.structureView.viewer} representation={structureRepresentations[k]}
/> viewer={this.props.structureView.viewer}
</div>) : '' } />
</div>
} else {
return ''
}
} ) }
</div> </div>
</div> </div>
</div>; </div>;
......
...@@ -5,16 +5,16 @@ ...@@ -5,16 +5,16 @@
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<title>Mol* Canvas</title> <title>Mol* Canvas</title>
<style> <style>
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
html, body { html, body {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
} }
</style> </style>
</head> </head>
<body> <body>
<div id="app" style="width: 100%; height: 100%"></div> <div id="app" style="width: 100%; height: 100%"></div>
......
...@@ -31,10 +31,14 @@ export interface StructureView { ...@@ -31,10 +31,14 @@ export interface StructureView {
readonly structure: Structure | undefined readonly structure: Structure | undefined
readonly assemblySymmetry: AssemblySymmetry | undefined readonly assemblySymmetry: AssemblySymmetry | undefined
readonly structureRepresentations: StructureRepresentation<any>[] readonly active: { [k: string]: boolean }
readonly structureRepresentationsUpdated: BehaviorSubject<null> readonly structureRepresentations: { [k: string]: StructureRepresentation<any> }
readonly updated: BehaviorSubject<null>
readonly symmetryAxes: ShapeRepresentation<ShapeProps> readonly symmetryAxes: ShapeRepresentation<ShapeProps>
setSymmetryAxes(value: boolean): void
setStructureRepresentation(name: string, value: boolean): void
readonly modelId: number readonly modelId: number
readonly assemblyId: string readonly assemblyId: string
readonly symmetryFeatureId: number readonly symmetryFeatureId: number
...@@ -54,23 +58,29 @@ interface StructureViewProps { ...@@ -54,23 +58,29 @@ interface StructureViewProps {
symmetryFeatureId?: number symmetryFeatureId?: number
} }
export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>, props: StructureViewProps = {}): Promise<StructureView> { export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>, props: StructureViewProps = {}): Promise<StructureView> {
const cartoon = CartoonRepresentation() const active: { [k: string]: boolean } = {
const point = PointRepresentation() cartoon: true,
const ballAndStick = BallAndStickRepresentation() point: false,
const carbohydrate = CarbohydrateRepresentation() ballAndStick: false,
carbohydrate: false,
const structureRepresentations: StructureRepresentation<any>[] = [ symmetryAxes: false,
// cartoon, polymerSphere: false,
point, }
// ballAndStick,
// carbohydrate const structureRepresentations: { [k: string]: StructureRepresentation<any> } = {
] cartoon: CartoonRepresentation(),
point: PointRepresentation(),
ballAndStick: BallAndStickRepresentation(),
carbohydrate: CarbohydrateRepresentation(),
}
const symmetryAxes = ShapeRepresentation() const symmetryAxes = ShapeRepresentation()
const polymerSphere = ShapeRepresentation() const polymerSphere = ShapeRepresentation()
const structureRepresentationsUpdated: BehaviorSubject<null> = new BehaviorSubject<null>(null) const updated: BehaviorSubject<null> = new BehaviorSubject<null>(null)
let label: string let label: string
let model: Model | undefined let model: Model | undefined
...@@ -81,12 +91,30 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model> ...@@ -81,12 +91,30 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
let assemblyId: string let assemblyId: string
let symmetryFeatureId: number let symmetryFeatureId: number
async function setSymmetryAxes(value: boolean) {
if (!value) {
assemblySymmetry = undefined
} else {
await AssemblySymmetry.attachFromCifOrAPI(models[modelId])
assemblySymmetry = AssemblySymmetry.get(models[modelId])
}
active.symmetryAxes = value
await setSymmetryFeature()
}
async function setStructureRepresentation(k: string, value: boolean) {
active[k] = value
await createStructureRepr()
}
async function setModel(newModelId: number, newAssemblyId?: string, newSymmetryFeatureId?: number) { async function setModel(newModelId: number, newAssemblyId?: string, newSymmetryFeatureId?: number) {
console.log('setModel', newModelId) console.log('setModel', newModelId)
modelId = newModelId modelId = newModelId
model = models[modelId] model = models[modelId]
await AssemblySymmetry.attachFromCifOrAPI(model) if (active.symmetryAxes) {
assemblySymmetry = AssemblySymmetry.get(model) await AssemblySymmetry.attachFromCifOrAPI(model)
assemblySymmetry = AssemblySymmetry.get(model)
}
await setAssembly(newAssemblyId, newSymmetryFeatureId) await setAssembly(newAssemblyId, newSymmetryFeatureId)
} }
...@@ -169,8 +197,13 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model> ...@@ -169,8 +197,13 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
async function createStructureRepr() { async function createStructureRepr() {
if (structure) { if (structure) {
console.log('createStructureRepr') console.log('createStructureRepr')
for (let i = 0, il = structureRepresentations.length; i < il; ++i) { for (const k in structureRepresentations) {
await structureRepresentations[i].createOrUpdate({}, structure).run() if (active[k]) {
await structureRepresentations[k].createOrUpdate({}, structure).run()
viewer.add(structureRepresentations[k])
} else {
viewer.remove(structureRepresentations[k])
}
} }
viewer.center(structure.boundary.sphere.center) viewer.center(structure.boundary.sphere.center)
...@@ -197,13 +230,14 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model> ...@@ -197,13 +230,14 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
// useFog: false // TODO fog not working properly // useFog: false // TODO fog not working properly
// }, shape).run() // }, shape).run()
} else { } else {
structureRepresentations.forEach(repr => repr.destroy) for (const k in structureRepresentations) structureRepresentations[k].destroy()
polymerSphere.destroy() polymerSphere.destroy()
} }
structureRepresentations.forEach(repr => viewer.add(repr))
viewer.add(polymerSphere) viewer.add(polymerSphere)
structureRepresentationsUpdated.next(null)
updated.next(null)
viewer.requestDraw()
} }
async function createSymmetryRepr() { async function createSymmetryRepr() {
...@@ -224,16 +258,17 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model> ...@@ -224,16 +258,17 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
// useFog: false // TODO fog not working properly // useFog: false // TODO fog not working properly
// }).run() // }).run()
await symmetryAxes.createOrUpdate({}, axesShape).run() await symmetryAxes.createOrUpdate({}, axesShape).run()
viewer.add(symmetryAxes)
} else { } else {
symmetryAxes.destroy() viewer.remove(symmetryAxes)
} }
} else { } else {
symmetryAxes.destroy() viewer.remove(symmetryAxes)
} }
} else { } else {
symmetryAxes.destroy() viewer.remove(symmetryAxes)
} }
viewer.add(symmetryAxes) updated.next(null)
viewer.requestDraw() viewer.requestDraw()
} }
...@@ -247,10 +282,14 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model> ...@@ -247,10 +282,14 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
get structure() { return structure }, get structure() { return structure },
get assemblySymmetry() { return assemblySymmetry }, get assemblySymmetry() { return assemblySymmetry },
active,
structureRepresentations, structureRepresentations,
structureRepresentationsUpdated, updated,
symmetryAxes, symmetryAxes,
setSymmetryAxes,
setStructureRepresentation,
get modelId() { return modelId }, get modelId() { return modelId },
get assemblyId() { return assemblyId }, get assemblyId() { return assemblyId },
get symmetryFeatureId() { return symmetryFeatureId }, get symmetryFeatureId() { return symmetryFeatureId },
...@@ -263,10 +302,10 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model> ...@@ -263,10 +302,10 @@ export async function StructureView(viewer: Viewer, models: ReadonlyArray<Model>
getSymmetryFeatureIds, getSymmetryFeatureIds,
destroy: () => { destroy: () => {
structureRepresentations.forEach(repr => { for (const k in structureRepresentations) {
viewer.remove(repr) viewer.remove(structureRepresentations[k])
repr.destroy() structureRepresentations[k].destroy()
}) }
viewer.remove(polymerSphere) viewer.remove(polymerSphere)
viewer.remove(symmetryAxes) viewer.remove(symmetryAxes)
viewer.requestDraw() viewer.requestDraw()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment