From 9317a2d5d4c711db83440aed431b24a34cc6d6f0 Mon Sep 17 00:00:00 2001
From: shenyu <448766534@qq.com>
Date: Sat, 23 May 2020 06:45:12 +0800
Subject: [PATCH] :rocket: feat: clickBoom
---
_config.yml | 6 +-
layout/_partial/after-footer.ejs | 4 +
layout/layout.ejs | 3 +
source/js/clickBoom.js | 154 +++++++++++++++++++++++++++++++
4 files changed, 165 insertions(+), 2 deletions(-)
create mode 100644 source/js/clickBoom.js
diff --git a/_config.yml b/_config.yml
index 6699612..f5c82a3 100644
--- a/_config.yml
+++ b/_config.yml
@@ -98,6 +98,8 @@ darkmode: true
# 页面点击小红心(开启请设置为true)
clickLove: false
+# 页面点击烟花效果(开启请设置为true)
+clickBoom: false
# 页面宽度自定义(不建议修改,可能造成布局混乱),article_width文章宽度,sidebar_width侧边栏宽度
layout:
@@ -110,8 +112,8 @@ layout:
# 启用Valine必须先创建leancloud应用, 获取 id|key 填入即可
leancloud:
enable: true
- app_id: # Your leancloud application appid
- app_key: # Your leancloud application appkey
+ app_id: #
+ app_key: #
# Valine配置
valine:
enable: true # 是否启用
diff --git a/layout/_partial/after-footer.ejs b/layout/_partial/after-footer.ejs
index ac40d69..7a8d47b 100644
--- a/layout/_partial/after-footer.ejs
+++ b/layout/_partial/after-footer.ejs
@@ -63,6 +63,10 @@
<% if (theme.clickLove){ %>
<%- js('/js/clickLove') %>
<% } %>
+
+<% if (theme.clickBoom){ %>
+<%- js('/js/clickBoom') %>
+<% } %>
<% if (theme.copy_btn == true) { %>
<%- css('/css/clipboard') %>
diff --git a/layout/layout.ejs b/layout/layout.ejs
index 0af2813..2ba1906 100644
--- a/layout/layout.ejs
+++ b/layout/layout.ejs
@@ -1,6 +1,9 @@
<%- partial('_partial/head') %>
+ <% if (theme.clickBoom){ %>
+
+ <% } %>
<%- body %>
diff --git a/source/js/clickBoom.js b/source/js/clickBoom.js
new file mode 100644
index 0000000..7926f94
--- /dev/null
+++ b/source/js/clickBoom.js
@@ -0,0 +1,154 @@
+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()
\ No newline at end of file