⚡ fix: click effect
This commit is contained in:
parent
da27325950
commit
1609b61336
@ -171,12 +171,8 @@ mouse:
|
|||||||
enable: false
|
enable: false
|
||||||
path: /images/mouse.cur
|
path: /images/mouse.cur
|
||||||
|
|
||||||
# ClickLove
|
# Click effect: 0-close,1-love,2-boom,3-particles
|
||||||
clickLove: false
|
click_effect: 0
|
||||||
# ClickBoom style 1
|
|
||||||
clickBoom: false
|
|
||||||
# ClickBoom style 2
|
|
||||||
clickBoom2: false
|
|
||||||
|
|
||||||
# articleWidth and sidebarWidth
|
# articleWidth and sidebarWidth
|
||||||
layout:
|
layout:
|
||||||
|
10
_config.yml
10
_config.yml
@ -97,19 +97,15 @@ rss: /atom.xml
|
|||||||
darkmode: true
|
darkmode: true
|
||||||
|
|
||||||
# 动态背景效果: 0-关闭,1-动态线条(跟随鼠标)
|
# 动态背景效果: 0-关闭,1-动态线条(跟随鼠标)
|
||||||
canvas_bg: 0
|
canvas_bg: 1
|
||||||
|
|
||||||
# 自定义鼠标样式,直接替换/images/mouse.cur文件
|
# 自定义鼠标样式,直接替换/images/mouse.cur文件
|
||||||
mouse:
|
mouse:
|
||||||
enable: false
|
enable: false
|
||||||
path: /images/mouse.cur
|
path: /images/mouse.cur
|
||||||
|
|
||||||
# 页面点击小红心(开启请设置为true)
|
# 鼠标点击效果:0-关闭,1-爱心,2-爆炸烟花,3-粒子烟花
|
||||||
clickLove: false
|
click_effect: 0
|
||||||
# 页面点击-粒子烟花效果(开启请设置为true)
|
|
||||||
clickBoom: false
|
|
||||||
# 页面点击-爆炸烟花效果(开启请设置为true)
|
|
||||||
clickBoom2: false
|
|
||||||
|
|
||||||
# 页面宽度自定义(不建议修改,可能造成布局混乱),article_width文章宽度,sidebar_width侧边栏宽度
|
# 页面宽度自定义(不建议修改,可能造成布局混乱),article_width文章宽度,sidebar_width侧边栏宽度
|
||||||
layout:
|
layout:
|
||||||
|
@ -60,16 +60,16 @@
|
|||||||
<%- js('/js/busuanzi-2.3.pure.min') %>
|
<%- js('/js/busuanzi-2.3.pure.min') %>
|
||||||
<% } %>
|
<% } %>
|
||||||
<!-- ClickLove -->
|
<!-- ClickLove -->
|
||||||
<% if (theme.clickLove){ %>
|
<% if (theme.click_effect===1){ %>
|
||||||
<%- js('/js/clickLove') %>
|
<%- js('/js/clickLove') %>
|
||||||
<% } %>
|
<% } %>
|
||||||
<!-- ClickBoom -->
|
<!-- ClickBoom1 -->
|
||||||
<% if (theme.clickBoom){ %>
|
<% if (theme.click_effect===2){ %>
|
||||||
<%- js('/js/clickBoom') %>
|
<script src="https://cdn.jsdelivr.net/npm/animejs@latest/anime.min.js"></script>
|
||||||
|
<%- js('/js/clickBoom1') %>
|
||||||
<% } %>
|
<% } %>
|
||||||
<!-- ClickBoom2 -->
|
<!-- ClickBoom2 -->
|
||||||
<% if (theme.clickBoom2){ %>
|
<% if (theme.click_effect===3){ %>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/animejs@latest/anime.min.js"></script>
|
|
||||||
<%- js('/js/clickBoom2') %>
|
<%- js('/js/clickBoom2') %>
|
||||||
<% } %>
|
<% } %>
|
||||||
<!-- CodeCopy -->
|
<!-- CodeCopy -->
|
||||||
|
@ -1,22 +1,6 @@
|
|||||||
<%- partial('_partial/head') %>
|
<%- partial('_partial/head') %>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<% if (theme.clickBoom){ %>
|
|
||||||
<canvas width="1777" height="841"
|
|
||||||
style="position: fixed; left: 0px; top: 0px; z-index: 999; pointer-events: none;"></canvas>
|
|
||||||
<% } %>
|
|
||||||
<% if (theme.clickBoom2){ %>
|
|
||||||
<canvas class="fireworks"></canvas>
|
|
||||||
<style>
|
|
||||||
.fireworks {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
z-index: 99999;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<% } %>
|
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<main class="content on">
|
<main class="content on">
|
||||||
<%- body %>
|
<%- body %>
|
||||||
@ -40,6 +24,23 @@
|
|||||||
<% if (theme.music&&theme.music.enable){ %>
|
<% if (theme.music&&theme.music.enable){ %>
|
||||||
<%- partial('_partial/music') %>
|
<%- partial('_partial/music') %>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
<% if (theme.click_effect===2){ %>
|
||||||
|
<canvas class="fireworks"></canvas>
|
||||||
|
<style>
|
||||||
|
.fireworks {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 99999;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<% } %>
|
||||||
|
<% if (theme.click_effect===3){ %>
|
||||||
|
<canvas width="1777" height="841"
|
||||||
|
style="position: fixed; left: 0px; top: 0px; z-index: 99999; pointer-events: none;"></canvas>
|
||||||
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -1,154 +0,0 @@
|
|||||||
class Circle {
|
|
||||||
constructor({ origin, speed, color, angle, context }) {
|
|
||||||
this.origin = origin
|
|
||||||
this.position = { ...this.origin }
|
|
||||||
this.color = color
|
|
||||||
this.speed = speed
|
|
||||||
this.angle = angle
|
|
||||||
this.context = context
|
|
||||||
this.renderCount = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
draw() {
|
|
||||||
this.context.fillStyle = this.color
|
|
||||||
this.context.beginPath()
|
|
||||||
this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2)
|
|
||||||
this.context.fill()
|
|
||||||
}
|
|
||||||
|
|
||||||
move() {
|
|
||||||
this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x
|
|
||||||
this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3)
|
|
||||||
this.renderCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Boom {
|
|
||||||
constructor ({ origin, context, circleCount = 10, area }) {
|
|
||||||
this.origin = origin
|
|
||||||
this.context = context
|
|
||||||
this.circleCount = circleCount
|
|
||||||
this.area = area
|
|
||||||
this.stop = false
|
|
||||||
this.circles = []
|
|
||||||
}
|
|
||||||
|
|
||||||
randomArray(range) {
|
|
||||||
const length = range.length
|
|
||||||
const randomIndex = Math.floor(length * Math.random())
|
|
||||||
return range[randomIndex]
|
|
||||||
}
|
|
||||||
|
|
||||||
randomColor() {
|
|
||||||
const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
|
|
||||||
return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range)
|
|
||||||
}
|
|
||||||
|
|
||||||
randomRange(start, end) {
|
|
||||||
return (end - start) * Math.random() + start
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
for(let i = 0; i < this.circleCount; i++) {
|
|
||||||
const circle = new Circle({
|
|
||||||
context: this.context,
|
|
||||||
origin: this.origin,
|
|
||||||
color: this.randomColor(),
|
|
||||||
angle: this.randomRange(Math.PI - 1, Math.PI + 1),
|
|
||||||
speed: this.randomRange(1, 6)
|
|
||||||
})
|
|
||||||
this.circles.push(circle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
move() {
|
|
||||||
this.circles.forEach((circle, index) => {
|
|
||||||
if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
|
|
||||||
return this.circles.splice(index, 1)
|
|
||||||
}
|
|
||||||
circle.move()
|
|
||||||
})
|
|
||||||
if (this.circles.length == 0) {
|
|
||||||
this.stop = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draw() {
|
|
||||||
this.circles.forEach(circle => circle.draw())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CursorSpecialEffects {
|
|
||||||
constructor() {
|
|
||||||
this.computerCanvas = document.createElement('canvas')
|
|
||||||
this.renderCanvas = document.createElement('canvas')
|
|
||||||
|
|
||||||
this.computerContext = this.computerCanvas.getContext('2d')
|
|
||||||
this.renderContext = this.renderCanvas.getContext('2d')
|
|
||||||
|
|
||||||
this.globalWidth = window.innerWidth
|
|
||||||
this.globalHeight = window.innerHeight
|
|
||||||
|
|
||||||
this.booms = []
|
|
||||||
this.running = false
|
|
||||||
}
|
|
||||||
|
|
||||||
handleMouseDown(e) {
|
|
||||||
const boom = new Boom({
|
|
||||||
origin: { x: e.clientX, y: e.clientY },
|
|
||||||
context: this.computerContext,
|
|
||||||
area: {
|
|
||||||
width: this.globalWidth,
|
|
||||||
height: this.globalHeight
|
|
||||||
}
|
|
||||||
})
|
|
||||||
boom.init()
|
|
||||||
this.booms.push(boom)
|
|
||||||
this.running || this.run()
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePageHide() {
|
|
||||||
this.booms = []
|
|
||||||
this.running = false
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
const style = this.renderCanvas.style
|
|
||||||
style.position = 'fixed'
|
|
||||||
style.top = style.left = 0
|
|
||||||
style.zIndex = '999999999999999999999999999999999999999999'
|
|
||||||
style.pointerEvents = 'none'
|
|
||||||
|
|
||||||
style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth
|
|
||||||
style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight
|
|
||||||
|
|
||||||
document.body.append(this.renderCanvas)
|
|
||||||
|
|
||||||
window.addEventListener('mousedown', this.handleMouseDown.bind(this))
|
|
||||||
window.addEventListener('pagehide', this.handlePageHide.bind(this))
|
|
||||||
}
|
|
||||||
|
|
||||||
run() {
|
|
||||||
this.running = true
|
|
||||||
if (this.booms.length == 0) {
|
|
||||||
return this.running = false
|
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(this.run.bind(this))
|
|
||||||
|
|
||||||
this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
|
|
||||||
this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
|
|
||||||
|
|
||||||
this.booms.forEach((boom, index) => {
|
|
||||||
if (boom.stop) {
|
|
||||||
return this.booms.splice(index, 1)
|
|
||||||
}
|
|
||||||
boom.move()
|
|
||||||
boom.draw()
|
|
||||||
})
|
|
||||||
this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const cursorSpecialEffects = new CursorSpecialEffects()
|
|
||||||
cursorSpecialEffects.init()
|
|
152
source/js/clickBoom1.js
Normal file
152
source/js/clickBoom1.js
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
const numberOfParticules = 20;
|
||||||
|
|
||||||
|
const minOrbitRadius = 50;
|
||||||
|
const maxOrbitRadius = 100;
|
||||||
|
|
||||||
|
const minCircleRadius = 10;
|
||||||
|
const maxCircleRadius = 20;
|
||||||
|
|
||||||
|
const minAnimeDuration = 900;
|
||||||
|
const maxAnimeDuration = 1500;
|
||||||
|
|
||||||
|
const minDiffuseRadius = 50;
|
||||||
|
const maxDiffuseRadius = 100;
|
||||||
|
|
||||||
|
let canvasEl = document.querySelector(".fireworks");
|
||||||
|
let ctx = canvasEl.getContext("2d");
|
||||||
|
let pointerX = 0;
|
||||||
|
let pointerY = 0;
|
||||||
|
|
||||||
|
let tap =
|
||||||
|
"ontouchstart" in window || navigator.msMaxTouchPoints
|
||||||
|
? "touchstart"
|
||||||
|
: "mousedown";
|
||||||
|
|
||||||
|
// sea blue
|
||||||
|
let colors = ["127, 180, 226", "157, 209, 243", "204, 229, 255"];
|
||||||
|
|
||||||
|
function setCanvasSize() {
|
||||||
|
canvasEl.width = window.innerWidth;
|
||||||
|
canvasEl.height = window.innerHeight;
|
||||||
|
canvasEl.style.width = window.innerWidth + "px";
|
||||||
|
canvasEl.style.height = window.innerHeight + "px";
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCoords(e) {
|
||||||
|
pointerX = e.clientX || e.touches[0].clientX;
|
||||||
|
pointerY = e.clientY || e.touches[0].clientY;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setParticuleDirection(p) {
|
||||||
|
let angle = (anime.random(0, 360) * Math.PI) / 180;
|
||||||
|
let value = anime.random(minDiffuseRadius, maxDiffuseRadius);
|
||||||
|
let radius = [-1, 1][anime.random(0, 1)] * value;
|
||||||
|
return {
|
||||||
|
x: p.x + radius * Math.cos(angle),
|
||||||
|
y: p.y + radius * Math.sin(angle)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createParticule(x, y) {
|
||||||
|
let p = {};
|
||||||
|
p.x = x;
|
||||||
|
p.y = y;
|
||||||
|
p.color =
|
||||||
|
"rgba(" +
|
||||||
|
colors[anime.random(0, colors.length - 1)] +
|
||||||
|
"," +
|
||||||
|
anime.random(0.2, 0.8) +
|
||||||
|
")";
|
||||||
|
p.radius = anime.random(minCircleRadius, maxCircleRadius);
|
||||||
|
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) {
|
||||||
|
let p = {};
|
||||||
|
p.x = x;
|
||||||
|
p.y = y;
|
||||||
|
p.color = "#000";
|
||||||
|
p.radius = 0.1;
|
||||||
|
p.alpha = 0.5;
|
||||||
|
p.lineWidth = 6;
|
||||||
|
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) {
|
||||||
|
let circle = createCircle(x, y);
|
||||||
|
let particules = [];
|
||||||
|
for (let i = 0; i < numberOfParticules; i++) {
|
||||||
|
particules.push(createParticule(x, y));
|
||||||
|
}
|
||||||
|
anime
|
||||||
|
.timeline()
|
||||||
|
.add({
|
||||||
|
targets: particules,
|
||||||
|
x: function (p) {
|
||||||
|
return p.endPos.x;
|
||||||
|
},
|
||||||
|
y: function (p) {
|
||||||
|
return p.endPos.y;
|
||||||
|
},
|
||||||
|
radius: 0.1,
|
||||||
|
duration: anime.random(minAnimeDuration, maxAnimeDuration),
|
||||||
|
easing: "easeOutExpo",
|
||||||
|
update: renderParticule
|
||||||
|
})
|
||||||
|
.add({
|
||||||
|
targets: circle,
|
||||||
|
radius: anime.random(minOrbitRadius, maxOrbitRadius),
|
||||||
|
lineWidth: 0,
|
||||||
|
alpha: {
|
||||||
|
value: 0,
|
||||||
|
easing: "linear",
|
||||||
|
duration: anime.random(600, 800)
|
||||||
|
},
|
||||||
|
duration: anime.random(1200, 1800),
|
||||||
|
easing: "easeOutExpo",
|
||||||
|
update: renderParticule,
|
||||||
|
offset: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let render = anime({
|
||||||
|
duration: Infinity,
|
||||||
|
update: function () {
|
||||||
|
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener(
|
||||||
|
tap,
|
||||||
|
function (e) {
|
||||||
|
render.play();
|
||||||
|
updateCoords(e);
|
||||||
|
animateParticules(pointerX, pointerY);
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
setCanvasSize();
|
||||||
|
window.addEventListener("resize", setCanvasSize, false);
|
@ -1,152 +1,154 @@
|
|||||||
const numberOfParticules = 20;
|
class Circle {
|
||||||
|
constructor({ origin, speed, color, angle, context }) {
|
||||||
const minOrbitRadius = 50;
|
this.origin = origin
|
||||||
const maxOrbitRadius = 100;
|
this.position = { ...this.origin }
|
||||||
|
this.color = color
|
||||||
const minCircleRadius = 10;
|
this.speed = speed
|
||||||
const maxCircleRadius = 20;
|
this.angle = angle
|
||||||
|
this.context = context
|
||||||
const minAnimeDuration = 900;
|
this.renderCount = 0
|
||||||
const maxAnimeDuration = 1500;
|
|
||||||
|
|
||||||
const minDiffuseRadius = 50;
|
|
||||||
const maxDiffuseRadius = 100;
|
|
||||||
|
|
||||||
let canvasEl = document.querySelector(".fireworks");
|
|
||||||
let ctx = canvasEl.getContext("2d");
|
|
||||||
let pointerX = 0;
|
|
||||||
let pointerY = 0;
|
|
||||||
|
|
||||||
let tap =
|
|
||||||
"ontouchstart" in window || navigator.msMaxTouchPoints
|
|
||||||
? "touchstart"
|
|
||||||
: "mousedown";
|
|
||||||
|
|
||||||
// sea blue
|
|
||||||
let colors = ["127, 180, 226", "157, 209, 243", "204, 229, 255"];
|
|
||||||
|
|
||||||
function setCanvasSize() {
|
|
||||||
canvasEl.width = window.innerWidth;
|
|
||||||
canvasEl.height = window.innerHeight;
|
|
||||||
canvasEl.style.width = window.innerWidth + "px";
|
|
||||||
canvasEl.style.height = window.innerHeight + "px";
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateCoords(e) {
|
|
||||||
pointerX = e.clientX || e.touches[0].clientX;
|
|
||||||
pointerY = e.clientY || e.touches[0].clientY;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setParticuleDirection(p) {
|
|
||||||
let angle = (anime.random(0, 360) * Math.PI) / 180;
|
|
||||||
let value = anime.random(minDiffuseRadius, maxDiffuseRadius);
|
|
||||||
let radius = [-1, 1][anime.random(0, 1)] * value;
|
|
||||||
return {
|
|
||||||
x: p.x + radius * Math.cos(angle),
|
|
||||||
y: p.y + radius * Math.sin(angle)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function createParticule(x, y) {
|
|
||||||
let p = {};
|
|
||||||
p.x = x;
|
|
||||||
p.y = y;
|
|
||||||
p.color =
|
|
||||||
"rgba(" +
|
|
||||||
colors[anime.random(0, colors.length - 1)] +
|
|
||||||
"," +
|
|
||||||
anime.random(0.2, 0.8) +
|
|
||||||
")";
|
|
||||||
p.radius = anime.random(minCircleRadius, maxCircleRadius);
|
|
||||||
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) {
|
|
||||||
let p = {};
|
|
||||||
p.x = x;
|
|
||||||
p.y = y;
|
|
||||||
p.color = "#000";
|
|
||||||
p.radius = 0.1;
|
|
||||||
p.alpha = 0.5;
|
|
||||||
p.lineWidth = 6;
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
draw() {
|
||||||
function animateParticules(x, y) {
|
this.context.fillStyle = this.color
|
||||||
let circle = createCircle(x, y);
|
this.context.beginPath()
|
||||||
let particules = [];
|
this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2)
|
||||||
for (let i = 0; i < numberOfParticules; i++) {
|
this.context.fill()
|
||||||
particules.push(createParticule(x, y));
|
|
||||||
}
|
}
|
||||||
anime
|
|
||||||
.timeline()
|
move() {
|
||||||
.add({
|
this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x
|
||||||
targets: particules,
|
this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3)
|
||||||
x: function (p) {
|
this.renderCount++
|
||||||
return p.endPos.x;
|
}
|
||||||
},
|
}
|
||||||
y: function (p) {
|
|
||||||
return p.endPos.y;
|
class Boom {
|
||||||
},
|
constructor ({ origin, context, circleCount = 10, area }) {
|
||||||
radius: 0.1,
|
this.origin = origin
|
||||||
duration: anime.random(minAnimeDuration, maxAnimeDuration),
|
this.context = context
|
||||||
easing: "easeOutExpo",
|
this.circleCount = circleCount
|
||||||
update: renderParticule
|
this.area = area
|
||||||
|
this.stop = false
|
||||||
|
this.circles = []
|
||||||
|
}
|
||||||
|
|
||||||
|
randomArray(range) {
|
||||||
|
const length = range.length
|
||||||
|
const randomIndex = Math.floor(length * Math.random())
|
||||||
|
return range[randomIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
randomColor() {
|
||||||
|
const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
|
||||||
|
return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range)
|
||||||
|
}
|
||||||
|
|
||||||
|
randomRange(start, end) {
|
||||||
|
return (end - start) * Math.random() + start
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
for(let i = 0; i < this.circleCount; i++) {
|
||||||
|
const circle = new Circle({
|
||||||
|
context: this.context,
|
||||||
|
origin: this.origin,
|
||||||
|
color: this.randomColor(),
|
||||||
|
angle: this.randomRange(Math.PI - 1, Math.PI + 1),
|
||||||
|
speed: this.randomRange(1, 6)
|
||||||
})
|
})
|
||||||
.add({
|
this.circles.push(circle)
|
||||||
targets: circle,
|
}
|
||||||
radius: anime.random(minOrbitRadius, maxOrbitRadius),
|
|
||||||
lineWidth: 0,
|
|
||||||
alpha: {
|
|
||||||
value: 0,
|
|
||||||
easing: "linear",
|
|
||||||
duration: anime.random(600, 800)
|
|
||||||
},
|
|
||||||
duration: anime.random(1200, 1800),
|
|
||||||
easing: "easeOutExpo",
|
|
||||||
update: renderParticule,
|
|
||||||
offset: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let render = anime({
|
|
||||||
duration: Infinity,
|
|
||||||
update: function () {
|
|
||||||
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
move() {
|
||||||
document.addEventListener(
|
this.circles.forEach((circle, index) => {
|
||||||
tap,
|
if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
|
||||||
function (e) {
|
return this.circles.splice(index, 1)
|
||||||
render.play();
|
}
|
||||||
updateCoords(e);
|
circle.move()
|
||||||
animateParticules(pointerX, pointerY);
|
})
|
||||||
},
|
if (this.circles.length == 0) {
|
||||||
false
|
this.stop = true
|
||||||
);
|
}
|
||||||
|
}
|
||||||
setCanvasSize();
|
|
||||||
window.addEventListener("resize", setCanvasSize, false);
|
draw() {
|
||||||
|
this.circles.forEach(circle => circle.draw())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CursorSpecialEffects {
|
||||||
|
constructor() {
|
||||||
|
this.computerCanvas = document.createElement('canvas')
|
||||||
|
this.renderCanvas = document.createElement('canvas')
|
||||||
|
|
||||||
|
this.computerContext = this.computerCanvas.getContext('2d')
|
||||||
|
this.renderContext = this.renderCanvas.getContext('2d')
|
||||||
|
|
||||||
|
this.globalWidth = window.innerWidth
|
||||||
|
this.globalHeight = window.innerHeight
|
||||||
|
|
||||||
|
this.booms = []
|
||||||
|
this.running = false
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMouseDown(e) {
|
||||||
|
const boom = new Boom({
|
||||||
|
origin: { x: e.clientX, y: e.clientY },
|
||||||
|
context: this.computerContext,
|
||||||
|
area: {
|
||||||
|
width: this.globalWidth,
|
||||||
|
height: this.globalHeight
|
||||||
|
}
|
||||||
|
})
|
||||||
|
boom.init()
|
||||||
|
this.booms.push(boom)
|
||||||
|
this.running || this.run()
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePageHide() {
|
||||||
|
this.booms = []
|
||||||
|
this.running = false
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
const style = this.renderCanvas.style
|
||||||
|
style.position = 'fixed'
|
||||||
|
style.top = style.left = 0
|
||||||
|
style.zIndex = '99999'
|
||||||
|
style.pointerEvents = 'none'
|
||||||
|
|
||||||
|
style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth
|
||||||
|
style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight
|
||||||
|
|
||||||
|
document.body.append(this.renderCanvas)
|
||||||
|
|
||||||
|
window.addEventListener('mousedown', this.handleMouseDown.bind(this))
|
||||||
|
window.addEventListener('pagehide', this.handlePageHide.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
run() {
|
||||||
|
this.running = true
|
||||||
|
if (this.booms.length == 0) {
|
||||||
|
return this.running = false
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(this.run.bind(this))
|
||||||
|
|
||||||
|
this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
|
||||||
|
this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
|
||||||
|
|
||||||
|
this.booms.forEach((boom, index) => {
|
||||||
|
if (boom.stop) {
|
||||||
|
return this.booms.splice(index, 1)
|
||||||
|
}
|
||||||
|
boom.move()
|
||||||
|
boom.draw()
|
||||||
|
})
|
||||||
|
this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cursorSpecialEffects = new CursorSpecialEffects()
|
||||||
|
cursorSpecialEffects.init()
|
Loading…
Reference in New Issue
Block a user