Hiệu ứng theo chuột với JavaScript rất ấn tượng

Hiệu ứng theo chuột được sử dụng rất nhiều trong thiết kế Banner trên website. Thông thường bạn sẽ thấy nhiều người sử dụng hiệu ứng công nghệ để trang trí cho website của mình bắt mắt hơn.

Trong bài viết này, Lại Văn Đức Blog giới thiệu đến bạn hiệu ứng Hạt sử dụng JavaScript. Bạn có thể sử dụng hiệu ứng này cho bất kỳ dự án nào của bạn một cách đơn giản và hiệu quả.

Hiệu ứng theo chuột với JavaScript

Trước khi đi đến các đoạn code triển khai hiệu ứng, mời các bạn cùng theo dõi cách bộ code này hoạt động. Với hiệu ứng theo chuột này các bạn sẽ cảm nhận được rõ ràng sự chuyển động khi bạn thao tác với con chuột máy tính. Cụ thể, chúng ta sẽ có hai hiệu ứng: Khi bạn Click thì màu sắc sẽ được thay đổi, khi bạn di chuyển con chuột thì các phần tử trong đó sẽ theo con chuột tới cùng trời cuối đất.

Code hiệu ứng theo chuột

Tiếp theo là những đoạn code sử dụng cho hiệu ứng này. Đầu tiên, chúng ta sẽ cần đoạn HTML sau.

<canvas id="canvas"></canvas>
<p>
	<strong>Thay đổi tỷ trọng:</strong> Di chuyển chuột<br>
	<strong>Thay đổi màu sắc:</strong> Click chuột
</p>

Bên trên chúng ta chỉ cần thẻ canvas thôi. Các đoạn trong thẻ P là được sử dụng để ghi chú. Và tiếp theo chúng ta sẽ cần đến đoạn Code CSS này:

body {
	overflow: hidden;	
}

canvas {
	left: 0;
	position: absolute;
	top: 0;
}

p {
	background: rgba(0, 0, 0, 0.5);
	color: #fff;
	left: 0;
	font-family: sans-serif;
	font-size: 14px;
	line-height: 1.5;
	margin: 0;
	padding: 20px 30px;
	position: absolute;
	top: 0;
}

Linh hồn cho hiệu ứng theo chuột này nằm ở đoạn JavaScript dưới đây:

var canvas,
	ctx,
	width,
	height,
	xGravity,
	yGravity,
	friction,
	dots,
	palettes,
	paletteCount,
	paletteCurrent,
	colorCount,
	tick,
	mx,
	my,
	PI,
	TWOPI;

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

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

function Dot() {
	this.x = width / 2;
	this.y = height / 2;
	this.vx = rand( -2, 2 );
	this.vy = rand( -2, 2 );
	this.radius = rand( 5, 15 );
	this.color = randInt( 1, colorCount - 1 );
}

Dot.prototype.step = function( i ) {
	// apply forces	
	this.x += this.vx;
	this.y += this.vy;
		
	// handle bounce	
	if( this.vx > 0 && this.x + this.radius >= width ) {
		this.vx *= -0.6;
	}
	
	if( this.vx < 0 && this.x - this.radius <= 0 ) {
		this.vx *= -0.6;
	}
	
	if( this.vy > 0 && this.y + this.radius >= height ) {
		this.vy *= -0.6;
	}
	
	if( this.vy < 0 && this.y - this.radius <= 0 ) {
		this.vy *= -0.6;
	}
	
	// handle bounds and friction	
	if( this.x + this.radius > width ) {
		this.x = width - this.radius;
		this.vy *= friction;
	}
	
	if( this.x - this.radius < 0 ) {
		this.x = this.radius;
		this.vy *= friction;
	}
	
	if( this.y + this.radius > height ) {
		this.y = height - this.radius;
		this.vx *= friction;
	}
	
	if( this.y - this.radius < 0 ) {
		this.y = this.radius;
		this.vx *= friction;
	}
	
	// handle gravity	
	this.vx += xGravity;
	this.vy += yGravity;
};

