diff --git a/src/mol-plugin-ui/controls/screenshot.tsx b/src/mol-plugin-ui/controls/screenshot.tsx index 90be286e6a7955ff67bd4024532440124fb6e0c7..3d79a786f49152bb3ca050d02b244acb35dd9226 100644 --- a/src/mol-plugin-ui/controls/screenshot.tsx +++ b/src/mol-plugin-ui/controls/screenshot.tsx @@ -1,7 +1,8 @@ /** - * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> + * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import * as React from 'react'; @@ -24,9 +25,8 @@ export interface ScreenshotPreviewProps { const _ScreenshotPreview = (props: ScreenshotPreviewProps) => { const { plugin, cropFrameColor } = props; - const helper = plugin.helpers.viewportScreenshot; - if (!helper) return null; + const helper = plugin.helpers.viewportScreenshot; const [currentCanvas, setCurrentCanvas] = useState<HTMLCanvasElement | null>(null); const canvasRef = useRef<HTMLCanvasElement | null>(null); const propsRef = useRef(props); @@ -53,7 +53,7 @@ const _ScreenshotPreview = (props: ScreenshotPreviewProps) => { function preview() { const p = propsRef.current; if (!p.suspend && canvasRef.current) { - drawPreview(helper!, canvasRef.current, p.customBackground, p.borderColor, p.borderWidth); + drawPreview(helper, canvasRef.current, p.customBackground, p.borderColor, p.borderWidth); } if (!canvasRef.current) isDirty = true; @@ -71,8 +71,8 @@ const _ScreenshotPreview = (props: ScreenshotPreviewProps) => { subscribe(plugin.state.data.behaviors.isUpdating, v => { if (!v) isDirty = true; }); - subscribe(helper.behaviors.values, () => isDirty = true); - subscribe(helper.behaviors.cropParams, () => isDirty = true); + subscribe(helper?.behaviors.values, () => isDirty = true); + subscribe(helper?.behaviors.cropParams, () => isDirty = true); let resizeObserver: any = void 0; if (typeof ResizeObserver !== 'undefined') { @@ -109,7 +109,9 @@ export const ScreenshotPreview = React.memo(_ScreenshotPreview, (prev, next) => declare const ResizeObserver: any; -function drawPreview(helper: ViewportScreenshotHelper, target: HTMLCanvasElement, customBackground?: string, borderColor?: string, borderWidth?: number) { +function drawPreview(helper: ViewportScreenshotHelper | undefined, target: HTMLCanvasElement, customBackground?: string, borderColor?: string, borderWidth?: number) { + if (!helper) return; + const { canvas, width, height } = helper.getPreview()!; const ctx = target.getContext('2d'); if (!ctx) return; @@ -152,11 +154,9 @@ function drawPreview(helper: ViewportScreenshotHelper, target: HTMLCanvasElement function ViewportFrame({ plugin, canvas, color = 'rgba(255, 87, 45, 0.75)' }: { plugin: PluginContext, canvas: HTMLCanvasElement | null, color?: string }) { const helper = plugin.helpers.viewportScreenshot; - if (!helper || !canvas) return null; - - const params = useBehavior(helper.behaviors.values); - const cropParams = useBehavior(helper.behaviors.cropParams); - const crop = useBehavior(helper.behaviors.relativeCrop!); + const params = useBehavior(helper?.behaviors.values); + const cropParams = useBehavior(helper?.behaviors.cropParams); + const crop = useBehavior(helper?.behaviors.relativeCrop); const cropFrameRef = useRef<Viewport>({ x: 0, y: 0, width: 0, height: 0 }); useBehavior(params?.resolution.name === 'viewport' ? plugin.canvas3d?.resized : void 0); @@ -164,6 +164,8 @@ function ViewportFrame({ plugin, canvas, color = 'rgba(255, 87, 45, 0.75)' }: { const [start, setStart] = useState([0, 0]); const [current, setCurrent] = useState([0, 0]); + if (!helper || !canvas || !crop) return null; + const { width, height } = helper.getSizeAndViewport(); const frame = getViewportFrame(width, height, canvas.clientWidth, canvas.clientHeight); @@ -268,7 +270,7 @@ function ViewportFrame({ plugin, canvas, color = 'rgba(255, 87, 45, 0.75)' }: { function finish() { const cropFrame = cropFrameRef.current; - if (cropParams.auto) { + if (cropParams?.auto) { helper?.behaviors.cropParams.next({ ...cropParams, auto: false }); } helper?.behaviors.relativeCrop.next({ diff --git a/src/mol-plugin-ui/left-panel.tsx b/src/mol-plugin-ui/left-panel.tsx index 32477e580739e3388dbf0763db542fb97eb3c09c..62db9be7c613c82d0d1e8974d3523437aca376cf 100644 --- a/src/mol-plugin-ui/left-panel.tsx +++ b/src/mol-plugin-ui/left-panel.tsx @@ -141,11 +141,13 @@ class FullSettings extends PluginUIComponent { this.subscribe(this.plugin.events.canvas3d.settingsUpdated, () => this.forceUpdate()); this.subscribe(this.plugin.layout.events.updated, () => this.forceUpdate()); - this.subscribe(this.plugin.canvas3d!.camera.stateChanged, state => { - if (state.radiusMax !== undefined || state.radius !== undefined) { - this.forceUpdate(); - } - }); + if (this.plugin.canvas3d) { + this.subscribe(this.plugin.canvas3d.camera.stateChanged, state => { + if (state.radiusMax !== undefined || state.radius !== undefined) { + this.forceUpdate(); + } + }); + } } render() { diff --git a/src/mol-plugin-ui/viewport/screenshot.tsx b/src/mol-plugin-ui/viewport/screenshot.tsx index bf4335cbfcca097f390af9d6c51eefd71508208b..9158ef2b58961341f817a5bca89c5b663f28c477 100644 --- a/src/mol-plugin-ui/viewport/screenshot.tsx +++ b/src/mol-plugin-ui/viewport/screenshot.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> * @author David Sehnal <david.sehnal@gmail.com> @@ -97,20 +97,20 @@ export class DownloadScreenshotControls extends PluginUIComponent<{ close: () => function ScreenshotParams({ plugin, isDisabled }: { plugin: PluginContext, isDisabled: boolean }) { const helper = plugin.helpers.viewportScreenshot; + + const values = useBehavior(helper?.behaviors.values); if (!helper) return null; - const values = useBehavior(helper.behaviors.values); return <ParameterControls params={helper.params} values={values} onChangeValues={v => helper.behaviors.values.next(v)} isDisabled={isDisabled} />; } function CropControls({ plugin }: { plugin: PluginContext }) { const helper = plugin.helpers.viewportScreenshot; - if (!helper) return null; - const cropParams = useBehavior(helper.behaviors.cropParams); + const cropParams = useBehavior(helper?.behaviors.cropParams); useBehavior(helper?.behaviors.relativeCrop); - if (!helper) return null; + if (!helper || !cropParams) return null; return <div style={{ width: '100%', height: '24px', marginTop: '8px' }}> <ToggleButton icon={CropOrginalSvg} title='Auto-crop' inline isSelected={cropParams.auto}