Published
Edited
Sep 28, 2020
2 forks
2 stars
Insert cell
md`# Image or Video with Graphical Overlay`
Insert cell
viewof enableWebcam = {
const check = checkbox({
options: [{ value: 'on', label: 'Enable webcam' }]
});
check.value = false;
return check;
}
Insert cell
{
const div = d3.select(DOM.element('div'));
let container = div
.append('div')
.style('position', 'relative')
.style('width', `${imgWidth}px`)
.style('height', `${imgHeight}px`);

// let image = container.append(testimage); // InvalidCharacterError: Failed to execute 'createElement' on 'Document': The tag name provided ('[object HTMLImageElement]') is not a valid name.
let image = container.node().appendChild(enableWebcam ? video : testimage);
d3.select(image)
.style('position', 'absolute')
.style('top', 0)
.style('left', 0)
.attr('width', imgWidth)
.attr('height', imgHeight);

let canvas = container
.append('canvas')
.style('position', 'absolute')
.style('top', 0)
.style('left', 0)
.attr('width', imgWidth)
.attr('height', imgHeight);

let svg = container
.append('svg')
.style('position', 'absolute')
.style('top', 0)
.style('left', 0)
.attr('width', imgWidth)
.attr('height', imgHeight);

// Draw plain SVG Node
svg.node().appendChild(starSVG);

// Draw SVG using D3
svg
.selectAll('circle')
.data([0, 100, 200, 300, 400])
.enter()
.append('circle')
.attr('cx', d => imgWidth - d)
.attr('cy', d => d)
.attr('r', 10)
.attr('fill', 'limegreen');

// Draw on Canvas (from @duncangeere/how-to-use-html5-canvas-part-one)
const context = canvas.node().getContext('2d');
context.fillStyle = 'orange';
context.strokeStyle = 'lightblue';
context.lineWidth = 5;
context.fillRect(225, 225, 100, 100); // Draw a filled rectangle
context.clearRect(245, 245, 60, 60); // Cut out a rectangular chunk from the middle
context.strokeRect(250, 250, 50, 50); // Draw an outline inside it

return div.node();
}
Insert cell
// From @uvizlab/d3-tutorial-1-introduction-to-observable
starSVG = html`
<svg width="200" height="200">
<polygon points="100,10 40,198 190,78 10,78 160,198"
style="fill:pink;stroke:purple;stroke-width:5;fill-rule:evenodd;" />
</svg>
`
Insert cell
imgHeight = 400
Insert cell
imgWidth = 400
Insert cell
video = {
if (enableWebcam) {
const stream = navigator.mediaDevices
? navigator.mediaDevices.getUserMedia({
video: {
width: { ideal: imgWidth },
height: { ideal: imgHeight },
facingMode: 'environment'
}
})
: new Promise((y, n) => navigator.getUserMedia({ video: true }, y, n));
const video = html`<video width=${width} autoplay=true playsinline=true></video>`;
video.style.maxWidth = "100%";
const vid = await stream.then(stream => {
if ("srcObject" in video) video.srcObject = stream;
else video.src = URL.createObjectURL(stream);
invalidation.then(() => {
stream.getTracks().forEach(t => t.stop());
URL.revokeObjectURL(video.src);
});
video.width = imgWidth;
video.height = imgHeight;
return video;
});
return vid;
}
}
Insert cell
testimage = {
const image = new Image();
image.crossOrigin = "anonymous";
image.src = await FileAttachment("neonbrand-FoiZoPtxSyA-unsplash.jpg").url();
image.width = imgWidth;
image.height = imgHeight;
return image;
}
Insert cell
Insert cell
d3 = require("d3")
Insert cell
import { checkbox, slider } from "@jashkenas/inputs"
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