HTML5 CSS3 (Animations, Blend Modes) JS (Canvas)
Created
February 24, 2019 22:33
-
-
Save yohannawaliya/25ae8694bcbad523e7466dd395fc20d5 to your computer and use it in GitHub Desktop.
#codevember - Day 19 - Ocean
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="page"> | |
<div class="data"> | |
<h1>Oceans</h1> | |
<h2>#Codevember</h2> | |
<a class="ghost" href="https://twitter.com/Manz" target="_blank">Code by Manz</a> | |
<a class="ghost" href="https://soundcloud.com/jjayberthume/ocean-side-8-bit" target="_blank">Music by JJayBerthume</a> | |
</div> | |
<div id="screen" class="sky"> | |
<div class="clouds"></div> | |
<div class="moon"></div> | |
<div class="moon reflect"></div> | |
<canvas id="canvas"></canvas> | |
</div> | |
</div> | |
<audio id="song" src="https://cdn.rawgit.com/ManzDev/codevember2017/master/assets/ocean-side-by-jjayberthume.mp3"></audio> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let canvas = document.querySelector('#canvas'); | |
let ctx = canvas.getContext('2d'); | |
canvas.width = innerWidth; | |
canvas.height = innerHeight; | |
let song = document.querySelector('#song'); | |
setTimeout(() => { song.play() } , 1000); | |
let horizont = canvas.height / 2; | |
let totalwaves = 70, | |
totalfishes = 30, | |
totalclouds = 10; | |
let fishImg = document.createElement('img'); | |
fishImg.src = 'https://cdn.rawgit.com/ManzDev/codevember2017/master/assets/fishes.png'; | |
let cloudsParent = document.querySelector('.clouds'); | |
function clearScreen() { | |
ctx.clearRect(0, horizont, canvas.width, canvas.height); | |
} | |
function drawSea() { | |
ctx.globalAlpha = 0.65; | |
ctx.fillStyle = '#254a6b'; | |
ctx.fillRect(0, horizont, canvas.width, canvas.height); | |
ctx.globalAlpha = 1.0; | |
} | |
function rnd(min, max) { | |
return min + ~~(Math.random() * (max - min)); | |
} | |
class Wave { | |
constructor(x, y) { | |
this.x = x; | |
this.y = y; | |
this.size = rnd(5, 40) * rnd(1, 5); | |
this.small = true; | |
this.color = ['#4591a8','#5ba4ba','#316b7c'][rnd(0,3)]; | |
this.speed = 10; | |
} | |
update() { | |
if (this.speed > 0) { | |
this.speed--; | |
return; | |
} | |
else | |
this.speed = 10; | |
if (this.small) { | |
this.x -= 2; | |
this.size += 4; | |
this.small = false; | |
} | |
else { | |
this.x += 2; | |
this.size -= 4; | |
this.small = true; | |
} | |
} | |
draw() { | |
ctx.beginPath(); | |
ctx.strokeStyle = this.color; | |
ctx.lineWidth = 3; | |
ctx.moveTo(this.x, this.y); | |
ctx.lineTo(this.x + this.size, this.y); | |
ctx.stroke(); | |
} | |
} | |
class Cloud { | |
constructor() { | |
this.type = rnd(1,4); | |
this.x = rnd(-256, canvas.width); | |
this.y = rnd(0, 64); | |
this.rate = 3; | |
// element | |
this.cloud = document.createElement('div'); | |
this.cloud.className = 'cloud type' + this.type; | |
cloudsParent.appendChild(this.cloud); | |
} | |
generate() { | |
this.x = rnd(-512, -256); | |
this.y = rnd(0, 64); | |
} | |
update() { | |
if (this.rate > 0) { | |
this.rate--; | |
return; | |
} else | |
this.rate = 3; | |
this.x += 1; | |
if (this.x > canvas.width + 256) | |
this.generate(); | |
} | |
draw() { | |
this.cloud.style.left = this.x + 'px'; | |
this.cloud.style.top = this.y + 'px'; | |
} | |
} | |
class Fish { | |
constructor() { | |
this.type = rnd(0,3); | |
this.size = 128; | |
this.generate(); | |
} | |
generate() { | |
this.x = -512 + rnd(0, 512); | |
this.y = rnd(horizont, canvas.height - 128); | |
} | |
update() { | |
if (this.y > horizont+5) | |
this.y += rnd(-1, 2); | |
else | |
this.y += rnd(0, 2); | |
this.x += rnd(0, 3); | |
if (this.x > canvas.width + 256) | |
this.generate(); | |
} | |
draw() { | |
ctx.drawImage(fishImg, 128, 128 * this.type, 128, 128, this.x, this.y, 64, 64); | |
} | |
} | |
ctx.beginPath(); | |
ctx.lineWidth = 2; | |
ctx.strokeStyle = '#074659' | |
ctx.moveTo(0, horizont-1); | |
ctx.lineTo(canvas.width, horizont-1); | |
ctx.stroke(); | |
// Init | |
let waves = [], | |
fishs = [], | |
clouds = []; | |
for (let i = 0; i < totalwaves; i++) | |
waves[i] = new Wave(rnd(0, canvas.width), rnd(horizont +1, canvas.height)); | |
for (let i = 0; i < totalfishes; i++) | |
fishs[i] = new Fish(); | |
for (let i = 0; i < totalclouds; i++) | |
clouds[i] = new Cloud(); | |
fishs[totalfishes - 1].type = 3; | |
fishs[totalfishes - 1].x = -640; | |
// Loop | |
function update() { | |
for (let i = 0; i < totalwaves; i++) | |
waves[i].update(); | |
for (let i = 0; i < totalfishes; i++) | |
fishs[i].update(); | |
for (let i = 0; i < totalclouds; i++) | |
clouds[i].update(); | |
} | |
function draw() { | |
clearScreen(); | |
for (let i = 0; i < totalfishes; i++) | |
fishs[i].draw(); | |
for (let i = 0; i < totalwaves; i++) | |
waves[i].draw(); | |
for (let i = 0; i < totalclouds; i++) | |
clouds[i].draw(); | |
drawSea(); | |
} | |
function loop() { | |
requestAnimationFrame(loop); | |
update(); | |
draw(); | |
} | |
loop(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import url('https://fonts.googleapis.com/css?family=Montserrat:400,600|Lobster'); | |
html { | |
background:#000; | |
overflow:hidden; | |
} | |
.data { | |
position:relative; | |
z-index:1; | |
text-align:center; | |
} | |
h1, h2, .ghost { | |
font-family:Montserrat; | |
font-weight:600; | |
margin:0; | |
} | |
h1 { | |
font-family:Lobster; | |
font-size:64px; | |
color:#000; | |
text-shadow:0 0 10px #ceac03; | |
} | |
h2 { | |
font-size:24px; | |
color:#111; | |
text-shadow:0 0 15px #FFF; | |
} | |
.ghost { | |
font-weight:400; | |
font-size:15px; | |
color:#CCC; | |
display:inline-block; | |
margin:8px 2px; | |
padding:8px; | |
border:1px solid #CCC; | |
text-decoration:none; | |
} | |
a.ghost:hover { | |
transition:all .5s linear; | |
background:rgba(50,50,50, .2); | |
border-color:#f2ea00; | |
color:#f2ea00; | |
} | |
#screen { | |
position:absolute; | |
top:0; | |
left:0; | |
width:100vw; | |
height:100vh; | |
} | |
/*** Codevember ***/ | |
.moon { | |
position:absolute; | |
width:128px; | |
height:128px; | |
border-radius:50%; | |
background:#FFF; | |
z-index:-1; | |
opacity:1; | |
animation:moonmove 60s linear infinite; | |
} | |
@keyframes moonmove { | |
0% { | |
top:calc(100vh - 128px); | |
left:-256px; | |
} | |
25%, 75% { | |
top:calc(30vh - 128px); | |
} | |
50% { | |
top:calc(3vh); | |
} | |
100% { | |
top:calc(100vh - 128px); | |
left:calc(100vw + 256px); | |
} | |
25%, 75% { opacity: 1; box-shadow:0 0 25px RGBA(255,255,255, .75) } | |
0%, 100% { opacity: 0; box-shadow:0 0 25px RGBA(255,255,255, 0) } | |
} | |
#canvas { | |
background: linear-gradient(to bottom, transparent, #000 50%); | |
} | |
.cloud { | |
position:absolute; | |
width:256px; | |
height:128px; | |
background:url(https://cdn.rawgit.com/ManzDev/codevember2017/master/assets/pixel-cloud.png); | |
animation:cloud 120s linear infinite; | |
mix-blend-mode:soft-light; | |
} | |
.cloud.type1 { background-position:0 0; } | |
.cloud.type2 { background-position:0 128px; } | |
.cloud.type3 { background-position:0 0; transform:scaleX(-1) } | |
.cloud.type4 { background-position:0 128px; transform:scaleX(-1) } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment