AIchat冬日限定系列主题
更新内容
实机效果
PC端效果

手机端效果

使用方式
一. [推荐]直接调用COS对象存储
对象存储中的代码已更新,之前调用对象存储的站长无需更新
1.进入管理后台,找到 网站全局脚本 这一栏
2.在后方输入框中输入以下代码:
var script = document.createElement('script');
script.src = 'https://js-snow-1300868563.cos.ap-nanjing.myqcloud.com/snow.js';
document.head.appendChild(script);
3.保存即可
二. 自行本地化
- 有能力的站长们可以自行将代码放置到js文件中,进行本地化部署
- 代码会在文末给出
三. [慎用]直接复制代码到网站全局脚本
- 将文末给出的代码直接复制到 网站全局脚本 这一栏
- 经个人测试,可以运行,但有可能存在未知问题
- 若原先全局脚本一栏已经填写过内容,请谨慎使用
源代码
class SnowFall {
constructor(snow) {
snow = snow || {};
this.isAnimating = false;
this.maxFlake = this.isMobile() ? 15 : (snow.maxFlake || 200);
this.flakeSize = snow.flakeSize || 15;
this.canvas = this.createCanvas();
this.ctx = this.canvas.getContext("2d");
this.setCanvasSize();
window.addEventListener('resize', () => {
cancelAnimationFrame(this.loop);
this.setCanvasSize();
this.flakes = this.createFlakes();
this.start();
});
this.flakes = this.createFlakes();
this.setupMouseInteraction();
}
isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
createCanvas() {
const snowcanvas = document.createElement("canvas");
snowcanvas.id = "snowfall";
snowcanvas.width = window.innerWidth;
snowcanvas.height = window.innerHeight;
snowcanvas.style.cssText = "position:absolute; top: 0; left: 0; z-index: 1; pointer-events: none;";
document.body.appendChild(snowcanvas);
return snowcanvas;
}
setCanvasSize() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
}
setupMouseInteraction() {
this.mouseX = 0;
this.mouseY = 0;
window.addEventListener('mousemove', (e) => {
this.mouseX = e.clientX;
this.mouseY = e.clientY;
});
}
createFlakes() {
const flakes = [];
const snowflakeCharacters = ["❄", "❉", "❅", "❆", "✻", "❇", "❈", "❊", "✺", "🎄", "🎁", "🔔", "☃️", "⛄", "❄️", "🎿", "🛷", "🎗️", "🎅"];
for (let i = 0; i < this.maxFlake; i++) {
const snowflakeCharacter = snowflakeCharacters[Math.floor(Math.random() * snowflakeCharacters.length)];
flakes.push(new FlakeMove(this.canvas.width, this.canvas.height, this.flakeSize, snowflakeCharacter));
}
return flakes;
}
drawSnow() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.flakes.forEach(flake => {
flake.update(this.mouseX, this.mouseY);
flake.render(this.ctx);
});
this.loop = requestAnimationFrame(() => this.drawSnow());
}
start() {
this.drawSnow();
}
toggleAnimation() {
if (this.isAnimating) {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
cancelAnimationFrame(this.loop);
} else {
this.start();
}
this.isAnimating = !this.isAnimating;
}
}
class FlakeMove {
constructor(canvasWidth, canvasHeight, flakeSize, character) {
this.canvasWidth = canvasWidth;
this.canvasHeight = canvasHeight;
this.x = Math.floor(Math.random() * canvasWidth);
this.y = Math.floor(Math.random() * canvasHeight);
this.size = Math.random() * flakeSize + 2;
this.maxSize = flakeSize;
this.velY = Math.random() * 0.8 + 0.3;
this.velX = Math.random() * 1 - 0.5;
this.character = character;
}
update(mouseX, mouseY) {
const distance = Math.sqrt(Math.pow(this.x - mouseX, 2) + Math.pow(this.y - mouseY, 2));
if (distance < 50) {
const angle = Math.atan2(this.y - mouseY, this.x - mouseX);
this.velX += Math.cos(angle) * 0.5;
this.velY += Math.sin(angle) * 0.25;
}
this.y += this.velY;
this.x += this.velX;
if (this.x >= this.canvasWidth || this.x <= 0 || this.y >= this.canvasHeight || this.y <= 0) {
this.reset();
}
}
reset() {
this.x = Math.floor(Math.random() * this.canvasWidth);
this.y = 0;
this.size = Math.random() * this.maxSize + 2;
this.velY = Math.random() * 0.8 + 0.3;
this.velX = Math.random() * 1 - 0.5;
}
render(ctx) {
ctx.save();
ctx.font = `${this.size}px Arial`;
ctx.fillStyle = "white";
ctx.fillText(this.character, this.x, this.y);
ctx.restore();
}
}
function addButtonIfMissing() {
const targetSelector = "#app-body > div > div.chat_chat-input-panel__rO72m > div.chat_chat-input-actions__mwYC_";
const targetElement = document.querySelector(targetSelector);
if (targetElement) {
const existingButton = targetElement.querySelector("#toggleButton");
if (!existingButton) {
const toggleButton = document.createElement("button");
toggleButton.id = "toggleButton";
toggleButton.textContent = "❄️";
toggleButton.style.display = "inline-flex";
toggleButton.style.borderRadius = "20px";
toggleButton.style.fontSize = "12px";
toggleButton.style.backgroundColor = "var(--white)";
toggleButton.style.color = "var(--black)";
toggleButton.style.border = "var(--border-in-light)";
toggleButton.style.padding = "4px 10px";
toggleButton.style.animation = "chat_slide-in__nvZgA .3s ease";
toggleButton.style.boxShadow = "var(--card-shadow)";
toggleButton.style.transition = "all .3s ease";
toggleButton.style.alignItems = "center";
toggleButton.style.height = "26px";
toggleButton.style.width = "var(--icon-width)";
targetElement.appendChild(toggleButton);
const snow = new SnowFall({ maxFlake: 60 });
toggleButton.addEventListener("click", () => {
snow.toggleAnimation();
});
} else {
console.log("按钮已存在,无需添加");
}
} else {
console.error("未找到指定元素");
}
}
document.addEventListener("DOMContentLoaded", addButtonIfMissing);
setInterval(addButtonIfMissing, 1000);
const style = document.createElement('style');
const css_mouse = 'body, a { cursor: url("data:image/svg+xml;utf8,' +
'<svg xmlns=\'http://www.w3.org/2000/svg\' height=\'16\' width=\'14\' viewBox=\'0 0 448 512\'>' +
'<path fill=\'%23ffffff\' d=\'M224 0c13.3 0 24 10.7 24 24V70.1l23-23c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-57 57v76.5l66.2-38.2 20.9-77.8c3.4-12.8 16.6-20.4 29.4-17s20.4 16.6 17 29.4L373 142.2l37.1-21.4c11.5-6.6 26.2-2.7 32.8 8.8s2.7 26.2-8.8 32.8L397 183.8l31.5 8.4c12.8 3.4 20.4 16.6 17 29.4s-16.6 20.4-29.4 17l-77.8-20.9L272 256l66.2 38.2 77.8-20.9c12.8-3.4 26 4.2 29.4 17s-4.2 26-17 29.4L397 328.2l37.1 21.4c11.5 6.6 15.4 21.3 8.8 32.8s-21.3 15.4-32.8 8.8L373 369.8l8.4 31.5c3.4 12.8-4.2 26-17 29.4s-26-4.2-29.4-17l-20.9-77.8L248 297.6v76.5l57 57c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-23-23V488c0 13.3-10.7 24-24 24s-24-10.7-24-24V441.9l-23 23c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l57-57V297.6l-66.2 38.2-20.9 77.8c-3.4 12.8-16.6 20.4-29.4 17s-20.4-16.6-17-29.4L75 369.8 37.9 391.2c-11.5 6.6-26.2 2.7-32.8-8.8s-2.7-26.2 8.8-32.8L51 328.2l-31.5-8.4c-12.8-3.4-20.4-16.6-17-29.4s16.6-20.4 29.4-17l77.8 20.9L176 256l-66.2-38.2L31.9 238.6c-12.8 3.4-26-4.2-29.4-17s4.2-26 17-29.4L51 183.8 13.9 162.4c-11.5-6.6-15.4-21.3-8.8-32.8s21.3-15.4 32.8-8.8L75 142.2l-8.4-31.5c-3.4-12.8 4.2-26 17-29.4s26 4.2 29.4 17l20.9 77.8L200 214.4V137.9L143 81c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l23 23V24c0-13.3 10.7-24 24-24z\'/>' +
'</svg>") 7 8, pointer; }';
style.appendChild(document.createTextNode(css_mouse));
document.head.appendChild(style);
function fairyDustCursor() {
const possibleColors = ["#D61C59", "#E7D84B", "#1B8798"];
const randomCharacters = ["❄", "❉", "❅", "❆", "✻", "❇", "❈", "❊", "✺", "🎄", "🎁", "🔔", "☃️", "⛄", "❄️", "🎿", "🛷", "🎗️", "🎅"];
let width = window.innerWidth;
let height = window.innerHeight;
const cursor = { x: width / 2, y: width / 2 };
const particles = [];
function init() {
bindEvents();
loop();
}
function bindEvents() {
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('touchmove', onTouchMove);
document.addEventListener('touchstart', onTouchMove);
window.addEventListener('resize', onWindowResize);
}
function onWindowResize(e) {
width = window.innerWidth;
height = window.innerHeight;
}
function onTouchMove(e) {
if (e.touches.length > 0) {
for (let i = 0; i < e.touches.length; i++) {
addParticle(e.touches[i].clientX, e.touches[i].clientY, possibleColors[Math.floor(Math.random() * possibleColors.length)]);
}
}
}
function onMouseMove(e) {
cursor.x = e.clientX;
cursor.y = e.clientY;
addParticle(cursor.x, cursor.y, possibleColors[Math.floor(Math.random() * possibleColors.length)]);
}
function addParticle(x, y, color) {
const particle = new Particle();
particle.init(x, y, color);
particles.push(particle);
}
function updateParticles() {
for (let i = 0; i < particles.length; i++) {
particles[i].update();
}
for (let i = particles.length - 1; i >= 0; i--) {
if (particles[i].lifeSpan < 0) {
particles[i].die();
particles.splice(i, 1);
}
}
}
function loop() {
requestAnimationFrame(loop);
updateParticles();
}
function applyProperties(target, properties) {
for (const key in properties) {
target.style[key] = properties[key];
}
target.style['user-select'] = 'none';
}
function Particle() {
this.character = randomCharacters[Math.floor(Math.random() * randomCharacters.length)];
this.lifeSpan = 120;
this.initialStyles = {
"position": "fixed",
"top": "0",
"display": "block",
"pointerEvents": "none",
"z-index": "10000000",
"fontSize": "20px",
"will-change": "transform"
};
this.init = function (x, y, color) {
this.velocity = {
x: (Math.random() < 0.5 ? -1 : 1) * (Math.random() / 2),
y: 1
};
this.position = { x: x - 10, y: y - 20 };
this.initialStyles.color = color;
this.element = document.createElement('span');
this.element.innerHTML = this.character;
applyProperties(this.element, this.initialStyles);
this.update();
document.body.appendChild(this.element);
};
this.update = function () {
this.position.x += this.velocity.x;
this.position.y += this.velocity.y;
this.lifeSpan--;
this.element.style.transform = "translate3d(" + this.position.x + "px," + this.position.y + "px,0) scale(" + (this.lifeSpan / 120) + ")";
};
this.die = function () {
this.element.parentNode.removeChild(this.element);
};
}
init();
}
fairyDustCursor();