Public
Edited
Oct 18, 2022
Insert cell
Insert cell
Insert cell
Insert cell
canvas = {
const ctx = DOM.context2d(width, height);

ctx.canvas.style.background = "hsl(216deg 20% 90%)";

const img = new Image();
img.src = select == "Road" ? backgroundImage.src : satelliteImage.src;
img.setAttribute("crossOrigin", "");

img.onload = () => {
ctx.canvas.onmousedown = (e) => {
console.log("Click", e);
origPtr.origPtrX = e.offsetX;
origPtr.origPtrY = e.offsetY;
draw();
};

draw();

function draw() {
const { fineWidth, fineHeight, roughWidth, roughHeight } = gridSet;
const { origPtrX, origPtrY } = origPtr;
const { roughColor, fineColor, origColor, rotate } = form;
// const roughColor = "#555555";
// const fineColor = "#bbbbbb";

ctx.drawImage(img, 0, 0, width, height);

// Draw grids
{
ctx.save();
// Bigger width and height to prevent out-of-range when rotating
const width2 = width * 3,
height2 = height * 3;

// Translate - rotate - translate
ctx.translate(origPtrX, origPtrY);
ctx.rotate(rotate);
ctx.translate(-width / 2, -height / 2);

// Draw x-direction grid lines
// Fine
for (let x = width / 2; x < width2; x += fineWidth) {
ctx.strokeStyle = fineColor;
ctx.lineWidth = 1;
ctx.beginPath(),
ctx.moveTo(x, -height2),
ctx.lineTo(x, height2),
ctx.stroke();
ctx.beginPath(),
ctx.moveTo(width - x, -height2),
ctx.lineTo(width - x, height2),
ctx.stroke();
}

// Draw y-direction grid lines
// Fine
for (let y = height / 2; y < height2; y += fineHeight) {
ctx.strokeStyle = fineColor;
ctx.lineWidth = 1;
ctx.beginPath(),
ctx.moveTo(-width2, y),
ctx.lineTo(width2, y),
ctx.stroke();
ctx.beginPath(),
ctx.moveTo(-width2, height - y),
ctx.lineTo(width2, height - y),
ctx.stroke();
}

// Draw x-direction grid lines
// Rough
for (let x = width / 2; x < width2; x += roughWidth) {
ctx.strokeStyle = roughColor;
ctx.lineWidth = 2;
ctx.beginPath(),
ctx.moveTo(x, -height2),
ctx.lineTo(x, height2),
ctx.stroke();
ctx.beginPath(),
ctx.moveTo(width - x, -height2),
ctx.lineTo(width - x, height2),
ctx.stroke();
}

// Draw y-direction grid lines
// Rough
for (let y = height / 2; y < height2; y += roughHeight) {
ctx.strokeStyle = roughColor;
ctx.lineWidth = 2;
ctx.beginPath(),
ctx.moveTo(-width2, y),
ctx.lineTo(width2, y),
ctx.stroke();
ctx.beginPath(),
ctx.moveTo(-width2, height - y),
ctx.lineTo(width2, height - y),
ctx.stroke();
}

// Draw origin point
ctx.fillStyle = origColor;
ctx.rect(width / 2 - 5, height / 2 - 5, 10, 10);
ctx.fill();

ctx.restore();
}
}
};

return ctx.canvas;
}
Insert cell
origPtr = {
return {
origPtrX: parseInt(width / 2),
origPtrY: parseInt(height / 2)
};
}
Insert cell
gridSet = {
const { fineDist, roughScale } = form;
return {
fineWidth: fineDist,
fineHeight: fineDist,
roughWidth: fineDist * roughScale,
roughHeight: fineDist * roughScale
};
}
Insert cell
height = (width / 16) * 9
Insert cell
backgroundImage = FileAttachment("Snipaste_2022-10-18_21-27-13.png").image()
Insert cell
satelliteImage = FileAttachment("Snipaste_2022-10-18_22-37-55.png").image()
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