diff --git a/components/Fireworks.js b/components/Fireworks.js index c3d48429..cb6a2d98 100644 --- a/components/Fireworks.js +++ b/components/Fireworks.js @@ -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 + }) + } + }) }) } @@ -37,204 +39,7 @@ const Fireworks = () => { } }, []) - return + 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 - ) -} diff --git a/components/MouseFollow.js b/components/MouseFollow.js index 28bacc3d..2215a0ce 100644 --- a/components/MouseFollow.js +++ b/components/MouseFollow.js @@ -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 }) }) }, []) diff --git a/components/Nest.js b/components/Nest.js index 47453ad2..8fc956b6 100644 --- a/components/Nest.js +++ b/components/Nest.js @@ -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) -} diff --git a/public/js/fireworks.js b/public/js/fireworks.js new file mode 100644 index 00000000..937f9bf3 --- /dev/null +++ b/public/js/fireworks.js @@ -0,0 +1,205 @@ +/** + * 创建烟花 + * @param config + */ +function createFireworks({ config, anime }) { + // 创建这个Canvas元素 给我代码 + const canvasElement = document.createElement('canvas') + canvasElement.id = 'fireworks' + canvasElement.className = 'fireworks' + document.body.appendChild(canvasElement) + + 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 + ) +} + +window.createFireworks = createFireworks diff --git a/public/js/nest.js b/public/js/nest.js new file mode 100644 index 00000000..72a861d3 --- /dev/null +++ b/public/js/nest.js @@ -0,0 +1,118 @@ +/* eslint-disable */ + +/** + * 创建连接点 + * @param config + */ + +const id = '__next' +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) +} + +function destroyNest() { + const nest = document.getElementById(id) + if(nest && nest.parentNode){ + nest.parentNode.removeChild(nest) + } +} + +window.createNest = createNest +window.destroyNest = destroyNest \ No newline at end of file