Dot.prototype.collide = function( otherDot ) {
	// still working on understanding this
	// lots of help from https://lamberta.github.io/html5-animation/
	var dx = otherDot.x - this.x,
		dy = otherDot.y - this.y,
		dist = Math.sqrt( dx * dx + dy * dy ),
		minDist = this.radius + otherDot.radius;
	if( dist < minDist ) {
		var tx = this.x + dx / dist * minDist,
			ty = this.y + dy / dist * minDist,
			ax = ( tx - otherDot.x ) * 0.6,
			ay = ( ty - otherDot.y ) * 0.6;
		this.vx -= ax;
		this.vy -= ay;      
		otherDot.vx += ax;
		otherDot.vy += ay;
		this.vx *= friction * 0.9;
		this.vy *= friction * 0.9;
		otherDot.vx *= friction * 0.9;
		otherDot.vy *= friction * 0.9;
	}
};

Dot.prototype.draw = function() {
	ctx.beginPath();
	ctx.arc( this.x, this.y, this.radius, 0, TWOPI );
	ctx.fillStyle = palettes[ paletteCurrent ][ this.color ];
	ctx.fill();
};

function init() {
	canvas = document.getElementById( 'canvas' );
	ctx = canvas.getContext( '2d' );
	xGravity = 0;
	yGravity = 1;
	friction = 0.99;
	dots = [];
	// palette credits:
	// https://color.adobe.com/Friends-and-foes-color-theme-1175537/
	// https://color.adobe.com/Ocean-Sunset-color-theme-46355/
	// https://color.adobe.com/Gettysburg-color-theme-209416/
	// https://color.adobe.com/vintage-card-color-theme-3165833/
	palettes = [
		[
			'#2e2932',
			'#01a2a6',
			'#37d8c2',
			'#bdf271',
			'#ffffa6'
		],
		[
			'#405952',
			'#9c9b7a',
			'#ffd393',
			'#ff974f',
			'#f35033'
		],
		[
			'#962d3e',
			'#343641',
			'#979c9c',
			'#f2ebc9',
			'#388898'
		],
		[
			'#f2ebbf',
			'#5c4b51',
			'#8dbeb2',
			'#f2b468',
			'#ee6163'
		]
	];
	paletteCount = palettes.length;
	paletteCurrent = 3;	
	colorCount = palettes[ 0 ].length;
	PI = Math.PI;
	TWOPI = PI * 2;
	
	reset();
	loop();
}

function reset() {
	width = window.innerWidth;
	height = window.innerHeight;
	dots.length = 0;
	tick = 0;
	mx = width / 2;
	my = height / 2;
	
	canvas.width = width;
	canvas.height = height;
}

function create() {
	if( tick && dots.length < 500 ) {
		dots.push( new Dot() );	
	}
}

function step() {
	var i = dots.length;
	while( i-- ) {
		dots[ i ].step( i );	
	}
	
	i = dots.length;
	while( i-- ) {
		dot = dots[ i ];
		var j = i;
		if( j > 0 ) {
			while( j-- ) {
				dot.collide( dots[ j ] );
			}
		}
	}
}

function draw() {
	ctx.fillStyle = palettes[ paletteCurrent ][ 0 ];
	ctx.fillRect( 0, 0, width, height );
	
	var i = dots.length;
	while( i-- ) {
		dots[ i ].draw();	
	}
}

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

function onmousemove( e ) {
	mx = e.pageX;
	my = e.pageY;
	
	xGravity = ( mx - width / 2 ) / ( width / 2 );
	yGravity = ( my - height / 2 ) / ( height / 2 );
}

function onmousedown() {
	var i = dots.length;
	while( i-- ) {
		dots[ i ].vx += rand( -10, 10 );
		dots[ i ].vy += rand( -10, 10 );
	}

	if( paletteCurrent < paletteCount - 1 ) {
		paletteCurrent++;	
	} else {
		paletteCurrent = 0;	
	}
}

window.addEventListener( 'resize', reset );
window.addEventListener( 'mousemove', onmousemove );
window.addEventListener( 'mousedown', onmousedown );

init();

Thế Thôi

Trong bộ code bên trên, HTML và CSS để tạo thành khung hiển thị cho hiệu ứng. Còn lại toàn bộ hiệu ứng được thực hiện bởi JavaScript. Bạn có thể tuỳ chỉnh bộ code theo nhu cầu và sử dụng cho các dự án khi cần thiết.

Hiệu ứng theo chuột sử dụng JavaScript có rất nhiều. Trong tương lai, Blog Lại Văn Đức sẽ chia sẻ thêm các hiệu ứng khác nhau để bạn tham khảo. Chúc các bạn luôn vui vẻ và thành công.

1 1 đánh giá
Đánh giá bài viết
Theo dõi
Thông báo của
guest

0 Bình luận
Phản hồi nội tuyến
Xem tất cả bình luận