Skip to content

Instantly share code, notes, and snippets.

@autioch
Last active July 25, 2023 19:33
Show Gist options
  • Save autioch/8b4ac4135ad2e17f5c100aab1f050d55 to your computer and use it in GitHub Desktop.
Save autioch/8b4ac4135ad2e17f5c100aab1f050d55 to your computer and use it in GitHub Desktop.
Millimeter paper creator
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,
body {
margin: 0;
padding: 0;
border: 0;
width: 99vw;
height: 99vh;
color: #ff8f3f;
background-color: #aaa;
}
canvas {
background-color: #fff;
}
button {
position: fixed;
top: 1vh;
left: 1vh;
}
</style>
</head>
<body>
<canvas id="can"></canvas>
<button id="btn" onclick="saveImage()">Save Image</button>
<script>
// dimensions that need to be drawn
const expectedWidth = 211;
const expectedHeight = 268;
const DRAW_MM = false;
// canvas
const canvas = can;
const ctx = canvas.getContext('2d');
// constants
const MARGIN = 20;
const MM_PIXEL = 10;
const ANTIALIAS = 0.5;
const space = 4;
const cmWidthCount = Math.ceil(expectedWidth / 10);
const cmHeightCount = Math.ceil(expectedHeight / 10);
const gridWidth = cmWidthCount * 10 * MM_PIXEL;
const gridHeight = cmHeightCount * 10 * MM_PIXEL;
console.log(expectedWidth, gridWidth, expectedHeight, gridHeight);
// set proper sizes
can.width = gridWidth + MARGIN + MARGIN;
can.height = gridHeight + MARGIN + MARGIN;
can.style.width = document.documentElement.style.width = document.body.style.width = can.width + 'px';
can.style.height = document.documentElement.style.height = document.body.style.height = can.height + 'px';
// background
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, can.width, can.height);
ctx.strokeStyle = '#ff8f3f'; // orange
ctx.fillStyle = '#000';
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = (3 * MM_PIXEL) + "px Arial";
//helper functions
const lineH = (at) => {
ctx.moveTo(MARGIN - ANTIALIAS, MARGIN + at);
ctx.lineTo(MARGIN + ANTIALIAS + gridWidth, MARGIN + at);
}
const lineV = (at) => {
ctx.moveTo(MARGIN + at, MARGIN - ANTIALIAS);
ctx.lineTo(MARGIN + at, MARGIN + ANTIALIAS + gridHeight);
}
function saveImage() {
const link = document.createElement("a");
link.download = "millimeter.png";
link.href = canvas.toDataURL();
link.click();
}
// horizontal lines
for (let i = 0; i < cmHeightCount; i++) {
// Top strong line
ctx.beginPath();
ctx.lineWidth = 3;
lineH(i * MM_PIXEL * 10 - ANTIALIAS);
ctx.stroke();
// middle semi-strong line
ctx.beginPath();
ctx.lineWidth = DRAW_MM ? 2 : 1;
lineH(i * MM_PIXEL * 10 + MM_PIXEL * 5 - 1 + (DRAW_MM ? 0 : 0.5));
ctx.stroke();
// mm small line
if (DRAW_MM) {
ctx.beginPath();
ctx.lineWidth = 1;
for (let j = 0; j < 5; j++) {
lineH(i * MM_PIXEL * 10 + MM_PIXEL * 5 + j * MM_PIXEL - ANTIALIAS);
}
for (let j = 0; j < 5; j++) {
lineH(i * MM_PIXEL * 10 + j * MM_PIXEL - ANTIALIAS);
}
ctx.stroke();
}
}
ctx.beginPath();
ctx.lineWidth = 3;
lineH(cmHeightCount * MM_PIXEL * 10 - ANTIALIAS);
ctx.stroke();
// vertical lines
for (let i = 0; i < cmWidthCount; i++) {
// Left strong line
ctx.beginPath();
ctx.lineWidth = 3;
lineV(i * MM_PIXEL * 10 - ANTIALIAS);
ctx.stroke();
// middle semi-strong line
ctx.beginPath();
ctx.lineWidth = DRAW_MM ? 2 : 1;
lineV(i * MM_PIXEL * 10 + MM_PIXEL * 5 - 1 + (DRAW_MM ? 0 : 0.5));
ctx.stroke();
// mm small line
if (DRAW_MM) {
ctx.beginPath();
ctx.lineWidth = 1;
for (let j = 0; j < 5; j++) {
lineV(i * MM_PIXEL * 10 + MM_PIXEL * 5 + j * MM_PIXEL - ANTIALIAS);
}
for (let j = 0; j < 5; j++) {
lineV(i * MM_PIXEL * 10 + j * MM_PIXEL - ANTIALIAS);
}
ctx.stroke();
}
}
ctx.beginPath();
ctx.lineWidth = 3;
lineV(cmWidthCount * MM_PIXEL * 10 - ANTIALIAS);
ctx.stroke();
// texts
ctx.beginPath();
for (let i = 2; i < cmHeightCount; i = i + 2) { //horizontal lines text
ctx.fillText(i.toString(), MARGIN, gridHeight - i * MM_PIXEL * 10 + MARGIN);
}
for (let i = 2; i < cmWidthCount; i = i + 2) { // vertical lines text
ctx.fillText(i.toString(), i * MM_PIXEL * 10 + MARGIN, gridHeight + MARGIN);
}
ctx.stroke();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment