Skip to content

Commit

Permalink
Merge pull request #2395 from Vixcity/wx
Browse files Browse the repository at this point in the history
把nest提炼出来,放到public上面,优化体积,优化鼠标移动粒子特效的代码
  • Loading branch information
tangly1024 authored May 10, 2024
2 parents 8a7c6b5 + 9530b66 commit eeef65a
Show file tree
Hide file tree
Showing 5 changed files with 340 additions and 327 deletions.
215 changes: 10 additions & 205 deletions components/Fireworks.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ const Fireworks = () => {
'https://cdn.bootcdn.net/ajax/libs/animejs/3.2.1/anime.min.js',
'js'
).then(() => {
if (window.anime) {
createFireworks({
config: { colors: fireworksColor },
anime: window.anime
})
}
loadExternalResource('/js/fireworks.js', 'js').then(() => {
if (window.anime && window.createFireworks) {
window.createFireworks({
config: { colors: fireworksColor },
anime: window.anime
})
}
})
})
}

Expand All @@ -37,204 +39,7 @@ const Fireworks = () => {
}
}, [])

return <canvas id='fireworks' className='fireworks'></canvas>
return <></>
}
export default Fireworks

/**
* 创建烟花
* @param config
*/
function createFireworks({ config, anime }) {
const defaultConfig = {
colors: config?.colors,
numberOfParticules: 20,
orbitRadius: {
min: 50,
max: 100
},
circleRadius: {
min: 10,
max: 20
},
diffuseRadius: {
min: 50,
max: 100
},
animeDuration: {
min: 900,
max: 1500
}
}
config = Object.assign(defaultConfig, config)

let pointerX = 0
let pointerY = 0

// sky blue
const colors = config.colors

const canvasEl = document.querySelector('.fireworks')
const ctx = canvasEl.getContext('2d')

/**
* 设置画布尺寸
*/
function setCanvasSize(canvasEl) {
canvasEl.width = window.innerWidth
canvasEl.height = window.innerHeight
canvasEl.style.width = `${window.innerWidth}px`
canvasEl.style.height = `${window.innerHeight}px`
}

/**
* update pointer
* @param {TouchEvent} e
*/
function updateCoords(e) {
pointerX =
e.clientX ||
(e.touches[0] ? e.touches[0].clientX : e.changedTouches[0].clientX)
pointerY =
e.clientY ||
(e.touches[0] ? e.touches[0].clientY : e.changedTouches[0].clientY)
}

function setParticuleDirection(p) {
const angle = (anime.random(0, 360) * Math.PI) / 180
const value = anime.random(
config.diffuseRadius.min,
config.diffuseRadius.max
)
const radius = [-1, 1][anime.random(0, 1)] * value
return {
x: p.x + radius * Math.cos(angle),
y: p.y + radius * Math.sin(angle)
}
}

/**
* 在指定位置创建粒子
* @param {number} x
* @param {number} y
* @returns
*/
function createParticule(x, y) {
const p = {
x,
y,
color: `rgba(${colors[anime.random(0, colors.length - 1)]},${anime.random(
0.2,
0.8
)})`,
radius: anime.random(config.circleRadius.min, config.circleRadius.max),
endPos: null,
draw() {}
}
p.endPos = setParticuleDirection(p)
p.draw = function () {
ctx.beginPath()
ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, true)
ctx.fillStyle = p.color
ctx.fill()
}
return p
}

function createCircle(x, y) {
const p = {
x,
y,
color: '#000',
radius: 0.1,
alpha: 0.5,
lineWidth: 6,
draw() {}
}
p.draw = function () {
ctx.globalAlpha = p.alpha
ctx.beginPath()
ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, true)
ctx.lineWidth = p.lineWidth
ctx.strokeStyle = p.color
ctx.stroke()
ctx.globalAlpha = 1
}
return p
}

function renderParticule(anim) {
for (let i = 0; i < anim.animatables.length; i++) {
anim.animatables[i].target.draw()
}
}

function animateParticules(x, y) {
const circle = createCircle(x, y)
const particules = []
for (let i = 0; i < config.numberOfParticules; i++) {
particules.push(createParticule(x, y))
}

anime
.timeline()
.add({
targets: particules,
x(p) {
return p.endPos.x
},
y(p) {
return p.endPos.y
},
radius: 0.1,
duration: anime.random(
config.animeDuration.min,
config.animeDuration.max
),
easing: 'easeOutExpo',
update: renderParticule
})
.add(
{
targets: circle,
radius: anime.random(config.orbitRadius.min, config.orbitRadius.max),
lineWidth: 0,
alpha: {
value: 0,
easing: 'linear',
duration: anime.random(600, 800)
},
duration: anime.random(1200, 1800),
easing: 'easeOutExpo',
update: renderParticule
},
0
)
}

