Toggle navigation
Sign Up
Log In
Explore
Works
Folders
Tools
Collections
Artists
Groups
Groups
Topics
Tasks
Tasks
Jobs
Teams
Jobs
Recommendation
More Effects...
JS
var mRenderer, mScene; window.onload = init; function init() { initRenderer(); initNodes(); requestAnimationFrame(loop); } function initRenderer() { mRenderer = new Renderer('#canvas'); mScene = new Node(); } function initNodes() { var skyNode = new Node(new Sky(600, 500, '#ffcbbb', '#ffe2c0')); mScene.add(skyNode); var waveNode, islandNode; islandNode = new Node(new Island( randomRange(60, 200), randomRange(120, 200), randomRange(3, 6) | 0, '#ffcab0','#a38286' )); islandNode.x = randomRange(200, 400); islandNode.y = randomRange(320, 350); mScene.add(islandNode); waveNode = new Node(new Wave(600, 300, 8, '#FFEDCF', '#7680A7')); waveNode.y = 280; mScene.add(waveNode); islandNode = new Node(new Island( randomRange(100, 200), randomRange(100, 200), randomRange(2, 4) | 0, '#ffcab0','#a38286' )); islandNode.x = randomRange(0, 300); islandNode.y = randomRange(320, 350); mScene.add(islandNode); waveNode = new Node(new Wave(600, 300, 8, '#FFDFCC', '#7680A7')); waveNode.y = 290; mScene.add(waveNode); islandNode = new Node(new Island( randomRange(100, 200), randomRange(100, 200), randomRange(2, 4) | 0, '#ffcab0','#a38286' )); islandNode.x = randomRange(300, 600); islandNode.y = randomRange(320, 350); mScene.add(islandNode); waveNode = new Node(new Wave(600, 300, 8, '#FFE4CD', '#7680A7')); waveNode.y = 300; mScene.add(waveNode); initRays(waveNode); var sunNode = new Node(new Sun(40, 300, '#ffefcb')); sunNode.x = 400; sunNode.y = 100; mScene.add(sunNode); } function initRays(waveNode) { var rayNode, width, height, angle; var count = 16, dx = 600 / count; for (var i = 0; i < count; i++) { width = randomRange(60, 120); height = width * 12; angle = Math.PI * randomRange(0.2, 0.8); rayNode = new Node(new Ray(width, height, angle)); rayNode.x = i * dx + randomRange(-40, 40); rayNode.y = -50; rayNode.rotation = Math.PI * 0.04; waveNode.add(rayNode); } } ///////////////////////////// // LOOP ///////////////////////////// function draw() { // shadow all the things mRenderer.ctx.shadowColor = 'rgba(255,239,203,0.5)'; mRenderer.ctx.shadowBlur = 64; mRenderer.render(mScene); } function loop() { draw(); requestAnimationFrame(loop); } ///////////////////////////// // Classes ///////////////////////////// function Wave(width, height, segments, colorTop, colorBottom) { this.verts = []; this.time = Math.random() * Math.PI; this.speed = (1/60); var dx = width / segments, xOffset = 0, yOffset = 0, turbulence = 10; for (var i = 0; i <= segments; i++) { xOffset = (i === 0 || i === segments) ? 0: randomRange(-turbulence, turbulence); yOffset = randomRange(-turbulence, turbulence); this.verts.push([dx * i + xOffset, yOffset]); } this.verts.push([width, height], [0, height]); this.fill = mRenderer.ctx.createLinearGradient(0, 0, 0, height); this.fill.addColorStop(0, colorTop); this.fill.addColorStop(1, colorBottom); } Wave.prototype = { draw:function(ctx) { this.time += this.speed; ctx.beginPath(); ctx.fillStyle = this.fill; for (var i = 0; i < this.verts.length - 2; i++) { ctx.lineTo( this.verts[i][0], this.verts[i][1] + Math.sin(this.time + i) * 8); } ctx.lineTo.apply(ctx, this.verts[this.verts.length - 2]); ctx.lineTo.apply(ctx, this.verts[this.verts.length - 1]); ctx.closePath(); ctx.fill(); ctx.clip(); } }; function Ray(width, height, angle) { this.width = width; this.height = height; this.angle = angle; this.time = Math.random() * Math.PI; this.speed = (1/60); var gradientX = Math.cos(this.angle) * this.height, gradientY = Math.sin(this.angle) * this.height; this.fill = mRenderer.ctx.createLinearGradient(0, 0, gradientX, gradientY); this.fill.addColorStop(0, 'rgba(255, 255, 255, 0.040)'); this.fill.addColorStop(0.3, 'rgba(255, 255, 255, 0.025)'); this.fill.addColorStop(1, 'rgba(255, 255, 255, 0.0)'); } Ray.prototype = { draw:function(ctx) { this.time += this.speed; var offsetX = Math.sin(this.time) * 10; ctx.globalCompositeOperation = 'lighter'; ctx.fillStyle = this.fill; ctx.fillRect(offsetX, 0, this.width, this.height); } }; function Sky(width, height, color1, color2) { this.width = width; this.height = height; this.fill = mRenderer.ctx.createLinearGradient(0, 0, 0, height); this.fill.addColorStop(0, color1); this.fill.addColorStop(1, color2); } Sky.prototype = { draw:function(ctx) { ctx.fillStyle = this.fill; ctx.fillRect(0, 0, this.width, this.height); } }; function Island(width, height, steps, color1, color2) { function getVert(a) { return [Math.cos(a) * width, Math.sin(a) * height]; } var angle = Math.PI; this.verts = []; this.verts.push(getVert(angle)); for (var i = 0; i < steps; i++) { angle += (Math.PI / steps) * randomRange(0.5, 1.0); this.verts.push(getVert(angle)); } this.verts.push(getVert(0)); this.fill = mRenderer.ctx.createLinearGradient(0, -height, 0, 0); this.fill.addColorStop(0, color1); this.fill.addColorStop(1, color2); } Island.prototype = { draw:function(ctx) { ctx.beginPath(); ctx.fillStyle = this.fill; for (var i = 0; i < this.verts.length; i++) { ctx.lineTo.apply(ctx, this.verts[i]); } ctx.closePath(); ctx.fill(); } }; function Sun(innerRadius, outerRadius, color1) { this.innerRadius = innerRadius; this.outerRadius = outerRadius; this.color1 = color1; this.gradient = mRenderer.ctx.createRadialGradient(0, 0, 0, 0, 0, outerRadius); this.gradient.addColorStop(0, 'rgba(255,255,255,0.2)'); this.gradient.addColorStop(1, 'rgba(255,255,255,0.0)'); } Sun.prototype = { draw:function(ctx) { ctx.fillStyle = this.gradient; ctx.globalCompositeOperation = 'lighter'; ctx.beginPath(); ctx.arc(0, 0, this.outerRadius, 0, Math.TWO_PI); ctx.fill(); ctx.fillStyle = this.color1; ctx.beginPath(); ctx.arc(0, 0, this.innerRadius, 0, Math.TWO_PI); ctx.fill(); } }; function Renderer(selector, width, height) { this.canvas = document.querySelector(selector); this.ctx = this.canvas.getContext('2d'); this.viewWidth = this.canvas.width = width || this.canvas.clientWidth; this.viewHeight = this.canvas.height = height || this.canvas.clientHeight; } Renderer.prototype = { render:function(node) { this.ctx.clearRect(0, 0, this.viewWidth, this.viewHeight); node.render(this.ctx); } }; function Node(graphics) { this.graphics = graphics; this.x = 0; this.y = 0; this.pivotX = 0; this.pivotY = 0; this.scaleX = 1; this.scaleY = 1; this.rotation = 0; this.children = []; } Node.prototype = { add:function(node) { this.children.push(node); }, remove:function(node) { var i = this.children.indexOf(node); if (i >= 0) { this.children.splice(i, 1); } }, render:function(ctx) { ctx.save(); ctx.translate(this.pivotX + this.x, this.pivotY + this.y); ctx.rotate(this.rotation); ctx.scale(this.scaleX, this.scaleY); ctx.translate(-this.pivotX, -this.pivotY); this.graphics && this.graphics.draw(ctx); for (var i = 0; i < this.children.length; i++) { this.children[i].render(ctx); } ctx.restore(); } }; ///////////////////////////// // utils ///////////////////////////// function randomRange(min, max) { return min + Math.random() * (max - min); } Math.TWO_PI = Math.PI * 2;
CSS
body { margin: 0; background: #fff; } #canvas { position: absolute; margin: auto; width: 600px; height: 600px; top: 0; bottom: 0; left: 0; right: 0; }
HTML
Join Effecthub.com
Working with Global Gaming Artists and Developers!
Login
Sign Up
Or Login with Your Email Address:
Email
Password
Remember
Or Sign Up with Your Email Address:
Your Email
This field must contain a valid email
Set Password
Password should be at least 1 character
Stay informed via email