前端开发 之 12个鼠标交互特效下【附完整源码】
文章目录
- 前端开发 之 12个鼠标交互特效下【附完整源码】
- 七:粒子烟花绽放特效
-
- 八:彩球释放特效
-
- 九:雨滴掉落特效
-
- 十:一叶莲滑动特效
-
- 十一:彩球背景滑动交互特效
-
- 十二:雨滴散落交互特效
-
七:粒子烟花绽放特效
1.效果展示
2.HTML
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>烟花绽放特效</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body, html {
height: 100%;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
background-color: #161816;
overflow: hidden;
}
#explosion-container {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
.particle {
position: absolute;
width: 4px;
height: 4px;
background-color: #fff;
border-radius: 50%;
opacity: 1;
pointer-events: none;
}
</style>
</head>
<body>
<div id="explosion-container"></div>
<script>
const container = document.getElementById('explosion-container');
const particleCount = 100;
const maxSpeed = 5;
const colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'];
function random(min, max) {
return Math.random() * (max - min) + min;
}
function getRandomColor() {
const randomIndex = Math.floor(Math.random() * colors.length);
return colors[randomIndex];
}
function createParticle(startX, startY) {
const particle = document.createElement('div');
particle.classList.add('particle');
const halfSize = random(2, 6) / 2;
particle.style.width = `${2 * halfSize}px`;
particle.style.height = `${2 * halfSize}px`;
particle.style.backgroundColor = getRandomColor();
const speedX = random(-maxSpeed, maxSpeed);
const speedY = random(-maxSpeed, maxSpeed);
let x = startX;
let y = startY;
let angle = random(0, 2 * Math.PI);
function update() {
x += speedX;
y += speedY;
angle += 0.1;
particle.style.transform = `translate3d(${x}px, ${y}px, 0) rotate(${angle}rad)`;
if (x < -50 || x > window.innerWidth + 50 || y < -50 || y > window.innerHeight + 50) {
particle.remove();
} else {
requestAnimationFrame(update);
}
}
update();
container.appendChild(particle);
}
function createExplosion(x, y) {
for (let i = 0; i < particleCount; i++) {
createParticle(x, y);
}
}
document.addEventListener('click', (event) => {
createExplosion(event.clientX, event.clientY);
});
</script>
</body>
</html>
八:彩球释放特效
1.效果展示
2.HTML
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>彩球释放特效</title>
<style>
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#particleCanvas {
display: block;
width: 100%;
height: 100%;
background: #000;
}
</style>
</head>
<body>
<canvas id="particleCanvas"></canvas>
</body>
<script>
const canvas = document.getElementById('particleCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const particlesArray = [];
const numberOfParticles = 100;
const mouse = {
x: undefined,
y: undefined,
};
class Particle {
constructor() {
this.x = canvas.width / 2;
this.y = canvas.height / 2;
this.size = Math.random() * 5 + 1;
this.speedX = Math.random() * 3 - 1.5;
this.speedY = Math.random() * 3 - 1.5;
this.color = 'hsl(' + Math.floor(Math.random() * 360) + ', 100%, 50%)';
}
update() {
this.x += this.speedX;
this.y += this.speedY;
if (this.x > canvas.width || this.x < 0) this.speedX *= -1;
if (this.y > canvas.height || this.y < 0) this.speedY *= -1;
this.draw();
}
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
}
function init() {
for (let i = 0; i < numberOfParticles; i++) {
particlesArray.push(new Particle());
}
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let particle of particlesArray) {
particle.update();
}
requestAnimationFrame(animate);
}
window.addEventListener('resize', function() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
window.addEventListener('mousemove', function(event) {
mouse.x = event.x;
mouse.y = event.y;
for (let particle of particlesArray) {
particle.x = mouse.x;
particle.y = mouse.y;
}
});
window.addEventListener('mouseout', function() {
mouse.x = undefined;
mouse.y = undefined;
});
init();
animate();
</script>
</html>
九:雨滴掉落特效
1.效果展示
2.HTML
完整代码
<!DOCTYPE html>
<html>
<head>
<title>雨滴掉落特效</title>
<meta name="Generator" content="EditPlus">
<meta charset="UTF-8">
<style>
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<canvas id="canvas-club"></canvas>
<div class="overlay"></div>
<script>
var c = document.getElementById("canvas-club");
var ctx = c.getContext("2d");
var w = c.width = window.innerWidth;
var h = c.height = window.innerHeight;
var clearColor = 'rgba(0, 0, 0, .1)';
var max = 30;
var drops = [];
var mouseX = 0;
var mouseY = 0;
function random(min, max) {
return Math.random() * (max - min) + min;
}
function O() {}
O.prototype = {
init: function(x, y) {
this.x = x;
this.y = y;
this.color = 'hsl(180, 100%, 50%)';
this.w = 2;
this.h = 1;
this.vy = random(4, 5);
this.vw = 3;
this.vh = 1;
this.size = 2;
this.hit = random(h * .8, h * .9);
this.a = 1;
this.va = 0.96;
},
draw: function() {
if (this.y > this.hit) {
ctx.beginPath();
ctx.moveTo(this.x, this.y - this.h / 2);
ctx.bezierCurveTo(
this.x + this.w / 2, this.y - this.h / 2,
this.x + this.w / 2, this.y + this.h / 2,
this.x, this.y + this.h / 2);
ctx.bezierCurveTo(
this.x - this.w / 2, this.y + this.h / 2,
this.x - this.w / 2, this.y - this.h / 2,
this.x, this.y - this.h / 2);
ctx.strokeStyle = 'hsla(180, 100%, 50%, ' + this.a + ')';
ctx.stroke();
ctx.closePath();
} else {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.size, this.size * 5);
}
this.update();
},
update: function() {
if (this.y < this.hit) {
this.y += this.vy;
} else {
if (this.a > 0.03) {
this.w += this.vw;
this.h += this.vh;
if (this.w > 100) {
this.a *= this.va;
this.vw *= 0.98;
this.vh *= 0.98;
}
} else {
this.a = 0;
}
}
}
}
function resize() {
w = c.width = window.innerWidth;
h = c.height = window.innerHeight;
}
function anim() {
ctx.fillStyle = clearColor;
ctx.fillRect(0, 0, w, h);
for (var i = drops.length - 1; i >= 0; i--) {
drops[i].draw();
if (drops[i].a <= 0.03) {
drops.splice(i, 1);
}
}
requestAnimationFrame(anim);
}
function onMouseMove(e) {
mouseX = e.clientX;
mouseY = e.clientY;
createRainDrop(mouseX, mouseY);
}
function createRainDrop(x, y) {
for (var i = 0; i < drops.length; i++) {
if (drops[i].y === 0) {
drops[i].init(x, y);
return;
}
}
var o = new O();
o.init(x, y);
drops.push(o);
if (drops.length > max) {
drops.shift();
}
}
window.addEventListener("resize", resize);
window.addEventListener("mousemove", onMouseMove);
anim();
</script>
</body>
</html>
十:一叶莲滑动特效
1.效果展示
2.HTML
完整代码
<!DOCTYPE HTML>
<html>
<head>
<title>一叶莲滑动特效</title>
<meta charset="UTF-8">
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
cursor: none;
}
.container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-image: linear-gradient(to right, rgba(154, 89, 168, 0.67), rgba(255, 30, 0, 0.67), rgba(0, 255, 153, 0.67));
}
.cursor {
position: absolute;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.8);
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
transition: transform 0.1s, opacity 0.1s;
}
</style>
<script src="jquery-3.7.1.min.js"></script>
</head>
<body>
<div id="jsi-cherry-container" class="container"></div>
<div id="cursor" class="cursor"></div>
<script>
var RENDERER = {
cherries: [],
mouse: { x: 0, y: 0 },
init: function () {
this.setParameters();
this.bindEvents();
this.animate();
},
setParameters: function () {
this.$container = $('#jsi-cherry-container');
this.width = this.$container.width();
this.height = this.$container.height();
this.context = $('<canvas />').attr({ width: this.width, height: this.height }).appendTo(this.$container).get(0).getContext('2d');
this.$cursor = $('#cursor');
},
bindEvents: function () {
$(document).on('mousemove', (e) => {
this.mouse.x = e.pageX;
this.mouse.y = e.pageY;
});
$(document).on('mouseout', () => {
this.mouse.x = -100;
this.mouse.y = -100;
});
window.addEventListener('resize', () => {
this.width = this.$container.width();
this.height = this.$container.height();
this.context.canvas.width = this.width;
this.context.canvas.height = this.height;
});
},
createCherry: function (x, y) {
var cherry = new CHERRY_BLOSSOM(this, x, y);
this.cherries.push(cherry);
},
animate: function () {
requestAnimationFrame(this.animate.bind(this));
this.context.clearRect(0, 0, this.width, this.height);
this.cherries.forEach((cherry, index) => {
cherry.update();
cherry.render(this.context);
if (cherry.opacity <= 0) {
this.cherries.splice(index, 1);
}
});
this.$cursor.css({
left: this.mouse.x,
top: this.mouse.y,
opacity: this.cherries.length > 0 ? 0 : 1
});
}
};
var CHERRY_BLOSSOM = function (renderer, x, y) {
this.renderer = renderer;
this.x = x;
this.y = y;
this.size = Math.random() * 10 + 10;
this.angle = Math.random() * Math.PI * 2;
this.speed = Math.random() * 0.5 + 0.5;
this.opacity = 1;
this.life = 100 + Math.random() * 100;
};
CHERRY_BLOSSOM.prototype = {
update: function () {
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed;
this.opacity -= 0.02;
this.size *= 0.98;
this.life--;
},
render: function (context) {
context.save();
context.globalAlpha = this.opacity;
context.fillStyle = 'hsl(330, 70%, 50%)';
context.translate(this.x, this.y);
context.scale(this.size / 20, this.size / 20);
context.beginPath();
context.moveTo(0, 40);
context.bezierCurveTo(-60, 20, -10, -60, 0, -20);
context.bezierCurveTo(10, -60, 60, 20, 0, 40);
context.fill();
context.restore();
}
};
$(function () {
RENDERER.init();
setInterval(() => {
RENDERER.createCherry(RENDERER.mouse.x, RENDERER.mouse.y);
}, 50);
});
</script>
</body>
</html>
十一:彩球背景滑动交互特效
1.效果展示
2.HTML
完整代码
<!DOCTYPE HTML>
<html>
<head>
<title>彩球背景滑动交互特效</title>
<meta charset="UTF-8">
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
cursor: none;
}
.container {
width: 100%;
height: 100%;
background-image: linear-gradient(to right, rgba(154, 89, 168, 0.67), rgba(255, 30, 0, 0.67), rgba(0, 255, 153, 0.67));
}
.cursor {
position: absolute;
width: 20px;
height: 20px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.7);
box-shadow: 0 0 10px rgba(255, 255, 255, 0.9);
pointer-events: none;
z-index: 1000;
}
</style>
<script type="text/javascript" src="jquery-3.7.1.min.js"></script>
</head>
<body>
<div id="jsi-cherry-container" class="container"></div>
<div id="cursor" class="cursor"></div>
<script>
var RENDERER = {
INIT_CHERRY_BLOSSOM_COUNT: 50,
MAX_ADDING_INTERVAL: 10,
cherries: [],
mouse: { x: 0, y: 0 },
init: function () {
this.setParameters();
this.reconstructMethods();
this.createCherries();
this.bindEvents();
this.render();
},
setParameters: function () {
this.$container = $('#jsi-cherry-container');
this.width = this.$container.width();
this.height = this.$container.height();
this.context = $('<canvas />').attr({ width: this.width, height: this.height }).appendTo(this.$container).get(0).getContext('2d');
this.maxAddingInterval = Math.round(this.MAX_ADDING_INTERVAL * 1000 / this.width);
this.addingInterval = this.maxAddingInterval;
},
reconstructMethods: function () {
this.render = this.render.bind(this);
this.onMouseMove = this.onMouseMove.bind(this);
},
bindEvents: function () {
$(window).on('mousemove', this.onMouseMove);
},
createCherries: function () {
for (var i = 0, length = Math.round(this.INIT_CHERRY_BLOSSOM_COUNT * this.width / 1000); i < length; i++) {
this.cherries.push(new CHERRY_BLOSSOM(this));
}
},
onMouseMove: function (e) {
this.mouse.x = e.pageX;
this.mouse.y = e.pageY;
},
render: function () {
requestAnimationFrame(this.render);
this.context.clearRect(0, 0, this.width, this.height);
$('#cursor').css({ left: this.mouse.x - 10 + 'px', top: this.mouse.y - 10 + 'px' });
this.cherries.sort(function (cherry1, cherry2) {
return cherry1.z - cherry2.z;
});
for (var i = this.cherries.length - 1; i >= 0; i--) {
if (!this.cherries[i].render(this.context, this.mouse)) {
this.cherries.splice(i, 1);
}
}
if (--this.addingInterval == 0) {
this.addingInterval = this.maxAddingInterval;
this.cherries.push(new CHERRY_BLOSSOM(this));
}
}
};
var CHERRY_BLOSSOM = function (renderer) {
this.renderer = renderer;
this.init();
};
CHERRY_BLOSSOM.prototype = {
FOCUS_POSITION: 300,
FAR_LIMIT: 600,
init: function () {
this.x = this.getRandomValue(-this.renderer.width, this.renderer.width);
this.y = this.getRandomValue(0, this.renderer.height);
this.z = this.getRandomValue(0, this.FAR_LIMIT);
this.vx = this.getRandomValue(-1, 1);
this.vy = this.getRandomValue(-1, 1);
this.theta = this.getRandomValue(0, Math.PI * 2);
this.phi = this.getRandomValue(0, Math.PI * 2);
this.size = this.getRandomValue(2, 5);
this.color = 'hsl(' + Math.floor(Math.random() * 360) + ', 100%, 50%)';
},
getRandomValue: function (min, max) {
return min + (max - min) * Math.random();
},
getAxis: function (mouse) {
var rate = this.FOCUS_POSITION / (this.z + this.FOCUS_POSITION),
x = this.renderer.width / 2 + (this.x - mouse.x) * rate,
y = this.renderer.height / 2 - (this.y - mouse.y) * rate;
return { rate: rate, x: x, y: y };
},
render: function (context, mouse) {
var axis = this.getAxis(mouse);
context.save();
context.fillStyle = this.color;
context.translate(axis.x, axis.y);
context.rotate(this.theta);
context.scale(axis.rate * this.size, axis.rate * this.size);
context.beginPath();
context.moveTo(0, 0);
context.arc(0, 0, 10, 0, Math.PI * 2, false);
context.fill();
context.restore();
this.x += this.vx;
this.y += this.vy;
this.theta += 0.01;
return this.z > -this.FOCUS_POSITION && this.z < this.FAR_LIMIT && this.x < this.renderer.width * 1.5 && this.x > -this.renderer.width * 0.5;
}
};
$(function () {
RENDERER.init();
});
</script>
</body>
</html>
十二:雨滴散落交互特效
1.效果展示
2.HTML
完整代码
<!DOCTYPE html>
<html>
<head>
<title>雨滴散落特效</title>
<meta name="Generator" content="EditPlus">
<meta charset="UTF-8">
<style>
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<canvas id="canvas-club"></canvas>
<div class="overlay"></div>
<script>
var c = document.getElementById("canvas-club");
var ctx = c.getContext("2d");
var w = c.width = window.innerWidth;
var h = c.height = window.innerHeight;
var clearColor = 'rgba(0, 0, 0, .1)';
var max = 30;
var drops = [];
var mouseX = 0;
var mouseY = 0;
function random(min, max) {
return Math.random() * (max - min) + min;
}
function O() {}
O.prototype = {
init: function(x, y) {
this.x = x;
this.y = y;
this.color = 'hsl(180, 100%, 50%)';
this.w = 2;
this.h = 1;
this.vy = random(4, 5);
this.vw = 3;
this.vh = 1;
this.size = 2;
this.hit = random(h * .8, h * .9);
this.a = 1;
this.va = .96;
},
draw: function() {
if (this.y > this.hit) {
ctx.beginPath();
ctx.moveTo(this.x, this.y - this.h / 2);
ctx.bezierCurveTo(
this.x + this.w / 2, this.y - this.h / 2,
this.x + this.w / 2, this.y + this.h / 2,
this.x, this.y + this.h / 2);
ctx.bezierCurveTo(
this.x - this.w / 2, this.y + this.h / 2,
this.x - this.w / 2, this.y - this.h / 2,
this.x, this.y - this.h / 2);
ctx.strokeStyle = 'hsla(180, 100%, 50%, ' + this.a + ')';
ctx.stroke();
ctx.closePath();
} else {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.size, this.size * 5);
}
this.update();
},
update: function() {
if (this.y < this.hit) {
this.y += this.vy;
} else {
if (this.a > .03) {
this.w += this.vw;
this.h += this.vh;
if (this.w > 100) {
this.a *= this.va;
this.vw *= .98;
this.vh *= .98;
}
} else {
this.init(random(0, w), 0);
}
}
}
}
function resize() {
w = c.width = window.innerWidth;
h = c.height = window.innerHeight;
}
function anim() {
ctx.fillStyle = clearColor;
ctx.fillRect(0, 0, w, h);
for (var i in drops) {
drops[i].draw();
}
requestAnimationFrame(anim);
}
function onMouseMove(e) {
mouseX = e.clientX;
mouseY = e.clientY;
createRainDrop(mouseX, mouseY);
}
function createRainDrop(x, y) {
for (var i = 0; i < drops.length; i++) {
if (drops[i].y === 0) {
drops[i].init(x, y);
return;
}
}
var o = new O();
o.init(x, y);
drops.push(o);
if (drops.length > max) {
drops.shift();
}
}
window.addEventListener("resize", resize);
window.addEventListener("mousemove", onMouseMove);
anim();
</script>
</body>
</html>