Published unlisted
Edited
May 4, 2021
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
add_context_listener(regl)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function *createREGLInstance () {
let border_style = "3px solid rgb(224, 224, 224)"
const container = document.createElement('div');
container.classList.add("container");
container.style.position = "relative";
container.style.marginLeft = 'auto';
container.style.marginRight = 'auto';
container.style.width = '100%';
container.style.fontSize = '15px'
if (width > breakpoint) {
container.style.maxWidth = 'none';
}
else {
container.style.maxWidth = 500 + 'px';
}
container.style.overflow = "hidden";
container.style.borderLeft = border_style;
container.style.borderRight = border_style;
container.style.marginBottom = "-0.5rem"
const glCanvas = document.createElement('canvas');
glCanvas.classList.add("glCanvas");
glCanvas.style.position = "relative";
glCanvas.style.top = 0
glCanvas.style.left = 0;
glCanvas.style.width = w + 'px';
glCanvas.style.height = h + 'px';
glCanvas.style.backgroundColor = canvas_color;
glCanvas.style.zIndex = 1;
glCanvas.width = canvas_w;
glCanvas.height = canvas_h;
glCanvas.style.verticalAlign = "bottom";

// used to provide an element to the camera, so it can properly calculate width and height of the 3D area
const cameraDiv = document.createElement('div');
cameraDiv.classList.add("cameraDiv");
cameraDiv.style.position = "absolute";
cameraDiv.style.top = 0
cameraDiv.style.right = 0 + 'px';
cameraDiv.style.width = width_3d_section + 'px';
cameraDiv.style.height = h + 'px';
cameraDiv.style.zIndex = 2;
cameraDiv.style.boxShadow = "rgb(0, 0, 0) 0px 0px 15px inset"
cameraDiv.onmouseover = () => { cameraDiv.style.cursor = "grab" }
cameraDiv.onmousedown = () => { cameraDiv.style.cursor = "grabbing" }
cameraDiv.onmouseup = () => { cameraDiv.style.cursor = "grab" }
cameraDiv.onmouseleave = () => { cameraDiv.style.cursor = "auto" }
if (width > breakpoint) {
cameraDiv.style.display = "block;"
}
else {
cameraDiv.style.display = "none";
}
const topCanvas = document.createElement('canvas');
topCanvas.classList.add("topCanvas");
topCanvas.style.zIndex = 2;
topCanvas.style.boxSizing = "border-box";
topCanvas.style.position = "absolute";
topCanvas.style.borderRight = border_style;
topCanvas.style.cursor = "crosshair";
if (width > breakpoint) {
topCanvas.style.top = 0 + 'px';
topCanvas.style.left = 0 + 'px';
topCanvas.style.width = width_2d_section + 'px';
topCanvas.style.height = h + 'px';
topCanvas.width = width_2d_section;
topCanvas.height = h;
}
else {
topCanvas.style.top = 0 + 'px';
topCanvas.style.left = 0 +'px';
topCanvas.style.width = w + 'px';
topCanvas.style.height = w + 'px';
topCanvas.width = w;
topCanvas.height = h;
}
const controls = document.createElement('div');
controls.classList.add("controls");
controls.style.borderTop = border_style;
controls.style.padding = "15px";
controls.style.fontFamily = "sans-serif";
controls.style.backgroundColor = "white";
if (width > breakpoint) {
controls.style.position = "relative";
controls.style.width = "100%";
}
else {
controls.style.position = "relative";
controls.style.width = "100%";
}
controls.style.zIndex = 3;
function addLabel(text) {
let d = document.createElement('span');
let n = document.createTextNode(text);
d.style.marginLeft = "5px";
d.style.fontSize = "15px"
d.appendChild(n);
return d
}
function addText(text) {
let d = document.createElement('p');
let n = document.createTextNode(text);
d.style.fontFamily = "sans-serif";
d.style.fontSize = "15px"
d.style.marginBottom = "0rem"
d.style.marginTop = "0rem"
d.appendChild(n);
return d
}
controls.appendChild(viewof playToggle);
controls.appendChild(viewof restart);
if (width < breakpoint) {
controls.appendChild(document.createElement('br'));
}
controls.appendChild(addLabel("Visualization:"));
controls.appendChild(viewof selected_visualization);
if (width < breakpoint) {
controls.appendChild(document.createElement('br'));
}
controls.appendChild(addLabel("Potential:"));
controls.appendChild(viewof potential_selection);
if (width > breakpoint) {
controls.appendChild(document.createElement('br'));
controls.appendChild(addText("Click and drag on the 3D view (right) to change the view."))
controls.appendChild(addText("Click and drag on the 2D view (left) to set the initial particle position and direction. Release to start the simulation."));
}
else {
controls.appendChild(document.createElement('br'));
controls.appendChild(addText("Click and drag above to set the initial wavepacket position and direction. Release to start the simulation."));
}
container.appendChild(glCanvas);
container.appendChild(cameraDiv);
container.appendChild(topCanvas);
container.appendChild(controls);

const regl = createREGL(Object.assign({
canvas: glCanvas,
extensions:["OES_texture_half_float"],
attributes: {antialias: antialiasing},
pixelRatio: 1}))
regl.cameraDiv = cameraDiv;
regl.canvas = glCanvas;
regl.topCanvas = topCanvas;
regl.container = container;
yield regl
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
max_width = {
try { // we first try inheriting the max width from the parent atlas page
let elem = document.querySelector('.atlasWidth');
let width = getComputedStyle(elem).maxWidth; // returns width as string with px at end, ex. '1000px'
width = width.substring(0, width.length - 2); // trim off 'px'
return width
}
catch { // if this doesn't work (for ex. for the original notebook) we set the max width to 66rem
return convertRemToPixels(66) // max width of the quantum atlas content column
}
}
Insert cell
function convertRemToPixels(rem) {
return rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more