<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<!DOCTYPE html><html lang='en' class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/zachernuk/pen/aJgYvN" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<style class="cp-pen-styles">
.canvas-outer {
margin:auto;
background:linear-gradient(to bottom, #a7f1ff, #f1feff 50%);
border-radius:298px;
width:564px;
height:564px;
position:relative;
top:50vh;
margin-top:-267px;
left:50vw;
margin-left:-267px;
}
#canvas {
border-radius:500px;
position:absolute;
}
#canvas2 {
position:absolute;
top:100px;
left:100px;
top:0;
}
.body {
height:100vh;
width:100vw;
position:fixed;
top:0;
left:0;
background:radial-gradient(circle, white 10%, #e9feff);
}</style></head><body>
<div class="body">
<div class="canvas-outer">
<canvas id="canvas2" width="300" height="564"></canvas>
<canvas id="canvas" width="564" height="564"></canvas>
</div>
</div>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script>
<script >
(()=>{
const c = document.getElementById('canvas2');
const g = c.getContext('2d');
c.style.width = (c.width/devicePixelRatio)+"px";
c.style.height = (c.height/devicePixelRatio)+"px";
let t =0 ;
const colorAt = y=>{
const min = 45;
const max = 70;
//let's set the y start and end positions for this:
const f = Math.max(0, Math.min(1,(y-min)/(max-min)));
const i = 1-f;
return "rgb("+[[255,254],[240,86],[155,180]].map(
p=>{
const out =Math.round(p[0]*i+p[1]*f);
// console.log("out is ", out);
return out}).join(",")+")";
};
setInterval(()=>{
c.width = c.width;
g.translate(0,(100*Math.sin(t++/10000)));
[170,150, 120, 90,60].forEach((r,i,a)=>{
g.beginPath();
g.globalAlpha =Math.pow( (i+1)/a.length,2);
g.arc(150,150, r/2,0,7);
g.fill();
});
g.globalCompositeOperation = "source-atop";
g.globalAlpha = 1;
g.scale(3,3);
for(var i =0;i<15;i++) {if (window.CP.shouldStopExecution(2)){break;}
g.lineWidth = 13;
const grad = g.createLinearGradient(0,i*12-9, 0,i*12+9);
grad.addColorStop(0,colorAt(i*12));
grad.addColorStop(0.49,colorAt(i*12+12));
// grad.addColorStop(0.51,"green");
grad.addColorStop(1,colorAt(i*12+32));
g.strokeStyle = grad;
g.beginPath();
for(var x=0;x<300;x+=5) {if (window.CP.shouldStopExecution(1)){break;}
const env = (x/100)*(1-x/100);
g.lineTo(x, i*12+20*Math.cos(x/8+t/3000)*Math.cos(t/5000)*env);
}
window.CP.exitedLoop(1);
g.stroke();
}
window.CP.exitedLoop(2);
},16);
})();
const c = document.getElementById('canvas');
const g = c.getContext('2d');
c.style.width = (c.width/devicePixelRatio)+"px";
c.style.height = (c.height/devicePixelRatio)+"px";
Object.assign(document.querySelector('.canvas-outer').style,
{
width:(564/devicePixelRatio).toFixed()+"px",
height:(564/devicePixelRatio).toFixed()+"px",
marginLeft:(-564/devicePixelRatio/2).toFixed()+"px",
marginTop:(-564/devicePixelRatio/2).toFixed()+"px",
});
const omega = 590;
class Point {
constructor(x,y) {
this.x = x;
this.y = y;
}
fromPolar(radius,angle) {
this.x = radius*Math.cos(angle);
this.y=radius*Math.sin(angle);
return this;
}
add(p) {
this.x+=p.x;
this.y+=p.y;
return this;
}
sub(p) {
this.x-=p.x;
this.y-=p.y;
return this;
}
length() {
return Math.sqrt(this.lengthSquared());
}
lengthSquared() {
return this.x*this.x+this.y*this.y;
}
clone() {
return new Point(this.x,this.y);
}
}
const center = new Point(canvas.width/2,canvas.height/2);
const arc = (r,theta)=> {
r-=6;
g.arc(center.x,center.y, r,0-theta , Math.PI+theta);
return {end:new Point().fromPolar(r, -theta).add(center),
start:new Point().fromPolar(r, Math.PI+theta).add(center)};
}
const BORDER = "#d6f9ff";
let prev = [];
const update = ()=>{
c.width = c.width;
g.strokeStyle = BORDER;
g.lineWidth = 20;
g.beginPath()
arc(279, Math.PI);
g.stroke();
g.save();
clouds.forEach(cloud=>cloud.update());
g.restore();
let toRight = g.createLinearGradient(512,200,400, 400);
toRight.addColorStop(1, "rgba(1,230,255,0)");
toRight.addColorStop(0, "rgba(1,230,255,0.48)");
const vGrag0 = g.createLinearGradient(0, 180, 0, 350);
vGrag0.addColorStop(0, "rgb(0,218,230)");
vGrag0.addColorStop(1, "rgb(0,139,255)");
g.fillStyle = vGrag0;
g.beginPath();
let sides = arc(248, 0.0);
let dx = sides.end.x-sides.start.x;
let xo = 0;
for(var x = sides.start.x; x<sides.end.x;xo++,x++) {if (window.CP.shouldStopExecution(3)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
g.lineTo(x, sides.start.y+65*envelope*Math.cos(Date.now()/omega+xo/dx*3));
}
window.CP.exitedLoop(3);
g.fill();
toRight = g.createLinearGradient(512,200,400, 400);
toRight.addColorStop(0, "rgba(1,230,255,0.5)");
toRight.addColorStop(1, "rgba(1,230,255,0.0)");
g.fillStyle = toRight;
g.beginPath();
for(var x = sides.end.x; x>sides.start.x;xo--,x--) {if (window.CP.shouldStopExecution(4)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
g.lineTo(x, sides.start.y+65*envelope*Math.cos(Date.now()/omega+xo/dx*3));
}
window.CP.exitedLoop(4);
for(var x = sides.start.x; x<sides.end.x;xo++,x++) {if (window.CP.shouldStopExecution(5)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
g.lineTo(x, sides.start.y+(65*envelope* Math.cos(Date.now()/omega+xo/dx*3) +55*envelope));
}
window.CP.exitedLoop(5);
g.fill();
g.fillStyle = "rgb(62,224,237) ";
g.beginPath();
sides = arc(250, 0.0);
dx = sides.end.x-sides.start.x;
xo = 0;
for(var x = sides.start.x; x<sides.end.x;xo++,x++) {if (window.CP.shouldStopExecution(6)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
g.lineTo(x, sides.start.y+65*envelope*Math.sin(Date.now()/omega+xo/dx*3));
}
window.CP.exitedLoop(6);
// g.stroke();
g.fill();
const vGrad1 = g.createLinearGradient(0, 230, 0, 390);
vGrad1.addColorStop(0, "rgb(0,218,230)");
vGrad1.addColorStop(1, "rgb(0,139,255)");
g.fillStyle = vGrad1;
g.beginPath();
sides = arc(248, -0.02);
dx = sides.end.x-sides.start.x;
xo = 0;
for(var x = sides.start.x; x<sides.end.x;xo++,x++) {if (window.CP.shouldStopExecution(7)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
g.lineTo(x, sides.start.y+65*envelope*Math.sin(Date.now()/omega+xo/dx*3));
}
window.CP.exitedLoop(7);
g.fill();
toRight = g.createLinearGradient(512,300,400, 500);
toRight.addColorStop(0, "rgba(1,230,255,0.5)");
toRight.addColorStop(1, "rgba(1,230,255,0.0)");
g.fillStyle = toRight;
g.beginPath();
for(var x = sides.end.x; x>sides.start.x;xo--,x--) {if (window.CP.shouldStopExecution(8)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
g.lineTo(x, sides.start.y+65*envelope*Math.sin(Date.now()/omega+xo/dx*3));
}
window.CP.exitedLoop(8);
for(var x = sides.start.x; x<sides.end.x;xo++,x++) {if (window.CP.shouldStopExecution(9)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
const sd = Math.sin(Date.now()/omega+xo/dx*3);
g.lineTo(x, sides.start.y+(65*envelope*sd+90*envelope));
}
window.CP.exitedLoop(9);
g.fill();
const vGrad2 = g.createLinearGradient(0, 310, 0, 512);
vGrad2.addColorStop(0, "rgb(100,218,230)");
vGrad2.addColorStop(1, "rgb(0,139,255)");
g.fillStyle = vGrad2;
g.beginPath();
sides = arc(248, -0.55);
dx = sides.end.x-sides.start.x;
xo = 0;
for(var x = sides.start.x; x<sides.end.x;xo++,x++) {if (window.CP.shouldStopExecution(10)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
g.lineTo(x, sides.start.y+65*envelope*Math.sin(Date.now()/omega+xo/dx*3));
}
window.CP.exitedLoop(10);
g.fill();
g.lineWidth = 4;
g.strokeStyle = "rgb(62,224,237)";
g.fillStyle = toRight;
g.beginPath();
for(var x = sides.end.x; x>sides.start.x;xo--,x--) {if (window.CP.shouldStopExecution(11)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
g.lineTo(x, sides.start.y+65*envelope*Math.sin(Date.now()/omega+xo/dx*3));
}
window.CP.exitedLoop(11);
g.stroke();
let yo = [];
for(var x = sides.start.x; x<sides.end.x;xo++,x++) {if (window.CP.shouldStopExecution(12)){break;}
const envelope = xo/dx*(1-(xo/dx))*4;
const sd = Math.sin(Date.now()/omega+xo/dx*3);
const yy = sides.start.y+(65*envelope*sd+60*envelope);
g.lineTo(x, yy);
yo[Math.floor(x)] = yy;
}
window.CP.exitedLoop(12);
g.fill();
//
let dy = [];
if(prev.length==yo.length) {
dy = yo.map((e,i)=>e-prev[i]);
}
g.globalCompositeOperation = "source-atop";
g.globalAlpha = 0.6;
// debugger;
const bubbleGrad = g.createLinearGradient(0,-9,0,6);
bubbleGrad.addColorStop(1,"rgba(0,240,254,0.6)");
bubbleGrad.addColorStop(0,"rgba(0,240,254,0.0)");
g.fillStyle = bubbleGrad;
bubbles.forEach(b=>{
circle(b.x,b.y,b.r);
let yy = 0;
let xx = Math.floor(b.x);
if(dy[xx]!==undefined) yy=dy[xx]/1.4;
b.y-=b.r/12-yy;
// b.r+=0.05;
b.x-= Math.cos(Date.now()/omega+b.x/512*3)*2*(512-b.y)/1200+1;
if(b.x<0) b.x+=512+Math.random()*60;
if(b.y<218) b.y+=312,b.r= b.or;
});
// circle(100,100, 10);
g.globalCompositeOperation = "source-atop";
g.globalAlpha = 1;
// g.strokeStyle = "#801010";
g.strokeStyle = BORDER;
g.lineWidth = 20;
g.beginPath()
arc(279, 0.3);
g.stroke();
prev = yo;
requestAnimationFrame(update);
}
// debugger;
/*
there are a couple of directions I could move in for this, one is more
interesting horizontal bubble flow.
*/
class Cloud {
constructor(d) {
this.x = Math.random()*0x400;
this.y = 180-Math.random()*140;
214, 249,255
// const d =
const r = (255*d+214*(1-d)).toFixed();
const g = (255*d+249*(1-d)).toFixed();
this.color = "rgb("+r+","+g+",255)";
this.velocity =( 1+d*2)/4;
this.scale = 0.3+d;
const lDelta = Math.random()*16+10;
const rDelta = Math.random()*16+10;
this.boxHeight = Math.min(lDelta,rDelta);
this.left = new Bubble({r:lDelta,x:-30,y:-lDelta});
this.right = new Bubble({r:rDelta,x:30,y:-rDelta});
this.top = new Bubble({r:20,y:-30, x:0});
}
update() {
this.x+=this.velocity;
if(this.x>650) this.x-=750;
this.draw();
}
draw() {
g.translate(this.x, this.y+10);
g.scale(this.scale,this.scale)
g.fillStyle = BORDER;
circle(this.left);
circle(this.right);
circle(this.top);
g.fillRect(-30,-this.boxHeight*2,60,this.boxHeight*2);
g.translate(-this.x, -this.y-10);
g.translate(this.x, this.y);
g.fillStyle = this.color;
circle(this.left);
circle(this.right);
circle(this.top);
g.fillRect(-30,-this.boxHeight*2,60,this.boxHeight*2);
g.scale(1/this.scale,1/this.scale);
g.translate(-this.x, -this.y);
}
}
class Bubble {
constructor(params) {
{
this.x=Math.random()*0x200;
this.y=Math.random()*0x200;
this.or=Math.random()*5+5;
this.r=Math.random()*5+5;
this.vy=Math.random()*3+1;
if(params) Object.assign(this, params);
}
}
}
const bubbles = new Array(30).fill(0).map((e,i)=>new Bubble());
const circle = (o,y,r) => {
if(o.y!=undefined) {
circle(o.x,o.y,o.r);
return;
}
let x = o;
g.translate(x,y);
g.beginPath();
g.arc(0,0,r, 0,7);
g.fill();
g.translate(-x,-y);
}
const clouds = new Array(10).fill(0).map((_,i,a)=>{return new Cloud(i/a.length)});
requestAnimationFrame(update);
//# sourceURL=pen.js
</script>
</body></html>