diff --git a/index.html b/index.html index e889079..16840fe 100644 --- a/index.html +++ b/index.html @@ -31,6 +31,11 @@ px per module +
diff --git a/script.js b/script.js index 59f8fa5..63413ec 100644 --- a/script.js +++ b/script.js @@ -3,6 +3,50 @@ function intDiv(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', () => { const canvas = document.getElementById("canvas") const ctx = canvas.getContext("2d") @@ -13,24 +57,73 @@ addEventListener('DOMContentLoaded', () => { size: document.getElementById("width"), ver: document.getElementById("version"), scale: document.getElementById("scale"), + gap: document.getElementById("gap"), } document.getElementById("gen-btn").addEventListener("click", () => { const mask = options.mask.value - const size = options.size.value - const scale = options.scale.value + const size = Number(options.size.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 ctx.clearRect(0, 0, canvas.width, canvas.height) + ctx.fillStyle = "black" for (let row = 0; row < size; row++) { for (let col = 0; col < size; col++) { 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 @@ -45,7 +138,7 @@ addEventListener('DOMContentLoaded', () => { const MIN_VER = 1 const MAX_VER = 40 - const getCodeVersion = () => { + getCodeVersion = () => { const size = options.size.value return Math.floor((size - MICRO_4) / DIFF) } diff --git a/style.css b/style.css index a4d7014..9a807d6 100644 --- a/style.css +++ b/style.css @@ -3,14 +3,17 @@ body { padding: 0.5rem; } -#options { +body > div { + width: fit-content; + margin: auto; +} + +body > div#options { display: flex; flex-direction: column; row-gap: 0.25rem; - width: fit-content; max-width: calc(100vw - 0.5rem * 2); - margin: auto; } select, input, button { @@ -20,7 +23,7 @@ select, input, button { } input[type=number] { - width: calc(1rem * 4 + 0.125rem * 2); + width: calc(4rem + 0.125rem * 2); } label { @@ -35,6 +38,11 @@ label#width-wrapper > button { } label > span:nth-child(1) { - width: calc(3.5rem); + width: 5rem; text-align: right; } + +canvas { + margin-top: 0.5rem; + border: 2px solid #555; +}