One way I can think of is with an animated svg, but there is probably a better way. What would you do if you had to animate these wavy blobs (mobile patible)
Link to the only pin I've found similar
var wave = document.createElement("div");
wave.className += " wave";
docFrag.appendChild(wave);
wave.style.left = i * waveWidth + "px";
wave.style.webkitAnimationDelay = (i / 100) + "s";
Touch interaction would be nice too. Would there be any problems with canvas stuff ?
One way I can think of is with an animated svg, but there is probably a better way. What would you do if you had to animate these wavy blobs (mobile patible)
Link to the only pin I've found similar
var wave = document.createElement("div");
wave.className += " wave";
docFrag.appendChild(wave);
wave.style.left = i * waveWidth + "px";
wave.style.webkitAnimationDelay = (i / 100) + "s";
Touch interaction would be nice too. Would there be any problems with canvas stuff ?
Share Improve this question edited Jun 3, 2016 at 23:29 LJᛃ 8,1832 gold badges26 silver badges35 bronze badges asked Jun 3, 2016 at 22:54 DawidDawid 5936 silver badges26 bronze badges 3- 1 Man, seriously? Won't the mobile die for this amount of effect? Just asking. – Praveen Kumar Purushothaman Commented Jun 3, 2016 at 22:56
- 1 I tried stuff with animated svg's and it's allright. I optimised it quite well though... Haven't checked out canvas. It's probably time to try it out – Dawid Commented Jun 4, 2016 at 7:56
- 1 Just for interest, here's an awesome Codepen that I found which does what you want a lot better than the one you linked to... codepen.io/rstacruz/pen/oxJqNv – Ethan Commented Mar 2, 2018 at 6:22
3 Answers
Reset to default 3Here's an implementation of @DA.'s good answer:
var canvas=document.getElementById('canvas');
var ctx=canvas.getContext('2d');
var cw=canvas.width;
var ch=canvas.height;
ctx.textAlign='center';
ctx.textBaseline='middle';
ctx.font='16px verdana';
ctx.lineWidth=5;
ctx.strokeStyle='white';
ctx.fillStyle='white';
var offsetX=0;
var bk=makeWave(canvas.width,canvas.height-120,10,2,'lightskyblue','cornflowerblue');
requestAnimationFrame(animate);
function animate(time){
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(bk,offsetX,0);
ctx.fillStyle='white';
ctx.font='18px verdana';
ctx.fillText('Multiple Lists',cw/2,30);
ctx.strokeRect(cw/2-50,85,100,50);
ctx.fillStyle='gray';
ctx.font='12px verdana';
ctx.fillText('You can create and save multiple ...',cw/2,250);
offsetX-=1;
if(offsetX< -bk.width/2){offsetX=0;}
requestAnimationFrame(animate);
}
function makeWave(width,midWaveY,amplitude,wavesPerWidth,grad0,grad1){
var PI2=Math.PI*2;
var totValue=PI2*wavesPerWidth;
var c=document.createElement('canvas');
var ctx=c.getContext('2d');
c.width=width*2;
c.height=midWaveY+amplitude;
var grad=ctx.createLinearGradient(0,0,0,midWaveY);
grad.addColorStop(0.00,grad0);
grad.addColorStop(1.00,grad1);
//
ctx.beginPath();
ctx.moveTo(0,0);
for (x=0;x<=200;x++) {
var n=totValue*x/100;
ctx.lineTo(width*x/100,Math.sin(n)*amplitude+midWaveY);
}
ctx.lineTo(c.width,0);
ctx.closePath();
ctx.fillStyle=grad;
ctx.fill();
return(c);
}
body{ background-color:white; }
canvas{border:1px solid red; margin:0 auto; }
<canvas id=canvas width=300 height=300></canvas>
I'd make the wave a PNG (bottom solid gray, top transparent). Place it in a div twice the width of the card, and place that in a div the width of the card (this second div is the 'mask').
Then via CSS, have the nested give transform on the x axis to animate it sideways.
You shouldn't need any JS for this.
I would do this:
- on page load create an off-screen canvas (just set
display: none
) - in a for loop pute the wave:
- clear with transparency
- paint only the white part because the colored part has a gradient
- after each paint, get the PNG data out of the canvas and store it in an array
- after the loop you will have an array of PNG images (frames)
- cycle through those frames without reputing the wave over and over again
This requires the wave to have a period that is affine to the number of frames you take (say a 2 second animation at 10 Hz would require 20 frames to be cyclic)
To be honest, you could store that server-side and just download it, without puting it client-side. Those PNG images would be very tiny because there isn't any color involved (just transparent/white/alpha channel). There are optimal settings for this, I guesstimate some 1KB per frame would suffice, that's a tiny 20 KB of images).