.container
.reveal
img
canvas#particles
button.btn-trigger#trigger poof!
View Compiled
body{
background: #333;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100vh;
}
.container{
position: relative;
width: 800px;
height: 600px;
background: #222 url(https://c.tadst.com/gfx/750x500/smoke-and-mirrors-day.jpg?1) no-repeat center center;
background-size: cover;
}
.reveal{
position: absolute;
top: 400px;
left: 390px;
img{
position: absolute;
bottom: 0;
transform: translate(-50%,0);
max-width: 200px;
}
}
.smoke-particle{
background: url(https://mephysto.github.io/sandbox/smoke.png) no-repeat center center;
background-size: cover;
width: 100px;
height: 86px;
}
canvas{
position: absolute;
top: 0;
left: 0;
}
button{
border: none;
background: white;
font-size: 3em;
text-transform: uppercase;
padding: 10px 40px;
margin-top: 45px;
border-radius: 50px;
line-height: 1em;
box-shadow: 5px 5px 0 0 #000;
}
View Compiled
var canvas, ctx;
const particleCount = 200;
let particles = [];
const cWidth = 800;
const cHeight = 600;
const maxLife = 8000;
const minLife = 5000;
// const imagePath = "http://www.freeiconspng.com/uploads/smoke-12.png";
// const imagePath = "http://gallery.yopriceville.com/var/resizes/Free-Clipart-Pictures/Smoke-PNG/Smoke_Transparent_PNG_Clipart_Image.png";
// const imagePath = "https://mephysto.github.io/sandbox/smoke.png";
// const imagePath = "http://www.pngmart.com/files/3/Smoke-Transparent-PNG.png";
const imagePath = "http://www.fun-lover.com/graphic-shop/Halloween/images/FireSmoke/smoke-036.png";
var stage;
var canvas;
var bitmap;
var image = new Image();
function rand(min, max) {
return (Math.floor(Math.random() * (max*1000 - min*1000 + 1)) + min*1000)/1000;
}
// one particle class
function smokeParticle(){
this.life = rand(minLife, maxLife);
// TODO: add origin point randomizer
this.asset = this.asset || new createjs.Bitmap(image);
this.origassetWidth = this.asset.image.width;
this.origassetHeight = this.asset.image.height;
this.assetWidth = this.asset.image.width;
this.assetHeight = this.asset.image.height;
this.originX = canvas.width * .5 - (this.assetWidth * 0.5);
this.originY = canvas.height * .5 - (this.assetHeight * 0.5);
this.asset.x = this.originX;
this.asset.y = this.originY;
this.reset = function(){
this.assetWidth = this.asset.image.width;
this.assetHeight = this.asset.image.height;
this.asset.scaleX = rand(0.2, .5);
this.asset.scaleY = rand(0.2, .5);
this.originX = canvas.width * .5 - (this.origassetWidth * .5 * this.asset.scaleX);
this.originY = canvas.height * .5 - (this.origassetHeight * .5 * this.asset.scaleY);
this.asset.alpha = rand(0.5, 1);
this.valpha = rand(0.02, 0.03);
this.vx = (Math.random() - 0.5) * 20;
this.vy = (Math.random() - 0.5) * 15;
this.rotation = (Math.random() - 0.5) * .5;
this.life = rand(minLife, maxLife);
this.asset.alpha = rand(0.5, 1);
this.asset.x = this.originX;
this.asset.y = this.originY;
}
}
// (re)set all particle values to start
const trigger = function(){
particles.map(function(particle){
particle.reset();
stage.addChild(particle.asset);
});
}
// initial set up for all particles
const build = function(){
// create all particles
for (var i = particleCount - 1; i >= 0; i--) {
let newParticle = new smokeParticle();
particles.push(newParticle);
}
// put all particles on stage
trigger();
createjs.Ticker.setFPS(90);
createjs.Ticker.addEventListener("tick", render);
}
// what happens during a render
const render = function(){
let part;
for (var i = particles.length - 1; i >= 0; i--) {
part = particles[i];
part.asset.x = part.asset.x + part.vx;
part.asset.y = part.asset.y + part.vy;
part.asset.rotation = part.asset.rotation + part.rotation;
if(part.asset.x > canvas.width || part.x < 0){
stage.removeChild(part.asset);
}
if(part.asset.y > canvas.height || part.y < 0){
stage.removeChild(part.asset);
}
part.life--;
if (part.life <= 0){
stage.removeChild(part.asset);
}
// part.asset.alpha-=0.042;}
part.asset.alpha = part.asset.alpha - part.valpha;
}
stage.update();
}
const PreloadAssets = (_options) => {
let imgcount = 0,
callback,
img
var preloadImage = (assetURL, assetsArray) => {
if (assetURL === '') {
imgcount++
if (imgcount === assetsArray.length) {
callback.call()
}
} else {
img = new Image()
img.onload = () => {
imgcount++
if (imgcount === assetsArray.length) {
callback.call()
}
}
img.src = assetURL
}
}
return {
preload: (_array, _callback) => {
callback = _callback
for (var i = 0; i < _array.length; i++) {
preloadImage(_array[i], _array)
}
}
}
}
// on DOM init
function init() {
let onImageLoaded = function (e){
console.log(`let's start`);
build();
}
canvas = document.getElementById('particles');
stage = new createjs.Stage(canvas);
canvas.width = cWidth;
canvas.height = cHeight;
image = new Image();
image.name = "smoke";
image.src = imagePath;
image.onload = onImageLoaded;
document.getElementById('trigger').onclick = onTriggerClick;
}
document.addEventListener("DOMContentLoaded", function() {
init();
});
const randomImages = [
'https://media.giphy.com/media/Hv4HcD1xAho1a/giphy.gif',
'http://vignette2.wikia.nocookie.net/hayday/images/4/44/White_Bunny.png/revision/latest/scale-to-width-down/100?cb=20150711214507',
'https://lh3.googleusercontent.com/kMP05B4UUGphEbLz0Xo-1pPgOfLG2Ezowu-e1YFEyNSh43QD_6gFNgi3IyWbeH4y7U4=w100',
'https://i.gifer.com/tGW.gif',
// 'http://findicons.com/files/icons/1012/racing_cars/128/ford_gt.png',
// 'https://66.media.tumblr.com/avatar_7fcda8ab63b1_128.png',
'http://www.yes24.vn/Upload02/Event/201601/PPAP_animation.gif',
'http://www.yes24.vn/Upload02/Event/201601/PPAP_animation.gif',
'http://78.media.tumblr.com/tumblr_mbnik2lM8i1qdpzt2o1_500.gif',
'https://66.media.tumblr.com/b2bfb7a9e3a5aa156411a0ecae55c581/tumblr_o26u8a7Ym81v0w4w9o1_250.gif',
'https://66.media.tumblr.com/1db6b33020ba33a5ec53a6d3c09ccff7/tumblr_nabnz3kUKx1rrckl5o1_500.gif'
]
PreloadAssets().preload(randomImages, () =>{});
const onTriggerClick = function(){
let img = document.querySelector('.reveal img');
let randimg = randomImages[~~(rand(0, randomImages.length))];
while (img.src === randimg){
randimg = randomImages[~~(rand(0, randomImages.length))];
}
console.log(randimg);
img.src = randimg;
trigger();
}
View Compiled
This Pen doesn't use any external CSS resources.