// 加载脚本函数
function loadScript(url) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
script.type = 'text/javascript';
script.onload = () => resolve();
script.onerror = () => reject(new Error(`Failed to load script: ${url}`));
document.head.appendChild(script);
});
}
// 加载样式表函数
function loadStyle(url) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
link.onload = () => resolve();
link.onerror = () => reject(new Error(`Failed to load style: ${url}`));
document.head.appendChild(link);
});
}
// 加载多个脚本
async function loadScripts(scripts) {
for (const script of scripts) {
try {
await loadScript(script);
} catch (error) {
console.error(error);
}
}
}
// 加载多个样式表
async function loadStyles(styles) {
const stylePromises = styles.map(style => loadStyle(style));
try {
await Promise.all(stylePromises);
} catch (error) {
console.error(error);
}
}
// 调用函数加载多个样式表
const scriptsToLoad = [
// '/custom/yiyan.js',
// '/custom/fish.js',
// '/custom/toc.js',
// '/custom/mouse.js'
// '/custom/待添加.js', // 如果需要,可以解除注释
];
// 调用函数加载多个脚本
const stylesToLoad = [
// '/custom/bk.css',
// '/custom/mouse.css',
// '/custom/logo.css',
// '/custom/xiantiao.css',
// '/custom/mouse.css',
// '/custom/loading.css'
// '/custom/待添加.css', // 如果需要,可以解除注释
];
// 调用加载函数
loadScripts(scriptsToLoad);
loadStyles(stylesToLoad);
JS代码:
1.// 鼠标点击爆炸特效
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).firework=e()}(this,(function(){"use strict";class t{constructor(){this.queue=[]}add(t){return this.queue.push(new n(t)),this}play(){this.queue.forEach((t=>t.play()))}}const e={targets:null,duration:1/0,easing:"linear",update:null};var s=()=>{const t={linear:()=>t=>t},e={Sine:()=>t=>1-Math.cos(t*Math.PI/2),Circ:()=>t=>1-Math.sqrt(1-t*t),Back:()=>t=>t*t*(3*t-2),Bounce:()=>t=>{let e,s=4;for(;t<((e=Math.pow(2,--s))-1)/11;);return 1/Math.pow(4,3-s)-7.5625*Math.pow((3*e-2)/22-t,2)}};return["Quad","Cubic","Quart","Quint","Expo"].forEach(((t,s)=>{e[t]=()=>t=>Math.pow(t,s+2)})),Object.keys(e).forEach((s=>{const n=e[s];t["easeIn"+s]=n,t["easeOut"+s]=()=>t=>1-n()(1-t),t["easeInOut"+s]=()=>t=>t<.5?n()(2*t)/2:1-n()(-2*t+2)/2,t["easeOutIn"+s]=()=>t=>t<.5?(1-n()(1-2*t))/2:(n()(2*t-1)+1)/2})),t};class n{constructor(t=e){t=Object.assign({},e,t);const{targets:s,duration:n,easing:o,update:i,...a}=t;this.targets=s,this.duration=n,this.easing=o,this.update=i,this.dest=a||{},this.tl=null,this.isPlay=!1}timeline(){return null===this.tl&&(this.tl=new t),this.tl}play(){this.isPlay||(this.isPlay=!0,(t=>{const e=Date.now(),n=e+t.duration,o=!!t.targets,i=[],a=(t,e,s,n,o,i=!1)=>{t[o]=i?n:(n-e)*s+e},r=(n,o,r=!1)=>{t.targets.forEach(((l,c)=>{Object.keys(t.dest).forEach((d=>{const h=parseFloat(i[c][d]);let u=t.dest[d];if("object"==typeof u){if(!Array.isArray(u)){const{value:i,duration:c,easing:p}=u;o<=e+c?(n=s()[p||t.easing]()((o-e)/c),a(l,h,n,i,d)):r&&a(l,h,n,i,d,r)}}else"function"==typeof u&&(u=u(l,c)),a(l,h,n,u,d,r)}))}))},l=()=>{const i=Date.now();if(i>n)return r(1,i,!0),void(t.isPlay=!1);if(i<e)return void requestAnimationFrame(l);const a=s()[t.easing]()((i-e)/t.duration);o&&r(a,i),"function"==typeof t.update&&t.update(t.targets),requestAnimationFrame(l)};(()=>{if(o){Array.isArray(t.targets)||(t.targets=[t.targets]);for(const e of t.targets){const s={};for(const n in t.dest)s[n]=e[n];i.push(s)}}})(),l()})(this))}}const o=t=>new n(t);o.random=(t,e)=>Math.floor(Math.random()*(e-t+1))+t;const i=t=>Array.isArray(t)?o.random(t[0],t[1]):t,a=(t,e)=>{e=e.toUpperCase();do{if(null==t)break;if(t.nodeName===e)return!0}while(null!==(t=t.parentNode));return!1},r=(t,e)=>{var s;if(e.move.includes("emit")){let{emitRadius:n=[50,180]}=null!==(s=e.moveOptions)&&void 0!==s?s:{};const a=o.random(0,360)*Math.PI/180;n=i(n);const r=[-1,1][o.random(0,1)]*n;t.endPos={x:t.x+r*Math.cos(a),y:t.y+r*Math.sin(a)}}},l=(t,e)=>{var s;if(e.move.includes("rotate")){const{angle:n=[-180,180]}=null!==(s=e.moveOptions)&&void 0!==s?s:{};t.endRotation=i(n)}};class c{constructor(t,e,s,n,o,i,a){this.ctx=t,this.x=e,this.y=s,this.color=n,this.radius=o,this.alpha=i,this.lineWidth=a,this.rotation=0}draw(){const{ctx:t,x:e,y:s}=this;t.save(),t.translate(e,s),t.rotate(this.rotation*(Math.PI/180)),t.globalAlpha=this.alpha,this.paint(),this.lineWidth?(t.lineWidth=this.lineWidth,t.strokeStyle=this.color,t.stroke()):(t.fillStyle=this.color,t.fill()),t.globalAlpha=1,t.restore()}}class d extends c{paint(){this.ctx.beginPath(),this.ctx.arc(0,0,this.radius,0,2*Math.PI)}}class h extends c{constructor(t,e,s,n,o,i,a,r){super(t,e,s,n,o,i,r),this.sides=a}paint(){const{ctx:t,sides:e,radius:s}=this;t.beginPath(),t.moveTo(s*Math.cos(0),s*Math.sin(0));for(let n=1;n<=e;n++){const o=2*n*Math.PI/e;t.lineTo(s*Math.cos(o),s*Math.sin(o))}t.closePath()}}class u extends c{constructor(t,e,s,n,o,i,a,r){super(t,e,s,n,o,i,r),this.spikes=a}paint(){const{ctx:t,spikes:e,radius:s}=this;t.beginPath(),t.moveTo(0,0-s);for(let n=0;n<2*e;n++){const o=n*Math.PI/e-Math.PI/2,i=n%2==0?s:.5*s,a=Math.cos(o)*i,r=Math.sin(o)*i;t.lineTo(a,r)}t.closePath()}}const p=(t,e,s,n)=>{const a=i(n.number);let{radius:c,alpha:h=100,lineWidth:u}=n.shapeOptions;Array.isArray(h)?h=h.map((t=>100*t)):h*=100;const p=[];for(let f=0;f<a;f++){const a=new d(t,e,s,n.colors[o.random(0,n.colors.length-1)],i(c),i(h)/100,i(u));r(a,n),l(a,n),p.push(a)}return p},f=(t,e,s,n)=>{const a=i(n.number);let{radius:c,alpha:d=100,lineWidth:h}=n.shapeOptions;Array.isArray(d)?d=d.map((t=>100*t)):d*=100;const p=i(n.shapeOptions.spikes),f=[];for(let m=0;m<a;m++){const a=new u(t,e,s,n.colors[o.random(0,n.colors.length-1)],i(c),i(d)/100,p,i(h));r(a,n),l(a,n),f.push(a)}return f},m=(t,e,s,n)=>{const a=i(n.number);let{radius:c,alpha:d=100,lineWidth:u}=n.shapeOptions;Array.isArray(d)?d=d.map((t=>100*t)):d*=100;const p=[],f=i(n.shapeOptions.sides);for(let m=0;m<a;m++){const a=new h(t,e,s,n.colors[o.random(0,n.colors.length-1)],i(c),i(d)/100,f,i(u));r(a,n),l(a,n),p.push(a)}return p},g=document.createElement("canvas");g.style.cssText="position:fixed;top:0;left:0;pointer-events:none;z-index:9999999",document.body.appendChild(g);const y=g.getContext("2d"),v=/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)?"touchstart":"click";let x=0,w=0;const M=()=>{g.width=2*document.documentElement.clientWidth,g.height=2*document.documentElement.clientHeight,g.style.width=document.documentElement.clientWidth+"px",g.style.height=document.documentElement.clientHeight+"px";const t=g.getContext("2d");t.setTransform(1,0,0,1,0,0),t.scale(2,2)},A=t=>{var e,s,n,o;const{move:a}=t;let r={};if(a.includes("emit")){const{radius:n=.1,alphaChange:o=!1,alphaEasing:a="linear",alphaDuration:l=[600,800]}=null!==(e=t.moveOptions)&&void 0!==e?e:{};let{alpha:c=0}=null!==(s=t.moveOptions)&&void 0!==s?s:{};Array.isArray(c)?c=c.map((t=>100*t)):c*=100;let d={};o&&(d={alpha:{value:i(c)/100,easing:a,duration:i(l)}}),r={...r,x:t=>t.endPos.x,y:t=>t.endPos.y,radius:i(n),...d}}else if(a.includes("diffuse")){const{diffuseRadius:e=[80,160],lineWidth:s=0,alphaEasing:a="linear",alphaDuration:l=[600,800]}=null!==(n=t.moveOptions)&&void 0!==n?n:{};let{alpha:c=0}=null!==(o=t.moveOptions)&&void 0!==o?o:{};Array.isArray(c)?c=c.map((t=>100*t)):c*=100,r={...r,radius:i(e),lineWidth:i(s),alpha:{value:i(c)/100,easing:a,duration:i(l)}}}return a.includes("rotate")&&(r={...r,rotation:t=>t.endRotation}),r},P=t=>{for(const e of t)e.draw()},E=o({duration:1/0,update(){y.clearRect(0,0,g.width,g.height)}});let b=null,O=null;const k=t=>{O=t,b&&document.removeEventListener(v,b,!1),b=e=>{for(const s of t.excludeElements)if(a(e.target,s))return;E.play(),(t=>{x=t.clientX||t.touches&&t.touches[0].clientX,w=t.clientY||t.touches&&t.touches[0].clientY})(e),W(x,w)},document.addEventListener(v,b,!1),M(),window.removeEventListener("resize",M,!1),window.addEventListener("resize",M,!1)},W=(t,e)=>{if(!O)return;const{particles:s}=O,n=o().timeline();for(const o of s){const{duration:s,easing:a}=o;let r=[];"circle"===o.shape?r=p(y,t,e,o):"star"===o.shape?r=f(y,t,e,o):"polygon"===o.shape&&(r=m(y,t,e,o));const l=A(o);n.add({targets:r,duration:i(s),easing:a,update:P,...l})}n.play()};return t=>{"loading"===document.readyState?window.addEventListener("DOMContentLoaded",(()=>k(t)),{passive:!0}):k(t)}}));
firework({
excludeElements: ["a"],
particles: [
{
shape: "circle",
move: "emit",
easing: "easeOutExpo",
colors: [
"rgba(255,182,185,.9)",
"rgba(250,227,217,.9)",
"rgba(187,222,214,.9)",
"rgba(138,198,209,.9)",
],
number: 30,
duration: [1200, 1800],
shapeOptions: {
radius: [16, 32],
},
},
],
});
2./* 一言Sun-Panel-Helper JS Start: search-quote */
// 定义一个函数,用于获取随机句子并更新占位符
function updatePlaceholder() {
// 定义接口列表
const apiUrls = [
'https://v1.hitokoto.cn/',
'https://yyapi.xpdbk.com/api/ian',
'https://api.nxvav.cn/api/yiyan'
];
// 定义一个函数来尝试获取句子
const fetchRandomSentence = (index) => {
if (index >= apiUrls.length) {
console.error('所有接口均获取句子失败');
return;
}
fetch(apiUrls[0])
.then(response => response.json())
.then(data => {
const sentence = data.hitokoto || data.content || data.data;
if (sentence) {
const inputElements = document.querySelectorAll('input[placeholder="请输入搜索内容"]');
if (inputElements.length > 0) {
inputElements.forEach(input => {
input.placeholder = sentence;
});
}
} else {
fetchRandomSentence(index + 1);
}
})
.catch(error => {
console.error('获取句子时出错:', error);
fetchRandomSentence(index + 1);
});
};
// 开始尝试获取句子
fetchRandomSentence(0);
}
// 页面加载时自动调用替换函数
window.onload = updatePlaceholder;
/* Sun-Panel-Helper JS End: search-quote */
3./* Sun-Panel-Helper JS Start: fish-animation */
// ====================== 鱼群动画系统 开始 ======================
window.SunPanelFish = (function() {
// 配置参数
const config = {
fishCount: 3,
heightRate: 0.5,
fishColor: 'hsl(0, 0%, 95%)',
opacity: 0.37
};
// 定义构造函数
function SURFACE_POINT(renderer, x) {
this.renderer = renderer;
this.x = x;
this.init();
}
// 设置完整的原型
SURFACE_POINT.prototype = {
SPRING_CONSTANT: 0.03,
SPRING_FRICTION: 0.9,
WAVE_SPREAD: 0.3,
ACCELARATION_RATE: 0.01,
init: function() {
this.initHeight = this.renderer.height * this.renderer.INIT_HEIGHT_RATE;
this.height = this.initHeight;
this.fy = 0;
this.force = {previous: 0, next: 0};
},
setPreviousPoint: function(previous) {
this.previous = previous;
},
setNextPoint: function(next) {
this.next = next;
},
interfere: function(y, velocity) {
this.fy = this.renderer.height * this.ACCELARATION_RATE * ((this.renderer.height - this.height - y) >= 0 ? -1 : 1) * Math.abs(velocity);
},
updateSelf: function() {
this.fy += this.SPRING_CONSTANT * (this.initHeight - this.height);
this.fy *= this.SPRING_FRICTION;
this.height += this.fy;
},
updateNeighbors: function() {
if(this.previous) {
this.force.previous = this.WAVE_SPREAD * (this.height - this.previous.height);
}
if(this.next) {
this.force.next = this.WAVE_SPREAD * (this.height - this.next.height);
}
},
render: function(context) {
if(this.previous) {
this.previous.height += this.force.previous;
this.previous.fy += this.force.previous;
}
if(this.next) {
this.next.height += this.force.next;
this.next.fy += this.force.next;
}
context.lineTo(this.x, this.renderer.height - this.height);
}
};
function FISH(renderer) {
this.renderer = renderer;
this.init();
}
// 设置完整的原型
FISH.prototype = {
GRAVITY: 0.4,
init: function() {
this.direction = Math.random() < 0.5;
this.x = this.direction ? (this.renderer.width + this.renderer.THRESHOLD) : -this.renderer.THRESHOLD;
this.previousY = this.y;
this.vx = this.getRandomValue(4, 10) * (this.direction ? -1 : 1);
if(this.renderer.reverse) {
this.y = this.getRandomValue(this.renderer.height * 1 / 10, this.renderer.height * 4 / 10);
this.vy = this.getRandomValue(2, 5);
this.ay = this.getRandomValue(0.05, 0.2);
} else {
this.y = this.getRandomValue(this.renderer.height * 6 / 10, this.renderer.height * 9 / 10);
this.vy = this.getRandomValue(-5, -2);
this.ay = this.getRandomValue(-0.2, -0.05);
}
this.isOut = false;
this.theta = 0;
this.phi = 0;
},
getRandomValue: function(min, max) {
return min + (max - min) * Math.random();
},
reverseVertical: function() {
this.isOut = !this.isOut;
this.ay *= -1;
},
controlStatus: function(context) {
this.previousY = this.y;
this.x += this.vx;
this.y += this.vy;
this.vy += this.ay;
if(this.renderer.reverse) {
if(this.y > this.renderer.height * this.renderer.INIT_HEIGHT_RATE) {
this.vy -= this.GRAVITY;
this.isOut = true;
} else {
if(this.isOut) {
this.ay = this.getRandomValue(0.05, 0.2);
}
this.isOut = false;
}
} else {
if(this.y < this.renderer.height * this.renderer.INIT_HEIGHT_RATE) {
this.vy += this.GRAVITY;
this.isOut = true;
} else {
if(this.isOut) {
this.ay = this.getRandomValue(-0.2, -0.05);
}
this.isOut = false;
}
}
if(!this.isOut) {
this.theta += Math.PI / 20;
this.theta %= Math.PI * 2;
this.phi += Math.PI / 30;
this.phi %= Math.PI * 2;
}
this.renderer.generateEpicenter(this.x + (this.direction ? -1 : 1) * this.renderer.THRESHOLD, this.y, this.y - this.previousY);
if(this.vx > 0 && this.x > this.renderer.width + this.renderer.THRESHOLD || this.vx < 0 && this.x < -this.renderer.THRESHOLD) {
this.init();
}
},
render: function(context) {
context.save();
context.translate(this.x, this.y);
context.rotate(Math.PI + Math.atan2(this.vy, this.vx));
context.scale(1, this.direction ? 1 : -1);
context.beginPath();
context.moveTo(-30, 0);
context.bezierCurveTo(-20, 15, 15, 10, 40, 0);
context.bezierCurveTo(15, -10, -20, -15, -30, 0);
context.fill();
context.save();
context.translate(40, 0);
context.scale(0.9 + 0.2 * Math.sin(this.theta), 1);
context.beginPath();
context.moveTo(0, 0);
context.quadraticCurveTo(5, 10, 20, 8);
context.quadraticCurveTo(12, 5, 10, 0);
context.quadraticCurveTo(12, -5, 20, -8);
context.quadraticCurveTo(5, -10, 0, 0);
context.fill();
context.restore();
context.save();
context.translate(-3, 0);
context.rotate((Math.PI / 3 + Math.PI / 10 * Math.sin(this.phi)) * (this.renderer.reverse ? -1 : 1));
context.beginPath();
if(this.renderer.reverse) {
context.moveTo(5, 0);
context.bezierCurveTo(10, 10, 10, 30, 0, 40);
context.bezierCurveTo(-12, 25, -8, 10, 0, 0);
} else {
context.moveTo(-5, 0);
context.bezierCurveTo(-10, -10, -10, -30, 0, -40);
context.bezierCurveTo(12, -25, 8, -10, 0, 0);
}
context.closePath();
context.fill();
context.restore();
context.restore();
this.controlStatus(context);
}
};
// 渲染器对象
var RENDERER = {
POINT_INTERVAL: 5,
FISH_COUNT: config.fishCount,
MAX_INTERVAL_COUNT: 50,
INIT_HEIGHT_RATE: config.heightRate,
THRESHOLD: 50,
init: function() {
this.setParameters();
this.reconstructMethods();
this.setup();
this.bindEvent();
this.render();
},
setParameters: function() {
this.$window = window;
this.$document = document.body;
this.$container = document.getElementById('jsi-flying-fish-container');
this.$canvas = document.createElement('canvas');
this.$container.appendChild(this.$canvas);
this.context = this.$canvas.getContext('2d');
this.points = [];
this.fishes = [];
this.watchIds = [];
},
reconstructMethods: function() {
this.watchWindowSize = this.watchWindowSize.bind(this);
this.jdugeToStopResize = this.jdugeToStopResize.bind(this);
this.startEpicenter = this.startEpicenter.bind(this);
this.moveEpicenter = this.moveEpicenter.bind(this);
this.reverseVertical = this.reverseVertical.bind(this);
this.render = this.render.bind(this);
},
setup: function() {
this.points.length = 0;
this.fishes.length = 0;
this.watchIds.length = 0;
this.intervalCount = this.MAX_INTERVAL_COUNT;
this.width = this.$container.offsetWidth;
this.height = this.$container.offsetHeight;
this.fishCount = Math.ceil(this.FISH_COUNT * (this.width / 1000));
this.$canvas.width = this.width;
this.$canvas.height = this.height;
this.reverse = false;
while(this.fishes.length < this.fishCount) {
this.fishes.push(new FISH(this));
}
this.createSurfacePoints();
},
createSurfacePoints: function() {
var count = Math.round(this.width / this.POINT_INTERVAL);
this.pointInterval = this.width / (count - 1);
this.points.push(new SURFACE_POINT(this, 0));
for(var i = 1; i < count; i++) {
var point = new SURFACE_POINT(this, i * this.pointInterval),
previous = this.points[i - 1];
point.setPreviousPoint(previous);
previous.setNextPoint(point);
this.points.push(point);
}
},
watchWindowSize: function() {
this.clearTimer();
this.tmpWidth = window.innerWidth;
this.tmpHeight = window.innerHeight;
this.watchIds.push(setTimeout(this.jdugeToStopResize, 200));
},
clearTimer: function() {
while(this.watchIds.length > 0) {
clearTimeout(this.watchIds.pop());
}
},
jdugeToStopResize: function() {
var width = window.innerWidth,
height = window.innerHeight,
stopped = (width == this.tmpWidth && height == this.tmpHeight);
this.tmpWidth = width;
this.tmpHeight = height;
if(stopped) {
this.setup();
}
},
bindEvent: function() {
let resizeTimeout;
window.addEventListener('resize', () => {
if (resizeTimeout) {
clearTimeout(resizeTimeout);
}
resizeTimeout = setTimeout(() => {
this.width = this.$container.offsetWidth;
this.height = this.$container.offsetHeight;
this.$canvas.width = this.width;
this.$canvas.height = this.height;
this.setup();
}, 100);
});
this.$container.onclick = this.reverseVertical;
this.$container.onmouseenter = this.startEpicenter;
this.$container.addEventListener('mousemove', this.moveEpicenter);
},
getAxis: function(event) {
var offset = this.getOffset(this.$container);
return {
x: event.clientX - offset.left + this.$document.scrollLeft,
y: event.clientY - offset.top + this.$document.scrollTop
};
},
getOffset: function(Node, offset) {
if (!offset) {
offset = {};
offset.top = 0;
offset.left = 0;
}
if (Node == document.body) {
return offset;
}
offset.top += Node.offsetTop;
offset.left += Node.offsetLeft;
return this.getOffset(Node.parentNode, offset);
},
startEpicenter: function(event) {
this.axis = this.getAxis(event);
},
moveEpicenter: function(event) {
var axis = this.getAxis(event);
if(!this.axis) {
this.axis = axis;
}
this.generateEpicenter(axis.x, axis.y, axis.y - this.axis.y);
this.axis = axis;
},
generateEpicenter: function(x, y, velocity) {
if(y < this.height / 2 - this.THRESHOLD || y > this.height / 2 + this.THRESHOLD) {
return;
}
var index = Math.round(x / this.pointInterval);
if(index < 0 || index >= this.points.length) {
return;
}
this.points[index].interfere(y, velocity);
},
reverseVertical: function() {
this.reverse = !this.reverse;
for(var i = 0, count = this.fishes.length; i < count; i++) {
this.fishes[i].reverseVertical();
}
},
controlStatus: function() {
for(var i = 0, count = this.points.length; i < count; i++) {
this.points[i].updateSelf();
}
for(var i = 0, count = this.points.length; i < count; i++) {
this.points[i].updateNeighbors();
}
if(this.fishes.length < this.fishCount) {
if(--this.intervalCount == 0) {
this.intervalCount = this.MAX_INTERVAL_COUNT;
this.fishes.push(new FISH(this));
}
}
},
render: function() {
requestAnimationFrame(this.render);
this.controlStatus();
this.context.clearRect(0, 0, this.width, this.height);
this.context.fillStyle = config.fishColor;
for(var i = 0, count = this.fishes.length; i < count; i++) {
this.fishes[i].render(this.context);
}
this.context.save();
this.context.globalCompositeOperation = 'xor';
this.context.beginPath();
this.context.moveTo(0, this.reverse ? 0 : this.height);
for(var i = 0, count = this.points.length; i < count; i++) {
this.points[i].render(this.context);
}
this.context.lineTo(this.width, this.reverse ? 0 : this.height);
this.context.closePath();
this.context.fill();
this.context.restore();
}
};
// 初始化函数
function initFishBackground() {
const addFishBackground = (wallpaperDiv) => {
if (!wallpaperDiv || wallpaperDiv.querySelector('.fishcontainer')) {
return;
}
var newDiv = document.createElement("div");
Object.assign(newDiv, {
id: "jsi-flying-fish-container",
className: "fishcontainer"
});
Object.assign(newDiv.style, {
width: "100vw",
height: "200px",
position: "fixed",
zIndex: "0",
opacity: config.opacity.toString(),
bottom: "0",
left: "0",
right: "0",
overflow: "hidden"
});
wallpaperDiv.appendChild(newDiv);
RENDERER.init();
// 标记鱼群背景初始化完成
if (window.initStatus) {
window.initStatus.fishBackgroundReady = true;
if (typeof window.checkInit === 'function') {
window.checkInit();
}
}
};
// 监视DOM变化
const fishObserver = new MutationObserver(() => {
const wallpaperDiv = document.querySelector('.cover.wallpaper');
addFishBackground(wallpaperDiv);
});
fishObserver.observe(document.body, { childList: true, subtree: true });
// 初始检查
const wallpaperDiv = document.querySelector('.cover.wallpaper');
addFishBackground(wallpaperDiv);
}
// 返回公共接口
return {
init: initFishBackground,
RENDERER: RENDERER,
SURFACE_POINT: SURFACE_POINT,
FISH: FISH,
updateConfig: function(newConfig) {
Object.assign(config, newConfig);
// 更新渲染器参数
RENDERER.FISH_COUNT = config.fishCount;
RENDERER.INIT_HEIGHT_RATE = config.heightRate;
// 如果已经初始化了,更新容器样式
const container = document.querySelector('.fishcontainer');
if (container) {
container.style.opacity = config.opacity.toString();
}
}
};
})();
// 启动初始化
window.SunPanelFish.init();
// ====================== 鱼群动画系统 结束 ======================
/* Sun-Panel-Helper JS End: fish-animation */
CSS代码
/* mouse-cursor */
body {
cursor: url(https://img.hi-linux.com/staticfile/P1i7yA-2024-04-26-hZZjUZ.png) 0 0, default !important;
}
.cursor-pointer,
a:hover,
button:hover,
.clickable:hover {
cursor: url(https://img.hi-linux.com/staticfile/hVX0Sf-2024-04-26-INwMSQ.png) 0 0, pointer !important;
}
/* mouse-cursor end */
/* 背景线条样式 BY 香水 [二群大佬提供] */
/* 伪元素创建背景线条样式 */
.w-full .font-semibold:before {
position: absolute;
/* 设置为绝对定位 */
width: 93px;
/* 宽度为93像素 */
display: block;
/* 设置为块级元素 */
height: 75px;
/* 高度为75像素 */
content: "";
/* 伪元素内容为空 */
border-radius: 50%;
/* 边框半径为50%,形成圆形 */
z-index: -1;
/* 设置层级为-1,将其放在内容之后 */
right: -27px;
/* 距离右边-27像素的位置 */
top: -35px;
/* 距离顶部-35像素的位置 */
background: #ffffff3b;
/* 背景颜色为淡白色带透明度的3b */
box-shadow: -8px 21px 0 #ffffff1a;
/* 设置阴影效果,水平偏移-8px,垂直偏移21px,颜色为淡白色带透明度的1a */
}
/* 设置图标信息框的圆角样式 */
.icon-info-box .rounded-2xl {
position: relative;
/* 设置为相对定位 */
border-radius: 15px;
/* 设置边框半径为15像素,形成圆角 */
overflow: hidden;
/* 超出部分隐藏 */
-webkit-backdrop-filter: blur(10px);
/* 使用Webkit前缀的背景滤镜,模糊程度为10像素 */
backdrop-filter: blur(10px);
/* 背景滤镜,模糊程度为10像素 */
}
/* 伪元素创建另一种背景线条样式 小圆环
.w-full .font-semibold:after {
content: "";
position: absolute;
width: 40px;
height: 40px;
border: 4px solid rgba(235, 236, 227, 0.26);
border-radius: 70%;
z-index: -1;
top: -19px;
right: 48px;
pointer-events: none;
}
*/
/*鼠标悬停动画 */
/* 当鼠标悬停在图标信息框上时触发动画 */
.icon-info-box .rounded-2xl:hover {
background: rgba(183, 238, 66, 0.9) !important;