diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-04-25 22:30:07 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-04-25 22:30:07 +0900 |
| commit | a3dd384695b5da93e69379be862eb7f0968c187b (patch) | |
| tree | 94d34fc75e65960cce9b7fb3ee8b318cf407c0c9 /vhosts/blog/public/my-icon.js | |
| parent | 39389d521d5790f203e07f6038789869b8015a42 (diff) | |
| download | nsfisis.dev-a3dd384695b5da93e69379be862eb7f0968c187b.tar.gz nsfisis.dev-a3dd384695b5da93e69379be862eb7f0968c187b.tar.zst nsfisis.dev-a3dd384695b5da93e69379be862eb7f0968c187b.zip | |
feat(blog/nuldoc): remove p5.js
Diffstat (limited to 'vhosts/blog/public/my-icon.js')
| -rw-r--r-- | vhosts/blog/public/my-icon.js | 267 |
1 files changed, 159 insertions, 108 deletions
diff --git a/vhosts/blog/public/my-icon.js b/vhosts/blog/public/my-icon.js index 5b52ca3d..7d3ea96e 100644 --- a/vhosts/blog/public/my-icon.js +++ b/vhosts/blog/public/my-icon.js @@ -1,121 +1,172 @@ -const colorBackground = 'white'; -const color蜜柑の果実 = [255, 165, 0]; -const color蜜柑の内果皮 = [255, 255, 255]; -const color蜜柑のじょうのう = [255, 255, 255]; -const colorMosaic = [ - [255, 165, 0], - [255, 140, 0], - [255, 215, 0], - [255, 205, 114], - [255, 210, 127], - [255, 192, 76], - [255, 169, 12], - [255, 228, 178], -]; -const colorEye = [0, 0, 0]; - -function setup() { - const container = document.getElementById("p5jsMyIcon"); - const canvas = createCanvas(100, 100); - canvas.parent(container); - - background(colorBackground); - frameRate(15); -} - -function draw() { - if (4 <= frameCount % 15) { - return; +const init = () => { + const SIZE = 100; + const DPR = globalThis.devicePixelRatio || 1; + const FPS = 15; + + const colorBackground = "rgb(255, 255, 255)"; + const color蜜柑の果実 = "rgb(255, 165, 0)"; + const color蜜柑の内果皮 = "rgb(255, 255, 255)"; + const color蜜柑のじょうのう = "rgb(255, 255, 255)"; + const colorMosaic = [ + [255, 165, 0], + [255, 140, 0], + [255, 215, 0], + [255, 205, 114], + [255, 210, 127], + [255, 192, 76], + [255, 169, 12], + [255, 228, 178], + ]; + const colorEye = "rgb(0, 0, 0)"; + + const container = document.getElementById("myIcon"); + const canvas = document.createElement("canvas"); + canvas.width = SIZE * DPR; + canvas.height = SIZE * DPR; + canvas.style.width = `${SIZE}px`; + canvas.style.height = `${SIZE}px`; + container.appendChild(canvas); + const ctx = canvas.getContext("2d"); + ctx.scale(DPR, DPR); + + let frameCount = 0; + + function randomChoice(xs) { + return xs[(Math.random() * xs.length) | 0]; } - clear(); + function roundRect(x, y, w, h, r) { + ctx.beginPath(); + ctx.moveTo(x + r, y); + ctx.lineTo(x + w - r, y); + ctx.quadraticCurveTo(x + w, y, x + w, y + r); + ctx.lineTo(x + w, y + h - r); + ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h); + ctx.lineTo(x + r, y + h); + ctx.quadraticCurveTo(x, y + h, x, y + h - r); + ctx.lineTo(x, y + r); + ctx.quadraticCurveTo(x, y, x + r, y); + ctx.closePath(); + ctx.fill(); + } + + function draw蜜柑() { + // 果実、外果皮 + ctx.fillStyle = color蜜柑の果実; + ctx.beginPath(); + ctx.arc(50, 50, 50, 0, Math.PI * 2); + ctx.fill(); + + // 内果皮 + ctx.strokeStyle = color蜜柑の内果皮; + ctx.lineWidth = 4; + ctx.beginPath(); + ctx.arc(50, 50, 45, 0, Math.PI * 2); + ctx.stroke(); + + // じょうのう + ctx.strokeStyle = color蜜柑のじょうのう; + ctx.lineWidth = 2; + for (let t = 0; t < 10; t++) { + ctx.save(); + ctx.translate(50, 50); + ctx.rotate((t * Math.PI) / 5); - draw蜜柑(); - applyMosaicEffect([10, 5, 2, 0][frameCount % 15]); - drawMosaic(); - drawEyes(); -} + ctx.beginPath(); + ctx.moveTo(0, -45); + ctx.lineTo(0, 0); + ctx.stroke(); -function applyMosaicEffect(k) { - if (k === 0) { - return; + ctx.beginPath(); + ctx.moveTo(0, -40); + ctx.lineTo(-4, -45); + ctx.lineTo(4, -45); + ctx.closePath(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(0, -20); + ctx.lineTo(-3, 0); + ctx.lineTo(3, 0); + ctx.closePath(); + ctx.stroke(); + + ctx.restore(); + } } - loadPixels(); - noStroke(); - const d = pixelDensity(); - for (let y = 0; y < 100; y += k) { - for (let x = 50; x < 100; x += k) { - var r = 0, g = 0, b = 0; - for (let i = 0; i < k; i++) { - for (let j = 0; j < k; j++) { - const offset = 4 * d * ((y + i) * 100 * d + (x + j)); - const r_ = pixels[offset]; - const g_ = pixels[offset + 1]; - const b_ = pixels[offset + 2]; - const a_ = pixels[offset + 3]; - r += a_ === 0 ? red(colorBackground) : r_; - g += a_ === 0 ? green(colorBackground) : g_; - b += a_ === 0 ? blue(colorBackground) : b_; + function applyMosaic(k) { + if (k === 0) return; + + const img = ctx.getImageData(0, 0, SIZE, SIZE); + const pixels = img.data; + + for (let y = 0; y < SIZE; y += k) { + for (let x = 50; x < SIZE; x += k) { + let r = 0, g = 0, b = 0; + for (let i = 0; i < k; i++) { + for (let j = 0; j < k; j++) { + const offset = 4 * ((y + i) * SIZE + (x + j)); + const a = pixels[offset + 3]; + r += a ? pixels[offset + 0] : 255; + g += a ? pixels[offset + 1] : 255; + b += a ? pixels[offset + 2] : 255; + } } + const n = k * k; + ctx.fillStyle = `rgb(${(r / n) | 0}, ${(g / n) | 0}, ${(b / n) | 0})`; + ctx.fillRect(x, y, k, k); } - fill(r / k**2, g / k**2, b / k**2); - rect(x, y, k, k); } } -} - -function draw蜜柑() { - // 果実、外果皮 - fill(color蜜柑の果実); - noStroke(); - ellipse(50, 50, 100, 100); - - // 内果皮 - noFill(); - stroke(color蜜柑の内果皮); - strokeWeight(4); - ellipse(50, 50, 90, 90); - - // じょうのう - stroke(color蜜柑のじょうのう); - strokeWeight(2); - for (let t = 0; t < 10; t++) { - push(); - translate(50, 50); - rotate(t * PI / 5); - line(0, -45, 0, 0); - triangle(0, -40, -4, -45, 4, -45); - triangle(0, -20, -3, 0, 3, 0); - pop(); - } -} - -function drawMosaic() { - for (let dy = 0; dy < 10; dy++) { - for (let dx = 0; dx < 10; dx++) { - const y = dy * 10; - const x = dx * 10; - if (x < 50) { - continue; - } - if ((x - 45)**2 + (y - 45)**2 > 55**2) { - continue; - } - if (random() < 0.5) { - continue; + + function drawMosaic() { + for (let dy = 0; dy < 10; dy++) { + for (let dx = 0; dx < 10; dx++) { + const y = dy * 10; + const x = dx * 10; + if (x < 50) { + continue; + } + if ((x - 45) ** 2 + (y - 45) ** 2 > 55 ** 2) { + continue; + } + if (Math.random() < 0.5) { + continue; + } + + const [r, g, b] = randomChoice(colorMosaic); + ctx.fillStyle = `rgba(${r}, ${g}, ${b}, 0.75)`; + ctx.fillRect(x, y, 10, 10); } - const [r, g, b] = random(colorMosaic); - noStroke(); - fill(r, g, b, 192); - rect(x, y, 10, 10); } } -} - -function drawEyes() { - noStroke(); - fill(colorEye); - rect(30, 35, 6, 25, 2); - rect(64, 35, 6, 25, 2); -} + + function drawEyes() { + ctx.fillStyle = colorEye; + roundRect(30, 35, 6, 25, 2); + roundRect(64, 35, 6, 25, 2); + } + + function mainLoop() { + frameCount++; + if (4 <= frameCount % 15) { + setTimeout(mainLoop, 1000 / FPS); + return; + } + + ctx.fillStyle = colorBackground; + ctx.fillRect(0, 0, SIZE, SIZE); + ctx.clearRect(0, 0, SIZE, SIZE); + + draw蜜柑(); + applyMosaic([10, 5, 2, 0][frameCount % 15]); + drawMosaic(); + drawEyes(); + + setTimeout(mainLoop, 1000 / FPS); + } + setTimeout(mainLoop, 2000); +}; + +document.addEventListener("DOMContentLoaded", init); |
