Ninja Cat w/ Laser Eyes

HTML
<svg id="s" viewBox="0,0,128,128"> <symbol id="ninjaCat" viewBox="0,0,128,128"> <!-- meta name=generator value=vim ;) --> <path class="cat-body" d="M24,120 Q24,64 64,64 Q104,64 104,120 L24,120" fill="#000" stroke="black" stroke-width="6" stroke-linecap="square"/> <path d="M32,24 Q32,80 64,80 Q96,80 96,24 L84,32 Q64,20 44,32Z" fill="#777" stroke="black" stroke-width="6" stroke-linecap="round"/> <circle cx="50" cy="50" r="3" fill="black"/> <circle cx="78" cy="50" r="3" fill="black"/> <path d="M56,30 q8,-2 16,0 l0,28 l-16,0Z" fill="#aaa"/> <path d="M57,57 l16,0 l-8,8Z" fill="salmon"/> <circle cx="57" cy="64" r="7" fill="white"/> <circle cx="71" cy="64" r="7" fill="white"/> <path d="M37,48 Q37,32 64,28 Q91,32 91,48Z q0,8 8,8 l38,0 q8,0 8,-8 Q88,77 64,78 Q40,77 37,48" fill="rgba(0,0,0,.8)" /> <path id="sunglasses" d="M37,48 Q48,64 64,48 Q80,64 91,48Z" fill="rgba(0,0,0,.2)" stroke-width="1" stroke="rgba(0,0,0,.1)"/> <path d="M35.5,41 92.5,41 91,48 37,48Z" fill="red"/> <path d="M92,42 q0,-4 4,-4 l2,0 l0,4 l-6,0 M90,48 q0,4 4,4 l2,0 l0,-4Z" fill="red" /> <path d="M97,44 l12,0 q08,0 08,-8 l-20,0" fill="red" stroke="black" stroke-width="4"/> <path d="M93,54 l12,0 q08,0 08,-8 l-20,0" fill="red" stroke="black" stroke-width="4"/> <path d="M32,88 L73,117 L85,117 L35,82Z" fill="#555"/> <path class="laser-eyes" d="M50,51 L120,120 M78,51 L120,120" stroke-width="4" stroke-linecap="round"/> </symbol> <use xlink:href="#ninjaCat"/> </svg>
CSS
body { margin: 0; } svg { position: absolute; width: 100vw; height: 100vh; } .laser-eyes { stroke: rgba(100%,0%,0%,0.8); mix-blend-mode: lighten; }
JAVASCRIPT
with(Math)R=random,Q=sqrt,π=PI,S=sin,C=cos W=innerWidth,H=innerHeight function setSize(){ W=innerWidth H=innerHeight s.setAttribute("viewBox",[0,0,W,H].join(",")) } setSize() onresize=setSize laserLeft={x:(R()*128)|0,y:(R()*128)|0} laserRight={x:(R()*128)|0,y:(R()*128)|0} laserTargetLeft={x:(R()*128)|0,y:(R()*128)|0} laserTargetRight={x:(R()*128)|0,y:(R()*128)|0} function distance(p0,p1) { return Q((p1.x-p0.x)*(p1.x-p0.x)+(p1.y-p0.y)*(p1.y-p0.y)) } function randomSparks(p,t,x,y,r,i,d,l){ r="" x=p.x y=p.y for(i=3;i--;){ d=((R()*360)|0)*π/180 l=((R()*80)|0)/10 r+="M"+x+","+y+" L"+((x+C(d)*l)|0)+","+((y+S(d)*l)|0)+" " } return r } onmousemove=function(e){ laserTargetLeft.x=128*e.clientX/W laserTargetLeft.y=128*e.clientY/H laserTargetRight.x=128*e.clientX/W laserTargetRight.y=128*e.clientY/H } onblur=function(e){ laserTargetLeft={x:(R()*128)|0,y:(R()*128)|0} laserTargetRight={x:(R()*128)|0,y:(R()*128)|0} } ~function L(t){ document.body.style.background="hsl("+(((t/10)|0)%360)+",33%,44%)"; [].slice.call(document.querySelectorAll('.laser-eyes')).forEach(function (path){ path.setAttribute("d", "M50,51 L"+laserLeft.x+","+laserLeft.y + " M78,51 L"+laserRight.x+","+laserRight.y + " " + randomSparks(laserLeft,t)+" "+randomSparks(laserRight,t) ) if(laserLeft.x<laserTargetLeft.x)laserLeft.x+=.5 if(laserLeft.x>laserTargetLeft.x)laserLeft.x-=.5 if(laserLeft.y<laserTargetLeft.y)laserLeft.y+=.5 if(laserLeft.y>laserTargetLeft.y)laserLeft.y-=.5 if(distance(laserLeft,laserTargetLeft)<2)laserTargetLeft={x:(R()*128)|0,y:(R()*128)|0} if(laserRight.x<laserTargetRight.x)laserRight.x+=.5 if(laserRight.x>laserTargetRight.x)laserRight.x-=.5 if(laserRight.y<laserTargetRight.y)laserRight.y+=.5 if(laserRight.y>laserTargetRight.y)laserRight.y-=.5 if(distance(laserRight,laserTargetRight)<2)laserTargetRight={x:(R()*128)|0,y:(R()*128)|0} }) requestAnimationFrame(L) }(0)
Expand for more options Login