const render = anime({
duration: Infinity,
update: () => {
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height)
}
})

document.addEventListener(
'mousedown',
e => {
render.play()
updateCoords(e)
animateParticules(pointerX, pointerY)
},
false
)

setCanvasSize(canvasEl)
window.addEventListener(
'resize',
() => {
setCanvasSize(canvasEl)
},
false
)
}
export default Fireworks
7 changes: 1 addition & 6 deletions components/MouseFollow.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@ const MOUSE_FOLLOW = () => {

useEffect(() => {
loadExternalResource('/js/mouse-follow.js', 'js').then(url => {
if (window.createMouseCanvas) {
window.createMouseCanvas()({
type,
color
})
}
window.createMouseCanvas && window.createMouseCanvas()({ type, color })
})
}, [])

Expand Down
122 changes: 6 additions & 116 deletions components/Nest.js
Original file line number Diff line number Diff line change
@@ -1,124 +1,14 @@
/* eslint-disable */
import { useEffect } from 'react'
const id = 'canvasNestCreated'
const Nest = () => {
const destroyNest = ()=>{
const nest = document.getElementById(id)
if(nest && nest.parentNode){
nest.parentNode.removeChild(nest)
}
}
import { loadExternalResource } from '@/lib/utils'

const Nest = () => {
useEffect(() => {
createNest()
return () => destroyNest()
loadExternalResource('/js/nest.js', 'js').then(url => {
window.createNest && window.createNest()
})
return () => window.destroyNest && window.destroyNest()
}, [])
return <></>
}

export default Nest

/**
* 创建连接点
* @param config
*/
function createNest() {
const e = document.getElementById('__next')
if(!e) return
function n(e, n, t) {
return e.getAttribute(n) || t
}
function t() {
;(u = i.width =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth),
(d = i.height =
window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight)
}
function o() {
c.clearRect(0, 0, u, d)
const e = [s].concat(x)
let n, t, i, l, r, w
x.forEach(function (o) {
for (
o.x += o.xa,
o.y += o.ya,
o.xa *= o.x > u || o.x < 0 ? -1 : 1,
o.ya *= o.y > d || o.y < 0 ? -1 : 1,
c.fillRect(o.x - 0.5, o.y - 0.5, 1, 1),
t = 0;
t < e.length;
t++
)
(n = e[t]),
o !== n &&
null !== n.x &&
null !== n.y &&
((l = o.x - n.x),
(r = o.y - n.y),
(w = l * l + r * r),
w < n.max &&
(n === s &&
w >= n.max / 2 &&
((o.x -= 0.03 * l), (o.y -= 0.03 * r)),
(i = (n.max - w) / n.max),
c.beginPath(),
(c.lineWidth = i / 2),
(c.strokeStyle = 'rgba(' + a.c + ',' + (i + 0.2) + ')'),
c.moveTo(o.x, o.y),
c.lineTo(n.x, n.y),
c.stroke()))
e.splice(e.indexOf(o), 1)
}),
m(o)
}
var i = document.createElement('canvas')
i.id = id
var a = (function () {
const t = e
return {
z: n(t, 'zIndex', 0),
o: n(t, 'opacity', 0.7),
c: n(t, 'color', '0,0,0'),
n: n(t, 'count', 99)
}
})(),
c = i.getContext('2d')
let u, d
var m =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (e) {
window.setTimeout(e, 1e3 / 45)
}
const l = Math.random
var r,
s = { x: null, y: null, max: 2e4 }
;(i.style.cssText =
'position:fixed;top:0;left:0;pointer-events:none;z-index:' + a.z + ';opacity:' + a.o),
(r = 'body'), e.appendChild(i),
t(),
(window.onresize = t),
(window.onmousemove = function (e) {
;(e = e || window.event), (s.x = e.clientX), (s.y = e.clientY)
}),
(window.onmouseout = function () {
;(s.x = null), (s.y = null)
})
for (var x = [], w = 0; a.n > w; w++) {
const e = l() * u,
n = l() * d,
t = 2 * l() - 1,
o = 2 * l() - 1
x.push({ x: e, y: n, xa: t, ya: o, max: 6e3 })
}
setTimeout(function () {
o()
}, 100)
}
Loading

0 comments on commit eeef65a

Please sign in to comment.