mochi-bun.js

total 0
used 0
limit 0
/* title: Mochi Bun category: cute files: head ../point_src/stage.js --- A tiny kawaii steamed bun: soft, white, and squishy. Move the pointer near it; click to make it bounce and blush. */ class MainStage extends Stage { canvas = 'playspace' mounted() { this.time=0;this.squish=0;this.pointer={x:-999,y:-999}; this.canvas.addEventListener('pointermove',e=>{ const r=this.canvas.getBoundingClientRect(); this.pointer.x=(e.clientX-r.left)*this.canvas.width/r.width; this.pointer.y=(e.clientY-r.top)*this.canvas.height/r.height; }); this.canvas.addEventListener('pointerleave',()=>{this.pointer.x=-999;this.pointer.y=-999;}); this.canvas.addEventListener('pointerdown',()=>{this.squish=1;}); } draw(ctx){ const w=this.canvas.width,h=this.canvas.height; this.time+=.045;this.squish*=.92; ctx.clearRect(0,0,w,h); const scale=Math.min(w,h)/350; const cx=w/2,cy=h*.54; const nearby=Math.hypot(this.pointer.x-cx,this.pointer.y-cy)<130*scale; const bounce=Math.sin(this.time*2)*3+Math.abs(Math.sin(this.time*10))*25*this.squish; ctx.save();ctx.translate(cx,cy-bounce*scale);ctx.scale(scale,scale); // small oval shadow ctx.fillStyle='rgba(119,90,89,.12)'; ctx.beginPath();ctx.ellipse(0,118+bounce,100-12*this.squish,15,0,0,Math.PI*2);ctx.fill(); // plump round white dumpling ctx.translate(0,20*this.squish); ctx.scale(1+this.squish*.13,1-this.squish*.2); ctx.shadowColor='rgba(125,105,115,.18)';ctx.shadowBlur=24;ctx.shadowOffsetY=8; const grad=ctx.createRadialGradient(-40,-65,12,5,4,150); grad.addColorStop(0,'#ffffff');grad.addColorStop(.68,'#fffefd');grad.addColorStop(1,'#e8dfe0'); ctx.fillStyle=grad;ctx.beginPath(); ctx.moveTo(-109,51); ctx.bezierCurveTo(-130,0,-107,-109,-25,-114); ctx.bezierCurveTo(49,-132,120,-77,116,25); ctx.bezierCurveTo(120,89,69,106,2,107); ctx.bezierCurveTo(-66,108,-103,94,-109,51); ctx.closePath();ctx.fill(); ctx.shadowBlur=0;ctx.shadowOffsetY=0; // two miniature dot eyes ctx.fillStyle='#39343a'; for(const ex of [-39,39]){ ctx.beginPath();ctx.ellipse(ex,-4,6.5,8,0,0,Math.PI*2);ctx.fill(); ctx.fillStyle='white';ctx.beginPath();ctx.arc(ex-2,-7,1.8,0,Math.PI*2);ctx.fill(); ctx.fillStyle='#39343a'; } // warm pink blush ctx.fillStyle=nearby||this.squish>.05?'#f5b4c2':'#f9d4db'; for(const x of [-72,72]){ ctx.beginPath();ctx.ellipse(x,23,17,9,0,0,Math.PI*2);ctx.fill(); } // teeny mouth, surprised when poked ctx.strokeStyle='#514047';ctx.lineWidth=3;ctx.lineCap='round'; if(this.squish>.16){ ctx.fillStyle='#704b59';ctx.beginPath();ctx.ellipse(0,24,6,9,0,0,Math.PI*2);ctx.fill(); } else { ctx.beginPath();ctx.moveTo(-8,20);ctx.quadraticCurveTo(0,30,8,20);ctx.stroke(); } ctx.restore(); ctx.fillStyle='#aeb4c6';ctx.textAlign='center'; ctx.font='14px sans-serif';ctx.fillText('a very small bun ♡ (poke me!)',cx,h-23); } } stage = MainStage.go();
Run
Meta Data
title Mochi Bun
imports ()
files ('head', '../point_src/stage.js')
unused_keys ()
unknown_keys ('category',)
category ['cute']
filepath_exists True
path mochi-bun.js
filepath mochi-bun.js
clean_files ('../point_src/core/head.js', '../point_src/stage-hooks.js', '../point_src/functions/resolve.js', '../point_src/stage.js')
markdown {'html': '<p>A tiny kawaii steamed bun: soft, white, and squishy. Move the pointer near it; click to make it bounce and blush.</p>', 'content': 'title: Mochi Bun\ncategory: cute\nfiles:\n head\n ../point_src/stage.js\n---\n\nA tiny kawaii steamed bun: soft, white, and squishy. Move the pointer near it; click to make it bounce and blush.'}