// 加载脚本函数
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;
End
最后修改:2025 年 02 月 09 日
如果觉得我的文章对你有用,请随意赞赏