Published
Edited
Jan 9, 2022
Insert cell
Insert cell
import {imageInput} from "@mbostock/file-input"
Insert cell
viewof image = imageInput({
crossOrigin: "anonymous",
initialUrl: testImage(4000, 5000)
})
Insert cell
function testImage(widthPx, heightPx) {
var canvas = document.createElement('canvas');
canvas.width = widthPx;
canvas.height = heightPx;
let ctx = canvas.getContext('2d');
ctx.fillStyle = "#ff0";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#555";
let stripe = 1000;
for (let i = 0; i < canvas.width; i += stripe * 2) {
ctx.fillRect(i, 0, stripe, canvas.height);
}
ctx.fillStyle = "#000";
ctx.fillRect(100, 500, canvas.width - 200, 100);
return canvas.toDataURL("image/png");
}
Insert cell
Insert cell
Insert cell
background = "#fafafa"
Insert cell
border = "#fff"
Insert cell
widthPx = 2048
Insert cell
heightPx = widthPx / aspect
Insert cell
paddingPx = 96
Insert cell
borderPx = 16
Insert cell
function drawImage(f) {
var canvas = document.createElement('canvas');
canvas.width = widthPx;
canvas.height = heightPx;
let ctx = canvas.getContext('2d');
ctx.fillStyle = background;
ctx.fillRect(0, 0, canvas.width, canvas.height);
f(ctx)
let result = document.createElement("img");
result.src = canvas.toDataURL("image/png");
return result;
}
Insert cell
Insert cell
md`## Cover Image`
Insert cell
function drawCover(ctx) {
ctx.save();
let imageWidthPx = image.width;
let imageHeightPx = image.height;
let minFrameDimensionPx = Math.min(widthPx - 2 * paddingPx, heightPx - 2 * paddingPx);
let maxImageDimensionPx = Math.max(image.width, image.height);
let scale = 1;
if (maxImageDimensionPx > minFrameDimensionPx) {
scale = minFrameDimensionPx / maxImageDimensionPx;
}
let newWidthPx = imageWidthPx * scale;
let newHeightPx = imageHeightPx * scale;
// drawSquare(ctx);

ctx.fillStyle = '#fff';
ctx.fillRect((widthPx - newWidthPx) / 2 - borderPx, (heightPx - newHeightPx) / 2 - borderPx, newWidthPx + 2* borderPx, newHeightPx + 2 * borderPx);
ctx.drawImage(image, (widthPx - newWidthPx) / 2, (heightPx - newHeightPx) / 2, newWidthPx, newHeightPx);

ctx.restore();
}
Insert cell
drawImage(drawCover)
Insert cell
function createPanes() {
let panes = [];
let imageWidthPx = image.width;
let imageHeightPx = image.height;

let maxFrameDimensionPx = Math.max(widthPx - 2 * paddingPx, heightPx - 2 * paddingPx);
let minImageDimensionPx = Math.min(image.width, image.height);
let scale = maxFrameDimensionPx / minImageDimensionPx;
let newWidthPx = imageWidthPx * scale;
let newHeightPx = imageHeightPx * scale;
console.log(imageHeightPx, scale, newHeightPx);
if (imageWidthPx >= imageHeightPx) {
let count = Math.ceil((newWidthPx + 2 * paddingPx) / widthPx);
let offsetPx = (count * widthPx - newWidthPx) / 2;
for (let i = 0; i < count; i++) {
panes.push(drawImage(function(ctx) {
ctx.fillStyle = border;
ctx.fillRect(offsetPx - i * widthPx - borderPx, paddingPx - borderPx, newWidthPx + 2 * borderPx, newHeightPx + 2 * borderPx);

ctx.drawImage(image, offsetPx - i * widthPx, paddingPx, newWidthPx, newHeightPx);
}))
}
} else {
let count = Math.ceil((newHeightPx + 2 * paddingPx) / widthPx);
console.log(newHeightPx, widthPx);
let offsetPx = (count * widthPx - newHeightPx) / 2;
for (let i = 0; i < count; i++) {
panes.push(drawImage(function(ctx) {
let rotation = - Math.PI / 2;
ctx.rotate(rotation);
ctx.translate(-heightPx, 0);

ctx.fillStyle = border;
ctx.fillRect(paddingPx - borderPx, offsetPx - i * widthPx - borderPx, newWidthPx + 2 * borderPx, newHeightPx + 2 * borderPx);
ctx.drawImage(image, paddingPx, offsetPx - i * widthPx, newWidthPx, newHeightPx);
}))
}
}

return panes;
}
Insert cell
Insert cell
function show(panes) {
let div = document.createElement('div');
for (let pane in panes) {
div.appendChild(panes[pane])
}
return div;
}
Insert cell
show(createPanes())
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more