From f0ce260961560e4fbce2a5401014b24101c11cee Mon Sep 17 00:00:00 2001 From: zyronon Date: Fri, 11 Aug 2023 18:32:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=8F=91=E7=83=9F=E8=8A=B1=E5=BC=B9?= =?UTF-8?q?=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Statistics.vue | 380 +++++++++++++++++++++++++++++++++- src/utils/index.ts | 3 + 2 files changed, 382 insertions(+), 1 deletion(-) create mode 100644 src/utils/index.ts diff --git a/src/components/Statistics.vue b/src/components/Statistics.vue index 60d08ebe..d2dd125a 100644 --- a/src/components/Statistics.vue +++ b/src/components/Statistics.vue @@ -4,8 +4,383 @@ import {useBaseStore} from "@/stores/base.ts"; import {Close, ShareThree, KeyboardOne, Tea, Like} from '@icon-park/vue-next' import Ring from "@/components/Ring.vue"; import Tooltip from "@/components/Tooltip.vue"; +import {onMounted} from "vue"; +import {getRandom} from "@/utils/index.js"; const store = useBaseStore() +const canvas = $ref() + +onMounted(() => { + let ocas = document.createElement("canvas"); + let octx = ocas.getContext("2d"); + let ctx = canvas.getContext("2d"); + ocas.width = canvas.width = window.innerWidth; + ocas.height = canvas.height = window.innerHeight; + let bigBooms = []; + let lastTime; + + Array.prototype.foreach = function (callback) { + for (let i = 0; i < this.length; i++) { + if (this[i] !== null) callback.apply(this[i], [i]); + } + }; + + let raf = + window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { + window.setTimeout(callback, 1000 / 60); + }; + + + function initAnimate() { + lastTime = new Date(); + animate(); + } + + initAnimate() + + function animate() { + ctx.save(); + ctx.globalCompositeOperation = "destination-out"; + ctx.globalAlpha = 0.1; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.restore(); + + let newTime = new Date(); + if (newTime - lastTime > 200 + (window.innerHeight - 767) / 2) { + let random = Math.random() * 100 > 2; + let x = getRandom(canvas.width / 5, (canvas.width * 4) / 5); + let y = getRandom(50, 200); + let bigBoom + if (random) { + bigBoom = new Boom( + getRandom(canvas.width / 3, (canvas.width * 2) / 3), + 2, + "#FFF", + {x: x, y: y} + ); + } else { + bigBoom = new Boom( + getRandom(canvas.width / 3, (canvas.width * 2) / 3), + 2, + "#FFF", + {x: canvas.width / 2, y: 200,}, + document.querySelectorAll(".shape")[parseInt(getRandom(0, document.querySelectorAll(".shape").length))] + ); + } + bigBooms.push(bigBoom); + lastTime = newTime; + } + + bigBooms.foreach(function (index) { + let that = this; + if (!this.dead) { + this._move(); + this._drawLight(); + } else { + this.booms.foreach(function (index) { + if (!this.dead) { + this.moveTo(index); + } else if (index === that.booms.length - 1) { + bigBooms.splice(bigBooms.indexOf(that), 1); + } + }); + } + }); + + raf(animate); + } + + canvas.onclick = function () { + let x = event.clientX; + let y = event.clientY; + let bigboom = new Boom( + getRandom(canvas.width / 3, (canvas.width * 2) / 3), + 2, + "#FFF", + {x: x, y: y} + ); + bigBooms.push(bigboom); + }; + + class Boom2 { + booms = []; + x; + y; + r; + c; + shape; + boomArea; + theta; + dead; + ba; + + constructor(x, r, c, boomArea, shape) { + this.x = x; + this.y = canvas.height + r; + this.r = r; + this.c = c; + this.shape = shape || false; + this.boomArea = boomArea; + this.theta = 0; + this.dead = false; + this.ba = parseInt(getRandom(80, 200)); + + let audio = document.getElementsByTagName("audio"); + for (let i = 0; i < audio.length; i++) { + if ( + audio[i].src.indexOf("shotfire") >= 0 && + (audio[i].paused || audio[i].ended) + ) { + audio[i].play(); + break; + } + } + } + } + + let Boom = function (x, r, c, boomArea, shape) { + this.booms = []; + this.x = x; + this.y = canvas.height + r; + this.r = r; + this.c = c; + this.shape = shape || false; + this.boomArea = boomArea; + this.theta = 0; + this.dead = false; + this.ba = parseInt(getRandom(80, 200)); + + let audio = document.getElementsByTagName("audio"); + for (let i = 0; i < audio.length; i++) { + if ( + audio[i].src.indexOf("shotfire") >= 0 && + (audio[i].paused || audio[i].ended) + ) { + audio[i].play(); + break; + } + } + }; + Boom.prototype = { + _paint: function () { + ctx.save(); + ctx.beginPath(); + ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI); + ctx.fillStyle = this.c; + ctx.fill(); + ctx.restore(); + }, + _move: function () { + let dx = this.boomArea.x - this.x, + dy = this.boomArea.y - this.y; + this.x = this.x + dx * 0.01; + this.y = this.y + dy * 0.01; + + if (Math.abs(dx) <= this.ba && Math.abs(dy) <= this.ba) { + if (this.shape) { + this._shapBoom(); + } else this._boom(); + this.dead = true; + } else { + this._paint(); + } + }, + _drawLight: function () { + ctx.save(); + ctx.fillStyle = "rgba(255,228,150,0.3)"; + ctx.beginPath(); + ctx.arc( + this.x, + this.y, + this.r + 3 * Math.random() + 1, + 0, + 2 * Math.PI + ); + ctx.fill(); + ctx.restore(); + }, + _boom: function () { + let fragNum = getRandom(100, 300); + let style = getRandom(0, 10) >= 5 ? 1 : 2; + let color; + if (style === 1) { + color = { + a: parseInt(getRandom(128, 255)), + b: parseInt(getRandom(128, 255)), + c: parseInt(getRandom(128, 255)), + }; + } + + let fanwei = fragNum; + let audio = document.getElementsByTagName("audio"); + for (let i = 0; i < audio.length; i++) { + if ( + audio[i].src.indexOf("boom") >= 0 && + (audio[i].paused || audio[i].ended) + ) { + audio[i].play(); + break; + } + } + for (let i = 0; i < fragNum; i++) { + if (style === 2) { + color = { + a: parseInt(getRandom(128, 255)), + b: parseInt(getRandom(128, 255)), + c: parseInt(getRandom(128, 255)), + }; + } + let a = getRandom(-Math.PI, Math.PI); + let x = getRandom(0, fanwei) * Math.cos(a) + this.x; + let y = getRandom(0, fanwei) * Math.sin(a) + this.y; + let radius = getRandom(0, 2); + let frag = new Frag(this.x, this.y, radius, color, x, y); + this.booms.push(frag); + } + }, + _shapBoom: function () { + let that = this; + putValue(ocas, octx, this.shape, 5, function (dots) { + let dx = canvas.width / 2 - that.x; + let dy = canvas.height / 2 - that.y; + for (let i = 0; i < dots.length; i++) { + let color = {a: dots[i].a, b: dots[i].b, c: dots[i].c}; + let x = dots[i].x; + let y = dots[i].y; + let radius = 1; + let frag = new Frag( + that.x, + that.y, + radius, + color, + x - dx, + y - dy + ); + that.booms.push(frag); + } + }); + }, + }; + + function putValue(canvas, context, ele, dr, callback) { + context.clearRect(0, 0, canvas.width, canvas.height); + let img = new Image(); + if (ele.innerHTML.indexOf("img") >= 0) { + img.src = ele.getElementsByTagName("img")[0].src; + imgload(img, function () { + context.drawImage( + img, + canvas.width / 2 - img.width / 2, + canvas.height / 2 - img.width / 2 + ); + let dots = getimgData(canvas, context, dr); + callback(dots); + }); + } else { + let text = ele.innerHTML; + context.save(); + let fontSize = 200; + context.font = fontSize + "px 宋体 bold"; + context.textAlign = "center"; + context.textBaseline = "middle"; + context.fillStyle = + "rgba(" + + parseInt(getRandom(128, 255)) + + "," + + parseInt(getRandom(128, 255)) + + "," + + parseInt(getRandom(128, 255)) + + " , 1)"; + context.fillText(text, canvas.width / 2, canvas.height / 2); + context.restore(); + let dots = getimgData(canvas, context, dr); + callback(dots); + } + } + + function imgload(img, callback) { + if (img.complete) { + callback.call(img); + } else { + img.onload = function () { + callback.call(this); + }; + } + } + + function getimgData(canvas, context, dr) { + let imgData = context.getImageData(0, 0, canvas.width, canvas.height); + context.clearRect(0, 0, canvas.width, canvas.height); + let dots = []; + for (let x = 0; x < imgData.width; x += dr) { + for (let y = 0; y < imgData.height; y += dr) { + let i = (y * imgData.width + x) * 4; + if (imgData.data[i + 3] > 128) { + let dot = { + x: x, + y: y, + a: imgData.data[i], + b: imgData.data[i + 1], + c: imgData.data[i + 2], + }; + dots.push(dot); + } + } + } + return dots; + } + + + let Frag = function (centerX, centerY, radius, color, tx, ty) { + this.tx = tx; + this.ty = ty; + this.x = centerX; + this.y = centerY; + this.dead = false; + this.centerX = centerX; + this.centerY = centerY; + this.radius = radius; + this.color = color; + }; + + Frag.prototype = { + paint: function () { + // ctx.beginPath(); + // ctx.arc(this.x , this.y , this.radius , 0 , 2*Math.PI); + ctx.fillStyle = + "rgba(" + + this.color.a + + "," + + this.color.b + + "," + + this.color.c + + ",1)"; + ctx.fillRect( + this.x - this.radius, + this.y - this.radius, + this.radius * 2, + this.radius * 2 + ); + }, + moveTo: function (index) { + this.ty = this.ty + 0.3; + let dx = this.tx - this.x, + dy = this.ty - this.y; + this.x = Math.abs(dx) < 0.1 ? this.tx : this.x + dx * 0.1; + this.y = Math.abs(dy) < 0.1 ? this.ty : this.y + dy * 0.1; + if (dx === 0 && Math.abs(dy) <= 80) { + this.dead = true; + } + this.paint(); + }, + }; + +})