前端开发 之 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>