From 2f8400e5710e6dea61c1ede3526f1a64632425ba Mon Sep 17 00:00:00 2001 From: Ardis Lu Date: Fri, 6 Jan 2023 21:38:58 -0800 Subject: [PATCH] Show the point binary aligning with encoded value --- script.js | 25 ++++++++++++++----------- style.css | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/script.js b/script.js index 76329b6..b9c7044 100644 --- a/script.js +++ b/script.js @@ -25,12 +25,10 @@ function calculateOutput(input) { for (const char of input) { const point = char.codePointAt(0); const pointHex = point.toString(16); - const pointBinary = point.toString(2); output.push({ char: invisibleCharacters.includes(point) ? '◌' : char, // Visual representation of the code point, replacing whitespace with ◌ point: `U+${pointHex.toUpperCase()}`, // Unicode code point, in hex - pointBinary: pointBinary.padStart(8 * Math.ceil(pointBinary.length / 8), '0'), // Unicode code point, in binary bytes: [...encoder.encode(char)].map(c => c.toString(2).padStart(8, '0')) // UTF-8 encoding of the code point, in binary }); } @@ -42,7 +40,7 @@ function parseBytes(bytes) { // A UTF-8 encoded code point with a byte length of 1 is always encoded with this pattern: 0xxxxxxx // Do not mark first bit insignificant because the UTF-8 encoding is exactly equal to the code point binary if (bytes.length === 1) { - return `${bytes[0]}`; + return [bytes[0], bytes[0]]; } // All other UTF-8 byte lengths follow the same pattern @@ -51,21 +49,24 @@ function parseBytes(bytes) { // Length = 4 bytes: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // Length = 5 bytes: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx else { - let template = ''; + let pointBinaryTemplate = ''; + let bytesTemplate = ''; // The number of insignificant bits in the first byte is always the length of the array plus one const initialLength = bytes.length; const firstByte = bytes.shift(); - template += `${firstByte.substring(0, initialLength + 1)}`; - template += `${firstByte.substring(initialLength + 1)}`; + const i = firstByte.substring(0, initialLength + 1); + const s = firstByte.substring(initialLength + 1); + pointBinaryTemplate += `${s}`; + bytesTemplate += `${i}${s}`; // Remaining bytes always have 2 insignificant bits for (const byte of bytes) { - template += `10`; - template += `${byte.substring(2)}`; + pointBinaryTemplate += `${byte.substring(2)}`; + bytesTemplate += `10${byte.substring(2)}`; } - return template; + return [pointBinaryTemplate, bytesTemplate]; } } @@ -77,8 +78,10 @@ function render(output) { const viz = document.createElement('al-point-visualization'); viz.insertAdjacentHTML('beforeend', `${item.char}`); viz.insertAdjacentHTML('beforeend', `${item.point}`); - viz.insertAdjacentHTML('beforeend', `${item.pointBinary}`); - viz.insertAdjacentHTML('beforeend', `${parseBytes(item.bytes)}`); + + const [pointBinary, bytes] = parseBytes(item.bytes); + viz.insertAdjacentHTML('beforeend', `${pointBinary}`); + viz.insertAdjacentHTML('beforeend', `${bytes}`); vizContainer.insertAdjacentElement('beforeend', viz); } diff --git a/style.css b/style.css index 85bfdab..54cf89c 100644 --- a/style.css +++ b/style.css @@ -77,6 +77,41 @@ a>svg { transition: transform 200ms; } +/* For the point binary */ +.shrink { + display: inline-block; + inline-size: 0; + line-height: 0; + overflow: hidden; + visibility: hidden; + transition: inline-size 600ms; +} + +:is(al-point-visualization:hover, al-point-visualization:focus-within) .shrink { + transition: inline-size 200ms; +} + +/* Can't use inline-size: fit-content or inline-size: auto, must hardcode a concrete size for transition to work. */ +:is(al-point-visualization:hover, al-point-visualization:focus-within) .shrink.w-2 { + inline-size: 2ch; +} + +:is(al-point-visualization:hover, al-point-visualization:focus-within) .shrink.w-3 { + inline-size: 3ch; +} + +:is(al-point-visualization:hover, al-point-visualization:focus-within) .shrink.w-4 { + inline-size: 4ch; +} + +:is(al-point-visualization:hover, al-point-visualization:focus-within) .shrink.w-5 { + inline-size: 5ch; +} + +:is(al-point-visualization:hover, al-point-visualization:focus-within) .shrink.w-6 { + inline-size: 6ch; +} + /* For the raw UTF-8 bytes */ .insignificant { transition: opacity 600ms; -- 2.47.3