This commit is contained in:
lyswhut
2022-12-17 16:01:31 +08:00
parent 959df65e0a
commit 2aad2c6b8a
3 changed files with 93 additions and 1 deletions
@@ -0,0 +1,183 @@
// https://github.com/tholman/cursor-effects/blob/master/src/bubbleCursor.js
class Particle {
constructor(x, y, fillStyle, strokeStyle) {
const lifeSpan = Math.floor(Math.random() * 60 + 60)
this.initialLifeSpan = lifeSpan //
this.lifeSpan = lifeSpan // ms
this.velocity = {
x: (Math.random() < 0.5 ? -1 : 1) * (Math.random() / 10),
y: -0.4 + Math.random() * -1,
}
this.position = { x, y }
this.fillStyle = fillStyle
this.strokeStyle = strokeStyle
this.baseDimension = 4
}
update(context, width) {
this.position.x += this.velocity.x
this.position.y += this.velocity.y
this.velocity.x += ((Math.random() < 0.5 ? -1 : 1) * 2) / 75
this.velocity.y -= Math.random() / 600
if (this.position.x >= width - 2 || this.position.x <= 2) this.lifeSpan = 0
else if (this.position.y <= 5) this.lifeSpan = 0
this.lifeSpan--
const scale =
0.2 + (this.initialLifeSpan - this.lifeSpan) / this.initialLifeSpan
context.fillStyle = this.fillStyle
context.strokeStyle = this.strokeStyle
context.beginPath()
context.arc(
this.position.x - (this.baseDimension / 2) * scale,
this.position.y - this.baseDimension / 2,
this.baseDimension * scale,
0,
2 * Math.PI,
)
context.stroke()
context.fill()
context.closePath()
}
}
export default class BubbleCursor {
constructor({ element, fillStyle = 'rgba(77, 175, 124, 0.1)', strokeStyle = 'rgba(77, 175, 124, 0.3)' } = {}) {
this.hasWrapperEl = element
this.element = this.hasWrapperEl || document.body
this.width = window.innerWidth
this.height = window.innerHeight
this.cursor = { x: this.width / 2, y: this.width / 2 }
this.particles = []
this.canvas = null
this.context = null
this.fillStyle = fillStyle
this.strokeStyle = strokeStyle
this.init()
}
init() {
this.canvas = document.createElement('canvas')
this.context = this.canvas.getContext('2d')
this.canvas.style.top = '0px'
this.canvas.style.left = '0px'
this.canvas.style.pointerEvents = 'none'
this.canvas.style.zIndex = 100
if (this.hasWrapperEl) {
this.canvas.style.position = 'absolute'
this.element.appendChild(this.canvas)
this.canvas.width = this.element.clientWidth
this.canvas.height = this.element.clientHeight
} else {
this.canvas.style.position = 'fixed'
document.body.appendChild(this.canvas)
this.canvas.width = this.width
this.canvas.height = this.height
}
this.bindEvents()
this.loop()
}
bindEvents() {
this.element.addEventListener('mousemove', this.onMouseMove)
this.element.addEventListener('touchmove', this.onTouchMove, { passive: true })
this.element.addEventListener('touchstart', this.onTouchMove, { passive: true })
window.addEventListener('resize', this.onWindowResize)
}
onWindowResize = (e) => {
this.width = window.innerWidth
this.height = window.innerHeight
if (this.hasWrapperEl) {
this.canvas.width = this.element.clientWidth
this.canvas.height = this.element.clientHeight
} else {
this.canvas.width = this.width
this.canvas.height = this.height
}
}
onTouchMove = (e) => {
if (e.touches.length > 0) {
for (let i = 0; i < e.touches.length; i++) {
this.addParticle(
e.touches[i].clientX,
e.touches[i].clientY,
)
}
}
}
onMouseMove = (e) => {
if (this.hasWrapperEl) {
const boundingRect = this.element.getBoundingClientRect()
this.cursor.x = e.clientX - boundingRect.left
this.cursor.y = e.clientY - boundingRect.top
} else {
this.cursor.x = e.clientX
this.cursor.y = e.clientY
}
this.addParticle(this.cursor.x, this.cursor.y)
}
addParticle(x, y) {
this.particles.push(new Particle(x, y, this.fillStyle, this.strokeStyle))
}
updateParticles() {
this.context.clearRect(0, 0, this.width, this.height)
// Update
for (let i = 0; i < this.particles.length; i++) {
this.particles[i].update(this.context, this.width)
}
// Remove dead particles
for (let i = this.particles.length - 1; i >= 0; i--) {
if (this.particles[i].lifeSpan < 0) {
this.particles.splice(i, 1)
}
}
}
loop = () => {
this.updateParticles()
window.requestAnimationFrame(this.loop)
}
setColor(fillStyle, strokeStyle) {
this.fillStyle = fillStyle
this.strokeStyle = strokeStyle
}
destroy() {
this.element.removeEventListener('mousemove', this.onMouseMove)
this.element.removeEventListener('touchmove', this.onTouchMove, { passive: true })
this.element.removeEventListener('touchstart', this.onTouchMove, { passive: true })
window.removeEventListener('resize', this.onWindowResize)
if (this.hasWrapperEl) {
this.element.removeChild(this.canvas)
} else {
document.body.removeChild(this.canvas)
}
this.canvas = null
this.context = null
}
}
+91
View File
@@ -0,0 +1,91 @@
// -------------------------------------------------------------------------------------------------
// JavaScript Snow Effect - © Copyright 2020 - Jam-Es.com
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------
// Change the following variables to customize the appearance of the particles
var numParticles = window.innerWidth / 50;
var maxSpeed = 2.5;
var minSpeed = 1;
var maxSize = 5;
var minSize = 3;
var maxOpacity = 1;
var minOpacity = 0.2;
// If the following is true, the canvas resolution will be set to match the full viewport width and height.
// var fixCanvasResolution = true;
var snow_particles = [];
var canvas
window.onload = function() {
canvas = document.createElement('canvas')
canvas.style.position = 'fixed';
canvas.style.top = '0px'
canvas.style.left = '0px'
canvas.style.pointerEvents = 'none'
canvas.style.zIndex = 100
canvas.width = document.documentElement.clientWidth
canvas.height = document.documentElement.clientHeight
document.body.appendChild(canvas)
// if (fixCanvasResolution) {
// // canvas.width = window.innerWidth;
// canvas.height = window.innerHeight;
// }
InitPoints();
requestAnimationFrame(Redraw, 15);
window.addEventListener('resize', this.onWindowResize)
}
function onWindowResize (e) {
canvas.width = document.documentElement.clientWidth
canvas.height = document.documentElement.clientHeight
}
function Redraw() {
var ctx = canvas.getContext("2d");
ctx.clearRect(0,0,canvas.width,canvas.height);
for (var i = 0; i < snow_particles.length; i++) {
var newYPos = snow_particles[i].yPos + snow_particles[i].speed;
if (newYPos > window.innerHeight) {
newYPos = getRandomInt(-100,-10);
snow_particles[i].xPos = getRandomInt(0, window.innerWidth);
snow_particles[i].speed = Math.random() * (maxSpeed - minSpeed) + minSpeed;
snow_particles[i].opacity = Math.random() * (maxOpacity - minOpacity) + minOpacity;
snow_particles[i].size = Math.random() * (maxSize - minSize) + minSize;
}
snow_particles[i].yPos = newYPos;
ctx.beginPath();
ctx.arc(snow_particles[i].xPos, newYPos, snow_particles[i].size, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(255, 255, 255, " + snow_particles[i].opacity + ")";
ctx.fill();
}
requestAnimationFrame(Redraw)
}
function InitPoints() {
for (var i = 0; i < numParticles; i++) {
var startX = getRandomInt(0, window.innerWidth);
var startY = getRandomInt(0, window.innerHeight);
var speed = Math.random() * (maxSpeed - minSpeed) + minSpeed;
var opacity = Math.random() * (maxOpacity - minOpacity) + minOpacity;
var size = Math.random() * (maxSize - minSize) + minSize;
snow_particles.push({
"xPos": startX,
"yPos": startY,
"speed": speed,
"opacity": opacity,
"size": size,
});
}
}
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}