1import lettersMapping from "./letters.js"; 2 3let WORD = "EMPTYCAN"; 4// let _RANDO = Math.floor(Math.random()*16777215).toString(16); 5let _BORDER = "#5581af"; 6let _START = "#ffffff"; 7let _FINAL = "yellow"; 8let _S = (Math.random() * (window.innerWidth / 50)) + 15; 9let _P, _D; 10 11const _OFFSETY = 112; 12 13// ###################################################### 14// thank you, ChatGPT, for the code and the laughs 15document.addEventListener("DOMContentLoaded", function() { 16 let canvas = document.getElementById('helloCanvas'); 17 let ctx = canvas.getContext('2d'); 18 19 let squareSize = window.innerWidth / 60; // size of each square 20 let spacing = 1; // space between letters 21 22 class RoundRect { 23 constructor(rectX, rectY, rectHeight, rectWidth, radius, color, c, e) { 24 this.rectX = rectX; 25 this.rectY = rectY; 26 this.rectWidth = rectWidth; 27 this.rectHeight = rectHeight; 28 this.radius = radius; 29 this.context = c; 30 this.color = color; 31 this.targetX = rectX; 32 this.targetY = rectY; 33 34 const rect = canvas.getBoundingClientRect(); 35 this.currentX = e.left + (Math.random() * e.width) - rect.left - squareSize; 36 this.currentY = e.top - rect.top - (squareSize/2); 37 // this.currentX = Math.random() * this.context.canvas.width; 38 // this.currentY = Math.random() * this.context.canvas.height; 39 } 40 41 draw() { 42 const c = this.context; 43 c.beginPath(); 44 c.roundRect(this.currentX + this.rectWidth / 2, this.currentY,this.rectWidth, this.rectHeight, this.radius); 45 c.fillStyle = this.color; 46 c.fill(); 47 c.lineWidth = 0.5; 48 c.stroke(); 49 } 50 51 update() { 52 // Move the rectangle towards the target position 53 this.currentX += (this.targetX - this.currentX) * (Math.random() * 0.1); 54 this.currentY += (this.targetY - this.currentY) * (Math.random() * 0.1); 55 56 // Redraw the rectangle 57 //this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height); 58 this.draw(); 59 60 // Continue the animation as long as the rectangle is not in position 61 if (!this.isInPosition()) { 62 requestAnimationFrame(this.update.bind(this)); 63 } else { 64 this.context.fillStyle = _FINAL; 65 this.context.fill(); 66 } 67 } 68 69 isInPosition() { 70 // Check if the rectangle is close enough to its target position 71 const distanceX = this.targetX - this.currentX; 72 const distanceY = this.targetY - this.currentY; 73 const distance = Math.sqrt(distanceX ** 2 + distanceY ** 2); 74 return distance < 0.5; // Consider it in position if less than 0.5 pixels away 75 } 76 77 animateToPosition() { 78 requestAnimationFrame(this.update.bind(this)); 79 } 80 } 81 82 // Function to draw a letter 83 function drawLetter(letter, offsetX, offsetY, color) { 84 if (lettersMapping[letter]) { 85 lettersMapping[letter].forEach(squareOffset => { 86 let _X = offsetX + squareOffset[0] * squareSize, 87 _Y = offsetY + squareOffset[1] * squareSize; 88 89 const myRoundRect = new RoundRect( 90 _X, _Y, 91 squareSize, 92 squareSize, 93 1, color, ctx, _P); 94 95 myRoundRect.animateToPosition(); 96 97 }); 98 } 99 } 100 101 102 // Function to draw the entire word 103 function drawWord(word, offsetX, offsetY, color) { 104 let currentPositionX = offsetX; 105 // Convert the word to uppercase to match the mappings 106 word = word.toUpperCase(); 107 108 word.split('').forEach(letter => { 109 drawLetter(letter, currentPositionX, offsetY, color); 110 111 // Advance the current position for the next letter. 112 currentPositionX += (4 * squareSize) + spacing; // the width of the widest letter + spacing 113 }); 114 115 116 } 117 function setup() { 118 squareSize = _S; // size of each square 119 spacing = 1; // space between letters 120 canvas.width = window.innerWidth; 121 canvas.height = window.innerHeight; // Fixed height to accommodate one letter vertically 122 ctx.fillStyle = "#FCF8B6"; 123 ctx.lineWidth = 4; 124 ctx.strokeStyle = _BORDER; 125 }
126 function init() { 127 squareSize = Math.floor(Math.random() * (window.innerWidth / (4 * WORD.length))); 128 if (squareSize < 20) 129 squareSize = 20; 130 if ((squareSize < 10) && (window.innerWidth < 800)) 131 squareSize = 10; 132 if ((window.innerWidth < 500)) 133 squareSize = 9 * (9 / WORD.length); 134 if (_D) { 135 drawWord(WORD, (canvas.width - (WORD.length * 4 * squareSize * spacing)) / 2, ((canvas.height - _OFFSETY) - 5 * squareSize) / 2, _START); 136 } 137 } 138 function getOffset(el) { 139 const rect = el.getBoundingClientRect(); 140 return { 141 left: rect.left + window.scrollX, 142 top: rect.top + window.scrollY - _OFFSETY/2, 143 width: rect.width 144 }; 145 } 146 147 // ###################################################### 148 // UI controls 149 150 const _SWATCH = document.querySelector("#color"); 151 _SWATCH.addEventListener('change', (e) => { 152 _FINAL = e.target.value; 153 document.querySelector("label span").style.background = _FINAL; 154 }); 155 156 const _SAVE = document.querySelector("#save"); 157 _SAVE.addEventListener('click', (e) => { 158 var link = document.createElement('a'); 159 link.setAttribute('download', WORD + '.png'); 160 link.setAttribute('href', canvas.toDataURL("image/png").replace("image/png", "image/octet-stream")); 161 link.click(); 162 }); 163 164 const _INPUT = document.querySelector("input"); 165 _INPUT.addEventListener('keyup', (e) => { 166 e.preventDefault(); 167 e.stopPropagation(); 168 if (e.key == 'Enter') { 169 170 WORD = _INPUT.value.toUpperCase(); 171 _D = true; 172 _P = getOffset(_INPUT); 173 init(); 174 } 175 }) 176 177 const _CLEAR = document.querySelector("#clear"); 178 _CLEAR.addEventListener('click', (e) => { 179 document.querySelector("body canvas").remove(); 180 let _canvas = document.createElement("canvas"); 181 _canvas.setAttribute('id','helloCanvas'); 182 document.querySelector("body main").appendChild(_canvas); 183 canvas = _canvas; 184 ctx = canvas.getContext('2d'); 185 e.stopPropagation(); 186 handleCanvas(); 187 setup(); 188 }) 189 function handleCanvas() { 190 canvas.addEventListener('mousedown', (e) => { 191 // if (e.target instanceof HTMLCanvasElement) { 192 // _P = { 193 // left: e.clientX, 194 // top: e.clientY, 195 // width: 50 196 // }; 197 // init(); 198 // } 199 _P = { 200 left: e.clientX, 201 top: e.clientY, 202 width: 50 203 }; 204 init(); 205 }); 206 canvas.addEventListener('mouseup', (e) => { 207 _D = false; 208 }); 209 canvas.addEventListener('mousemove', (e) => { 210 _D = true; 211 }); 212 canvas.oncontextmenu = function () { 213 _D = false; 214 } 215 canvas.addEventListener('mouseleave', (e) => {_D = false;}); 216 canvas.addEventListener('mouseout', (e) => {_D = false;}); 217 // ###################################################### 218 // mousedown === touchstart 219 // mousemove === touchmove 220 // mouseup === touchend 221 canvas.addEventListener('touchstart', (e) => { 222 let _touches = e.targetTouches[0]; 223 if (e.target instanceof HTMLCanvasElement) { 224 _P = { 225 left: _touches.clientX, 226 top: _touches.clientY, 227 width: 50 228 }; 229 init(); 230 } 231 }); 232 canvas.addEventListener('touchmove', (e) => { 233 _D = true; 234 }); 235 canvas.addEventListener('touchend', (e) => { 236 _D = false; 237 }); 238 } 239 240 window.addEventListener('resize', (e) => { 241 //setup(); 242 }); 243 244 245 // ###################################################### 246 // START ME UP, MIC 247 handleCanvas(); 248 setup(); 249 _D = true; 250 _P = getOffset(canvas); 251 init(); 252 253 254 }); 255 256 257 258 259 260 261
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.