Skip to content

Commit

Permalink
动态彩带特效
Browse files Browse the repository at this point in the history
  • Loading branch information
Vixcity committed Jan 30, 2023
1 parent f1f9f28 commit ee19780
Show file tree
Hide file tree
Showing 3 changed files with 313 additions and 1 deletion.
5 changes: 4 additions & 1 deletion blog.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ const BLOG = {
SAKURA: process.env.NEXT_PUBLIC_SAKURA || false, // 开关

// 漂浮线段特效
NEST: process.env.NEXT_PUBLIC_NEST || true, // 开关
NEST: process.env.NEXT_PUBLIC_NEST || false, // 开关

// 动态彩带特效
FLUTTERINGRIBBON: process.env.NEXT_PUBLIC_NEST || true, // 开关

// 星空雨特效 黑夜模式才会生效
STARRY_SKY: process.env.NEXT_PUBLIC_STARRY_SKY || false, // 开关
Expand Down
307 changes: 307 additions & 0 deletions components/FlutteringRibbon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
/* eslint-disable */
import React from 'react'

export const FlutteringRibbon = () => {
React.useEffect(() => {
createFlutteringRibbon()
}, [])
}

/**
* 创建连接点
* @param config
*/
function createFlutteringRibbon() {
'object' == typeof window &&
(window.Ribbons = (function () {
const t = window,
i = document.body,
n = document.documentElement
var o = function () {
if (1 === arguments.length) {
if (Array.isArray(arguments[0])) {
const t = Math.round(o(0, arguments[0].length - 1))
return arguments[0][t]
}
return o(0, arguments[0])
}
return 2 === arguments.length
? Math.random() * (arguments[1] - arguments[0]) + arguments[0]
: 0
}
const s = function (o) {
const s = Math.max(
0,
t.innerWidth || n.clientWidth || i.clientWidth || 0
),
e = Math.max(
0,
t.innerHeight || n.clientHeight || i.clientHeight || 0
)
return {
width: s,
height: e,
ratio: s / e,
centerx: s / 2,
centery: e / 2,
scrollx:
Math.max(0, t.pageXOffset || n.scrollLeft || i.scrollLeft || 0) -
(n.clientLeft || 0),
scrolly:
Math.max(0, t.pageYOffset || n.scrollTop || i.scrollTop || 0) -
(n.clientTop || 0)
}
},
e = function (t, i) {
;(this.x = 0), (this.y = 0), this.set(t, i)
}
e.prototype = {
constructor: e,
set: function (t, i) {
;(this.x = t || 0), (this.y = i || 0)
},
copy: function (t) {
return (this.x = t.x || 0), (this.y = t.y || 0), this
},
multiply: function (t, i) {
return (this.x *= t || 1), (this.y *= i || 1), this
},
divide: function (t, i) {
return (this.x /= t || 1), (this.y /= i || 1), this
},
add: function (t, i) {
return (this.x += t || 0), (this.y += i || 0), this
},
subtract: function (t, i) {
return (this.x -= t || 0), (this.y -= i || 0), this
},
clampX: function (t, i) {
return (this.x = Math.max(t, Math.min(this.x, i))), this
},
clampY: function (t, i) {
return (this.y = Math.max(t, Math.min(this.y, i))), this
},
flipX: function () {
return (this.x *= -1), this
},
flipY: function () {
return (this.y *= -1), this
}
}
const h = function (t) {
;(this._canvas = null),
(this._context = null),
(this._sto = null),
(this._width = 0),
(this._height = 0),
(this._scroll = 0),
(this._ribbons = []),
(this._options = {
colorSaturation: '80%',
colorBrightness: '60%',
colorAlpha: 0.65,
colorCycleSpeed: 6,
verticalPosition: 'center',
horizontalSpeed: 150,
ribbonCount: 5,
strokeSize: 5,
parallaxAmount: -0.5,
animateSections: !0
}),
(this._onDraw = this._onDraw.bind(this)),
(this._onResize = this._onResize.bind(this)),
(this._onScroll = this._onScroll.bind(this)),
this.setOptions(t),
this.init()
}
return (
(h.prototype = {
constructor: h,
setOptions: function (t) {
if ('object' == typeof t)
for (const i in t)
t.hasOwnProperty(i) && (this._options[i] = t[i])
},
init: function () {
try {
;(this._canvas = document.createElement('canvas')),
(this._canvas.style.display = 'block'),
(this._canvas.style.position = 'fixed'),
(this._canvas.style.margin = '0'),
(this._canvas.style.padding = '0'),
(this._canvas.style.border = '0'),
(this._canvas.style.outline = '0'),
(this._canvas.style.left = '0'),
(this._canvas.style.top = '0'),
(this._canvas.style.width = '100%'),
(this._canvas.style.height = '100%'),
(this._canvas.style['z-index'] = '0'),
this._onResize(),
(this._context = this._canvas.getContext('2d')),
this._context.clearRect(0, 0, this._width, this._height),
(this._context.globalAlpha = this._options.colorAlpha),
window.addEventListener('resize', this._onResize),
window.addEventListener('scroll', this._onScroll),
document.body.appendChild(this._canvas)
} catch (t) {
return void console.warn('Canvas Context Error: ' + t.toString())
}
this._onDraw()
},
addRibbon: function () {
const t = Math.round(o(1, 9)) > 5 ? 'right' : 'left'
let i = 1e3
const n = 200,
s = 0 - n,
h = this._width + n
let a = 0,
r = 0
const l = 'right' === t ? s : h
let c = Math.round(o(0, this._height))
;/^(top|min)$/i.test(this._options.verticalPosition)
? (c = 0 + n)
: /^(middle|center)$/i.test(this._options.verticalPosition)
? (c = this._height / 2)
: /^(bottom|max)$/i.test(this._options.verticalPosition) &&
(c = this._height - n)
const p = [],
_ = new e(l, c),
d = new e(l, c)
let u = null,
b = Math.round(o(0, 360)),
f = 0
for (; !(i <= 0); ) {
if (
(i--,
(a = Math.round(
(1 * Math.random() - 0.2) * this._options.horizontalSpeed
)),
(r = Math.round(
(1 * Math.random() - 0.5) * (0.25 * this._height)
)),
(u = new e()),
u.copy(d),
'right' === t)
) {
if ((u.add(a, r), d.x >= h)) break
} else if ('left' === t && (u.subtract(a, r), d.x <= s)) break
p.push({
point1: new e(_.x, _.y),
point2: new e(d.x, d.y),
point3: u,
color: b,
delay: f,
dir: t,
alpha: 0,
phase: 0
}),
_.copy(d),
d.copy(u),
(f += 4),
(b += this._options.colorCycleSpeed)
}
this._ribbons.push(p)
},
_drawRibbonSection: function (t) {
if (t) {
if (t.phase >= 1 && t.alpha <= 0) return !0
if (t.delay <= 0) {
if (
((t.phase += 0.02),
(t.alpha = 1 * Math.sin(t.phase)),
(t.alpha = t.alpha <= 0 ? 0 : t.alpha),
(t.alpha = t.alpha >= 1 ? 1 : t.alpha),
this._options.animateSections)
) {
const i = 0.1 * Math.sin(1 + (t.phase * Math.PI) / 2)
'right' === t.dir
? (t.point1.add(i, 0),
t.point2.add(i, 0),
t.point3.add(i, 0))
: (t.point1.subtract(i, 0),
t.point2.subtract(i, 0),
t.point3.subtract(i, 0)),
t.point1.add(0, i),
t.point2.add(0, i),
t.point3.add(0, i)
}
} else t.delay -= 0.5
const i = this._options.colorSaturation,
n = this._options.colorBrightness,
o =
'hsla(' +
t.color +
', ' +
i +
', ' +
n +
', ' +
t.alpha +
' )'
this._context.save(),
0 !== this._options.parallaxAmount &&
this._context.translate(
0,
this._scroll * this._options.parallaxAmount
),
this._context.beginPath(),
this._context.moveTo(t.point1.x, t.point1.y),
this._context.lineTo(t.point2.x, t.point2.y),
this._context.lineTo(t.point3.x, t.point3.y),
(this._context.fillStyle = o),
this._context.fill(),
this._options.strokeSize > 0 &&
((this._context.lineWidth = this._options.strokeSize),
(this._context.strokeStyle = o),
(this._context.lineCap = 'round'),
this._context.stroke()),
this._context.restore()
}
return !1
},
_onDraw: function () {
for (let t = 0, i = this._ribbons.length; t < i; ++t)
this._ribbons[t] || this._ribbons.splice(t, 1)
this._context.clearRect(0, 0, this._width, this._height)
for (let t = 0; t < this._ribbons.length; ++t) {
const i = this._ribbons[t],
n = i.length
let o = 0
for (let t = 0; t < n; ++t) this._drawRibbonSection(i[t]) && o++
o >= n && (this._ribbons[t] = null)
}
this._ribbons.length < this._options.ribbonCount &&
this.addRibbon(),
requestAnimationFrame(this._onDraw)
},
_onResize: function (t) {
const i = s(t)
;(this._width = i.width),
(this._height = i.height),
this._canvas &&
((this._canvas.width = this._width),
(this._canvas.height = this._height),
this._context &&
(this._context.globalAlpha = this._options.colorAlpha))
},
_onScroll: function (t) {
const i = s(t)
this._scroll = i.scrolly
}
}),
h
)
})())
new Ribbons({
colorSaturation: '60%',
colorBrightness: '50%',
colorAlpha: 0.5,
colorCycleSpeed: 5,
verticalPosition: 'random',
horizontalSpeed: 200,
ribbonCount: 3,
strokeSize: 0,
parallaxAmount: -0.2,
animateSections: !0
})
}
2 changes: 2 additions & 0 deletions pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { DebugPanel } from '@/components/DebugPanel'
import { ThemeSwitch } from '@/components/ThemeSwitch'
import { Fireworks } from '@/components/Fireworks'
import { Nest } from '@/components/Nest'
import { FlutteringRibbon } from '@/components/FlutteringRibbon'
import { Sakura } from '@/components/Sakura'
import { StarrySky } from '@/components/StarrySky'
import MusicPlayer from '@/components/MusicPlayer'
Expand Down Expand Up @@ -55,6 +56,7 @@ const MyApp = ({ Component, pageProps }) => {
{JSON.parse(BLOG.STARRY_SKY) && <StarrySky />}
{JSON.parse(BLOG.MUSIC_PLAYER) && <MusicPlayer />}
{JSON.parse(BLOG.NEST) && <Nest />}
{JSON.parse(BLOG.FLUTTERINGRIBBON) && <FlutteringRibbon />}
</>

// 默认Webfont: 请在font.js文件中检查font-family 新版改从npm本地导入;
Expand Down

0 comments on commit ee19780

Please sign in to comment.