javascript - Creating animated rainbows via pure js -
the code (pure js) creating animated rainbow in successive rainbows delayed bit of time. animation not consistent (slows down eventually). beginner in programming code getting lengthy too.
if run code on local, animation slows down after bit of time , there no consistency in way rainbows coming out (there should time gap between each rainbow). second issue want reduce code dont have create function each , every rainbow animation.
function anim() { var x,y,z,p,q,r; x = y = z = p = q = r = 2*math.pi; var c = document.getelementbyid("mycanvas"); var ctx = c.getcontext("2d"); ctx.clearrect(0,0,c.width,c.height); var id = setinterval(frame_one,1); var t = setinterval(frame_two,1); var u = setinterval(frame_three,1); var v = setinterval(frame_four,1); var w = setinterval(frame_five,1); var s = setinterval(frame_six,1); function frame_one() { if (x <=(math.pi)) { clearinterval(id); x = 2*math.pi; } else { x = x - 0.036; ctx.linewidth = 20; ctx.beginpath(); ctx.arc(c.width/2, c.height/2, c.height/2-20, 2* math.pi,x,true); ctx.strokestyle="red"; ctx.stroke(); } } function frame_two() { if (y <= (math.pi)) { y = 2*math.pi; clearinterval(t); } else { y= y - 0.032; ctx.beginpath(); ctx.linewidth=20; ctx.arc(c.width/2,c.height/2, c.height/2-40, 2* math.pi,y,true); ctx.strokestyle="orange"; ctx.stroke(); } } function frame_three() { if (z <= (math.pi)) { clearinterval(u); } else { z = z - 0.028; ctx.beginpath(); ctx.linewidth = 20; ctx.arc(c.width/2,c.height/2,(c.height)/2-60, 2* math.pi,z,true); ctx.strokestyle = "yellow"; ctx.stroke(); } } function frame_four() { if (p <= (math.pi)) { clearinterval(v); } else { p = p - 0.024; ctx.beginpath(); ctx.linewidth = 20; ctx.arc(c.width/2,c.height/2,(c.height)/2-80, 2* math.pi,p,true); ctx.strokestyle = "green"; ctx.stroke(); } } function frame_five() { if (q <= (math.pi)) { clearinterval(w); } else { q = q - 0.020; ctx.beginpath(); ctx.linewidth = 20; ctx.arc(c.width/2,c.height/2,(c.height)/2-100, 2* math.pi,q,true); ctx.strokestyle = "blue"; ctx.stroke(); } } function frame_six() { if (r <= (math.pi)) { clearinterval(s); } else { r = r - 0.016; ctx.beginpath(); ctx.linewidth = 20; ctx.arc(c.width/2,c.height/2,(c.height)/2-120, 2* math.pi,r,true); ctx.strokestyle = "violet"; ctx.stroke(); } } } anim(); setinterval(anim,3000);
<canvas onclick="info()" id="mycanvas" width="500" height="500" style="border:1px solid #d3d3d3;"></canvas>
this 1 of several approaches. 1 of reason why inner circle seems animate slower due size: since it's smaller move in smaller step in same period of time. can compensate reducing duration time.
example code
using stroke combined line-width instead of fills allows use cap types such "round" (shown below), simplifies calculations needed.
and of course, recommend clearing each frame remove overlapping anti-aliased pixels make hard edge.
var ctx = c.getcontext("2d"), /* these settings dynamic 1 can alter number of colors, sizes, line width etc. without modifying code */ colors = ["red", "orange", "yellow", "green", "blue", "violet"], radius = 140, // max radius linewidth = 16, // width of each arc in pixels delay = 300, // ms duration = 1000, // ms (per arc) starttime; // animation loop // initialize common line width , cap ctx.linewidth = linewidth; ctx.linecap = "round"; // helper: draw arc start end angle @ given color , position // arc(): https://devdocs.io/dom/canvasrenderingcontext2d/arc function arc(radius, angle, color) { ctx.beginpath(); // clear existing path , sub-paths ctx.arc(c.width*0.5, c.height, radius, angle, math.pi*2); // end-angle 360° ctx.strokestyle = color; ctx.stroke(); // render arc } function draw(time) { if (!starttime) starttime = time; // initialize start time if none initialized ctx.clearrect(0,0,c.width,c.height); // clear canvas per frame // iterate on color-array, each color entry: colors.foreach(function(color, i) { /* calc t normalized value. we're interested in values between [0, 1]. offset delay can use current index times delay. subtract current time delay. starttime subtracted relative beginning of animation. , divide on duration normalize. */ var t = ((time - * delay) - starttime) / duration; /* t may lower 0; we're interested in t when equal or more 0. don't care being above 1 since clamp angle below , need redraw each arc per frame */ if (t >= 0) { /* arc(radius, startangle, color) here calculate radius max minus linewidth times index of color. start angle start @ 360° (in radians 2xpi). use normalized t value of 180° (or pi in radians). subtract 360 go [360°, 180°], e.g. drawing arc right side left going in arc on canvas (not under). , pass in current color */ arc(radius - linewidth * i, math.max(math.pi, math.pi * 2 - math.pi * t), color); } }); /* animate until drawn. calculate max time using duration + each delay times number of colors */ if (time < starttime + colors.length * delay + duration) requestanimationframe(draw); } // invoke animation passing time argument requestanimationframe(draw);
<canvas id=c></canvas>
Comments
Post a Comment