Compare commits

...

2 commits

3 changed files with 115 additions and 9 deletions

View file

@ -31,6 +31,11 @@
<input id="scale" type="number" min="1" value="40"> <input id="scale" type="number" min="1" value="40">
px per module px per module
</label> </label>
<label for="gap">
<span>Grid gap:</span>
<input id="gap" type="number" min="0" value="0">
px between modules
</label>
<button id="gen-btn">Generate</button> <button id="gen-btn">Generate</button>
</div> </div>
<div> <div>

101
script.js
View file

@ -3,6 +3,50 @@ function intDiv(a, b) {
return ~~(a / b) return ~~(a / b)
} }
let getCodeVersion
const alignmentCoords = [
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170],
]
addEventListener('DOMContentLoaded', () => { addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById("canvas") const canvas = document.getElementById("canvas")
const ctx = canvas.getContext("2d") const ctx = canvas.getContext("2d")
@ -13,24 +57,73 @@ addEventListener('DOMContentLoaded', () => {
size: document.getElementById("width"), size: document.getElementById("width"),
ver: document.getElementById("version"), ver: document.getElementById("version"),
scale: document.getElementById("scale"), scale: document.getElementById("scale"),
gap: document.getElementById("gap"),
} }
document.getElementById("gen-btn").addEventListener("click", () => { document.getElementById("gen-btn").addEventListener("click", () => {
const mask = options.mask.value const mask = options.mask.value
const size = options.size.value const size = Number(options.size.value)
const scale = options.scale.value const scale = Number(options.scale.value)
const gap = Math.min(Number(options.gap.value), scale) // not more than 1 module scaled size
const wh = scale - gap * 2 // width&height for 1 module with grid gap
canvas.width = canvas.height = size * scale canvas.width = canvas.height = size * scale
ctx.clearRect(0, 0, canvas.width, canvas.height) ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = "black"
for (let row = 0; row < size; row++) { for (let row = 0; row < size; row++) {
for (let col = 0; col < size; col++) { for (let col = 0; col < size; col++) {
if (eval(mask) == 0) { if (eval(mask) == 0) {
ctx.fillRect(col * scale, row * scale, scale, scale) ctx.fillRect(col * scale + gap, row * scale + gap, wh, wh)
} }
} }
} }
const idSize = 8 * scale
{ // finder pattern
ctx.fillStyle = "rgba(224, 63, 102, 0.5)"
ctx.fillRect(0, 0, idSize, idSize)
ctx.fillRect(canvas.width - idSize, 0, idSize, idSize)
ctx.fillRect(0, canvas.height - idSize, idSize, idSize)
}
const ver = getCodeVersion()
if (ver > 1) { // alignment pattern
ctx.fillStyle = "rgba(209, 63, 224, 0.5)"
const alignSize = 5 * scale
const coords = alignmentCoords[ver - 2] // array begins with version 2
const len = coords.length
for (let i = 0; i < len; i++) {
for (let j = 0; j < len; j++) {
const row = coords[i], col = coords[j]
if (row < 8 && col < 8 || row < 8 && col > size - 8 || row > size - 8 && col < 8) {
// do not overlap with finder pattern
continue
}
ctx.fillRect((row - 2) * scale, (col - 2) * scale, alignSize, alignSize)
}
}
}
{ // timing pattern
ctx.fillStyle = "rgba(76, 63, 224, 0.5)"
const idEndPos = 6 * scale
const betweenIds = canvas.width - idSize * 2
ctx.fillRect(idSize, idEndPos, betweenIds, scale)
ctx.fillRect(idEndPos, idSize, scale, betweenIds)
}
{ // format info
// TODO
}
}) })
{ // Choose best scale for screen height { // Choose best scale for screen height
@ -45,7 +138,7 @@ addEventListener('DOMContentLoaded', () => {
const MIN_VER = 1 const MIN_VER = 1
const MAX_VER = 40 const MAX_VER = 40
const getCodeVersion = () => { getCodeVersion = () => {
const size = options.size.value const size = options.size.value
return Math.floor((size - MICRO_4) / DIFF) return Math.floor((size - MICRO_4) / DIFF)
} }

View file

@ -3,14 +3,17 @@ body {
padding: 0.5rem; padding: 0.5rem;
} }
#options { body > div {
width: fit-content;
margin: auto;
}
body > div#options {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
row-gap: 0.25rem; row-gap: 0.25rem;
width: fit-content;
max-width: calc(100vw - 0.5rem * 2); max-width: calc(100vw - 0.5rem * 2);
margin: auto;
} }
select, input, button { select, input, button {
@ -20,7 +23,7 @@ select, input, button {
} }
input[type=number] { input[type=number] {
width: calc(1rem * 4 + 0.125rem * 2); width: calc(4rem + 0.125rem * 2);
} }
label { label {
@ -35,6 +38,11 @@ label#width-wrapper > button {
} }
label > span:nth-child(1) { label > span:nth-child(1) {
width: calc(3.5rem); width: 5rem;
text-align: right; text-align: right;
} }
canvas {
margin-top: 0.5rem;
border: 2px solid #555;
}