mirror of
https://github.com/molstar/molstar.git
synced 2026-06-04 13:30:24 +08:00
better canvas background handling
This commit is contained in:
@@ -30,6 +30,8 @@ Note that since we don't clearly distinguish between a public and private interf
|
||||
- Fix `flipSided` for meshes
|
||||
- Add `label/auth_comp_id` to `StructureProperties.residue`
|
||||
- Previously, this has been only been present on `.atom` (since residue name can alter on per-atom basis), but this has been a bit confusing for the general use-case
|
||||
- Move canvas "checked background" logic to `canvas3d.ts` and only apply it when `transparentBackground` is on
|
||||
- This prevents an ugly flicked during plugin initialization
|
||||
|
||||
## [v5.4.2] - 2025-12-07
|
||||
- Fix postprocessing issues with SSAO and outlines for large structures (#1387)
|
||||
|
||||
1
breaking-v6-changes.md
Normal file
1
breaking-v6-changes.md
Normal file
@@ -0,0 +1 @@
|
||||
- Remove `checkeredCanvasBackground` from `PluginContext` and `PluginContainer`
|
||||
@@ -83,6 +83,9 @@ export class Viewer {
|
||||
}
|
||||
|
||||
const spec: PluginUISpec = {
|
||||
canvas3d: {
|
||||
...defaultSpec.canvas3d,
|
||||
},
|
||||
actions: defaultSpec.actions,
|
||||
behaviors: [
|
||||
...baseBehaviors,
|
||||
|
||||
@@ -6,12 +6,16 @@
|
||||
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
||||
<title>Mol* Viewer MolViewSpec Example</title>
|
||||
<style>
|
||||
body {
|
||||
background: #111318;
|
||||
}
|
||||
|
||||
#app {
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
top: 100px;
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#controls {
|
||||
@@ -23,7 +27,7 @@
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
z-index: 10;
|
||||
background-color: black;
|
||||
background-color: #111318;
|
||||
padding: 10px;
|
||||
color: white;
|
||||
}
|
||||
@@ -96,7 +100,7 @@
|
||||
})
|
||||
|
||||
builder.canvas({
|
||||
background_color: "black",
|
||||
background_color: "#111318",
|
||||
})
|
||||
|
||||
structure.primitives()
|
||||
|
||||
@@ -96,6 +96,7 @@ export const Canvas3DParams = {
|
||||
cameraResetDurationMs: PD.Numeric(250, { min: 0, max: 1000, step: 1 }, { description: 'The time it takes to reset the camera.' }),
|
||||
sceneRadiusFactor: PD.Numeric(1, { min: 1, max: 10, step: 0.1 }),
|
||||
transparentBackground: PD.Boolean(false),
|
||||
checkeredTransparentBackground: PD.Boolean(false),
|
||||
dpoitIterations: PD.Numeric(2, { min: 1, max: 10, step: 1 }),
|
||||
pickPadding: PD.Numeric(3, { min: 0, max: 10, step: 1 }, { description: 'Extra pixels to around target to check in case target is empty.' }),
|
||||
userInteractionReleaseMs: PD.Numeric(250, { min: 0, max: 1000, step: 1 }, { description: 'The time before the user is not considered interacting anymore.' }),
|
||||
@@ -405,6 +406,22 @@ const cancelAnimationFrame = typeof window !== 'undefined'
|
||||
? window.cancelAnimationFrame
|
||||
: (handle: number) => clearImmediate(handle as unknown as NodeJS.Immediate);
|
||||
|
||||
function syncCanvasBackground(canvas: HTMLCanvasElement, canvasProps: Canvas3DProps) {
|
||||
if (canvasProps.transparentBackground && canvasProps.checkeredTransparentBackground) {
|
||||
Object.assign(canvas.style, {
|
||||
'background-image': 'linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey), linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey)',
|
||||
'background-size': '60px 60px',
|
||||
'background-position': '0 0, 30px 30px'
|
||||
});
|
||||
} else {
|
||||
Object.assign(canvas.style, {
|
||||
'background-image': '',
|
||||
'background-size': '',
|
||||
'background-position': ''
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
namespace Canvas3D {
|
||||
export interface HoverEvent { current: Representation.Loci, buttons: ButtonsType, button: ButtonsType.Flag, modifiers: ModifiersKeys, page?: Vec2, position?: Vec3 }
|
||||
export interface DragEvent { current: Representation.Loci, buttons: ButtonsType, button: ButtonsType.Flag, modifiers: ModifiersKeys, pageStart: Vec2, pageEnd: Vec2 }
|
||||
@@ -435,6 +452,7 @@ namespace Canvas3D {
|
||||
let forceNextRender = false;
|
||||
let currentTime = 0;
|
||||
|
||||
syncCanvasBackground(canvas!, p);
|
||||
updateViewport();
|
||||
const scene = Scene.create(webgl, passes.draw.transparency, {
|
||||
dColorMarker: p.renderer.colorMarker,
|
||||
@@ -1061,6 +1079,7 @@ namespace Canvas3D {
|
||||
cameraResetDurationMs: p.cameraResetDurationMs,
|
||||
sceneRadiusFactor: p.sceneRadiusFactor,
|
||||
transparentBackground: p.transparentBackground,
|
||||
checkeredTransparentBackground: p.checkeredTransparentBackground,
|
||||
dpoitIterations: p.dpoitIterations,
|
||||
pickPadding: p.pickPadding,
|
||||
userInteractionReleaseMs: p.userInteractionReleaseMs,
|
||||
@@ -1311,6 +1330,7 @@ namespace Canvas3D {
|
||||
}
|
||||
if (props.cameraResetDurationMs !== undefined) p.cameraResetDurationMs = props.cameraResetDurationMs;
|
||||
if (props.transparentBackground !== undefined) p.transparentBackground = props.transparentBackground;
|
||||
if (props.checkeredTransparentBackground !== undefined) p.checkeredTransparentBackground = props.checkeredTransparentBackground;
|
||||
if (props.dpoitIterations !== undefined) p.dpoitIterations = props.dpoitIterations;
|
||||
if (props.pickPadding !== undefined) {
|
||||
p.pickPadding = props.pickPadding;
|
||||
@@ -1357,6 +1377,12 @@ namespace Canvas3D {
|
||||
p.camera.stereo.name = 'off';
|
||||
}
|
||||
|
||||
if ('transparentBackground' in props
|
||||
|| 'checkeredTransparentBackground' in props
|
||||
|| (props.renderer && 'backgroundColor' in props.renderer)) {
|
||||
syncCanvasBackground(canvas!, p);
|
||||
}
|
||||
|
||||
shaderManager.updateRequired(p);
|
||||
if (!doNotRequestDraw) {
|
||||
requestDraw();
|
||||
|
||||
@@ -22,27 +22,6 @@
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.msp-viewport-host3d {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
-webkit-touch-callout: none;
|
||||
touch-action: manipulation;
|
||||
|
||||
>canvas {
|
||||
background-color: $default-background;
|
||||
background-image: linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey),
|
||||
linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey);
|
||||
background-size: 60px 60px;
|
||||
background-position: 0 0, 30px 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.msp-viewport-controls {
|
||||
position: absolute;
|
||||
right: $control-spacing;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2024 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2024-25 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
*
|
||||
* @author David Sehnal <david.sehnal@gmail.com>
|
||||
*/
|
||||
@@ -19,6 +19,10 @@ export class PluginContainer {
|
||||
this.parent.parentElement?.removeChild(this.parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* options.checkeredCanvasBackground has no effect. Use canvas3d.checkeredTransparentBackground instead.
|
||||
* TODO: remove in v6
|
||||
*/
|
||||
constructor(public options?: { checkeredCanvasBackground?: boolean, canvas?: HTMLCanvasElement }) {
|
||||
const parent = document.createElement('div');
|
||||
Object.assign(parent.style, {
|
||||
@@ -36,13 +40,6 @@ export class PluginContainer {
|
||||
let canvas = options?.canvas;
|
||||
if (!canvas) {
|
||||
canvas = document.createElement('canvas');
|
||||
if (options?.checkeredCanvasBackground) {
|
||||
Object.assign(canvas.style, {
|
||||
'background-image': 'linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey), linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%, lightgrey)',
|
||||
'background-size': '60px 60px',
|
||||
'background-position': '0 0, 30px 30px'
|
||||
});
|
||||
}
|
||||
parent.appendChild(canvas);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2024 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
||||
* Copyright (c) 2018-2025 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>
|
||||
@@ -246,6 +246,9 @@ export class PluginContext {
|
||||
if (!this._initViewer(container.canvas, container.parent, options?.canvas3dContext)) {
|
||||
return false;
|
||||
}
|
||||
if (options?.checkeredCanvasBackground) {
|
||||
this.canvas3d?.setProps({ checkeredTransparentBackground: true });
|
||||
}
|
||||
this.container = container;
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user