1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| let offscreen let ctx
const colors = [ '#a09d1d', '#84b826', '#168a30', '#155fbf', '#40148c', '#5f168b', '#93148c', '#970c0d', '#af2e15', '#ab4913', '#a45a12', '#514e0e', ] let cvsWidth, cvsHeight let particleSize let particleSpacing let particleList let wordLeft let wordTop let generating
addEventListener('message', function (e) {
if (e.data.signal === 'init') { cvsWidth = e.data.width cvsHeight = e.data.height particleSpacing = e.data.particleSpacing offscreen = new OffscreenCanvas(cvsWidth, cvsHeight) ctx = offscreen.getContext('2d') postMessage({ signal: 'initialized' }) } else if (e.data.signal === 'generate') { generate(e.data.word, e.data.fontSize) } }, false)
function generate (word, fontSize) { generating = true offscreen = new OffscreenCanvas(cvsWidth, cvsHeight) if (fontSize === 'auto') { fontSize = cvsWidth / word.length fontSize = Math.min(cvsHeight * 0.8, fontSize) }
ctx.textAlign = 'left' ctx.textBaseline = 'middle' ctx.fillStyle = '#000' ctx.font = 'bold ' + fontSize + 'px Tahoma' const wordWidth = ctx.measureText(word).width particleSize = Math.max(wordWidth / 140, 5) wordLeft = (cvsWidth - wordWidth) / 2 wordTop = cvsHeight / 2 ctx.clearRect(0, 0, cvsWidth, cvsHeight) ctx.fillText(word, (cvsWidth - ctx.measureText(word).width) / 2, cvsHeight / 2)
particleList = [] let imageData = ctx.getImageData(0, 0, cvsWidth, cvsHeight).data let i, j const sampleOffset = Math.floor(particleSize + particleSpacing) for (i = 0; i < cvsWidth; i += sampleOffset) { for (j = 0; j < cvsHeight; j += sampleOffset) { if (imageData[4 * (j * cvsWidth + i) + 3]) { particleList.push({ from: { x: cvsWidth * Math.random(), y: cvsHeight * Math.random() }, to: { x: i, y: j }, color: colors[Math.floor(Math.random() * colors.length)], speed: 0.08 + 0.04 * Math.random(), size: 0, done: false, }) } } } postMessage({ signal: 'generated', particleList, particleSize }) generating = false }
|