Кодинг
★ Рубрика: Кодинг

Красивая javascript анимация на канве: кирпичики

Красивая анимация на сайте может создать атмосферу праздничности и необычности. Здесь приведена демонстрация и коды показанной анимации. Работает и на адаптивных шаблонах.
Для начала разместим на страницу код контейнера для рисования:
< canvas style="width: 100%; height:400px;" id="canvas" >< /canvas >
А затем javascript-код:
var canvas,
 ctx,
 width,
 height,
 size,
 lines,
 tick;

function line() {
 this.path = [];
 this.speed = rand( 10, 20 );
 this.count = randInt( 10, 30 );
 this.x = width / 2, + 1;
 this.y = height / 2 + 1;
 this.target = { x: width / 2, y: height / 2 };
 this.dist = 0;
 this.angle = 0;
 this.hue = tick / 5;
 this.life = 1;
 this.updateAngle();
 this.updateDist();
}

line.prototype.step = function( i ) {
 this.x += Math.cos( this.angle ) * this.speed;
 this.y += Math.sin( this.angle ) * this.speed;
 
 this.updateDist();
 
 if( this.dist < this.speed ) {
 this.x = this.target.x;
 this.y = this.target.y;
 this.changeTarget();
 }
 
 this.path.push( { x: this.x, y: this.y } ); 
 if( this.path.length > this.count ) {
 this.path.shift();
 }
 
 this.life -= 0.001;
 
 if( this.life <= 0 ) {
 this.path = null;
 lines.splice( i, 1 ); 
 }
};

line.prototype.updateDist = function() {
 var dx = this.target.x - this.x,
 dy = this.target.y - this.y;
 this.dist = Math.sqrt( dx * dx + dy * dy );
}

line.prototype.updateAngle = function() {
 var dx = this.target.x - this.x,
 dy = this.target.y - this.y;
 this.angle = Math.atan2( dy, dx );
}

line.prototype.changeTarget = function() {
 var randStart = randInt( 0, 3 );
 switch( randStart ) {
 case 0: // up
 this.target.y = this.y - size;
 break;
 case 1: // right
 this.target.x = this.x + size;
 break;
 case 2: // down
 this.target.y = this.y + size;
 break;
 case 3: // left
 this.target.x = this.x - size;
 }
 this.updateAngle();
};

line.prototype.draw = function( i ) {
 ctx.beginPath();
 var rando = rand( 0, 10 );
 for( var j = 0, length = this.path.length; j < length; j++ ) {
 ctx[ ( j === 0 ) ? 'moveTo' : 'lineTo' ]( this.path[ j ].x +
 rand( -rando, rando ), this.path[ j ].y + rand( -rando, rando ) );
 }
 ctx.strokeStyle = 'hsla(' + rand( this.hue, this.hue + 30 ) +
 ', 80%, 55%, ' + ( this.life / 3 ) + ')';
 ctx.lineWidth = rand( 0.1, 2 );
 ctx.stroke();
};

function rand( min, max ) {
 return Math.random() * ( max - min ) + min;
}

function randInt( min, max ) {
 return Math.floor( min + Math.random() * ( max - min + 1 ) );
};

function init() {
 canvas = document.getElementById( 'canvas' );
 ctx = canvas.getContext( '2d' );
 size = 30;
 lines = [];
 reset();
 loop();
}

function reset() {
 width = Math.ceil( window.innerWidth / 2 ) * 2;
 height = Math.ceil( window.innerHeight / 2 ) * 2;
 tick = 0;
 
 lines.length = 0; 
 canvas.width = width;
 canvas.height = height;
}

function create() {
 if( tick % 10 === 0 ) { 
 lines.push( new line());
 }
}

function step() {
 var i = lines.length;
 while( i-- ) {
 lines[ i ].step( i ); 
 }
}

function clear() {
 ctx.globalCompositeOperation = 'destination-out';
 ctx.fillStyle = 'hsla(0, 0%, 0%, 0.1';
 ctx.fillRect( 0, 0, width, height );
 ctx.globalCompositeOperation = 'lighter';
}

function draw() {
 ctx.save();
 ctx.translate( width / 2, height / 2 );
 ctx.rotate( tick * 0.001 );
 var scale = 0.8 + Math.cos( tick * 0.02 ) * 0.2;
 ctx.scale( scale, scale );
 ctx.translate( -width / 2, -height / 2 );
 var i = lines.length;
 while( i-- ) {
 lines[ i ].draw( i ); 
 }
 ctx.restore();
}

function loop() {
 requestAnimationFrame( loop );
 create();
 step();
 clear();
 draw();
 tick++;
}

function onresize() {
 reset(); 
}

window.addEventListener( 'resize', onresize );

init();
И в завершение - маленькая хитрость. Если на анимации кликнуть правой кнопкой мышки, то текущий кадр можно сохранить как картинку. Таким образом можно сгенерировать коллекцию картинок для создания набора изображений в одном стиле. Получается весьма эффектно. Примеры таких картинок можно увидеть ниже:
img01
img02
img03
img04
img05
img06
 Похожие публикации: Javascript, анимация

Войдите, чтобы добавить Ваш ответ. [ Регистрация | Вход ]