侧边栏壁纸
博主头像
与末

永远相信美好的事情即将发生

  • 累计撰写 4 篇文章
  • 累计创建 9 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

Sun-Panel YM-NAV 自定义css js 源码思路

与末
2024-01-27 / 6 评论 / 42 点赞 / 4,896 阅读 / 4,481 字

此文章美化已经和我目前的美化部分差别过多

但是此教程写的功能和样式都还有效
如果你需要最新的美化效果
或是自己是小白不会弄,看不懂教程怎么办
可以前往最新的美化定制文档查看!
可以付费提供美化,定制功能!
价格实惠,童叟无欺!
点击立即前往 YM Sun-panel 搭建 美化 定制

注意!!!

更新完不生效请 ctrl+F5 强制刷新浏览器!!!

如还不生效请请F12检查文件是否被加载!!!

出现样式问题请先删除自定义css后再检查!!!

CSS相关

导航页展示:YM-NAV

BK-ym-nav-1.png

自定义css js :官方文档

可以参考不建议完全复制

动态背景

背景是GIF格式加载的动态壁纸
想要高清流畅的动态壁纸靠GIF实现不太现实
高清流畅的GIF文件很吃存储,会影响加载速度与运行流畅度
我的GIF文件大小都在30mb-100mb
时长都在20s以内
分辨率 640x360 20帧
带上一点模糊效果就不会显得GIF分辨率低
SP:这算是最后的妥协了

现在可以直接使用mp4文件加载动态壁纸了!!!

直接跳转至MP4动态视频背景

随机背景

我的随机背景api是用php搭建的
你们也可以在背景设置区域写上别的随机背景的api

这里我提供一个我自己搭建的图片API聚合站点供你们使用YM-API

随机背景php代码

这里提供的是随机背景php源代码
是给各位有服务器有能力自行搭建的人提供源码的
如没有服务器请略过此内容

随机图片

php文件和图片文件需要在同级目录
这个代码图片只支持jpg格式
文件命名方式是1.jpg,2.jpg,3.jpg

<?php
# 随机图片名称 取得值1-30之间的随机数
$img = rand(1, 30) . '.jpg';
# 拼凑,完整的图片地址
$URI = 'http://这里填上你的随机背景链接' . $img;

# 302 Found 转向,并添加随机参数
header("HTTP/1.1 302 Found");
header("Location: $URI?rand=" . uniqid());
exit();
?>

随机GIF

php文件和GIF文件需要在同级目录
这个代码只支持GIF格式
文件命名方式是1.gif,2.gif,3.gif

<?php
# 随机gif名称 取得值1-9之间的随机数
$gif =  rand(1, 9) . '.gif';
# 拼凑,完整的gif地址
$URI = 'hhttp://这里填上你的随机背景链接' . $gif;

# 302 Found 转向,并添加随机参数
header("HTTP/1.1 302 Found");
header("Location: $URI?rand=" . uniqid());
exit();
?>

自定义字体

定义字体名MC (虽然字体出处不是MC)
用*直接全局替换字体
字体出自游戏:主播女孩重度依赖
如字体文件不生效,请确保路径文件正确或字体可以正常使用。
建议先用我这提供的字体进行测试再使用自定义字体!
附件:字体文件下载

/* 自定义字体 */
@font-face {
  font-family: "MC";
  src: url("/custom/DinkieBitmap-9px.ttf");
}

/* 自定义全局字体 */
* {
  font-family: MC;
}

自定义光标

用body定义默认鼠标样式
.cursor-pointer定义悬浮鼠标样式
(这应该是个笨办法,但是我尽力了,我尝试了很多办法只有这个生效了)
光标由Custom-Cursor提供

/* 定义新光标样式 */
body {
  cursor: url(https://cdn.custom-cursor.com/db/4828/32/arrow2747.png), default !important;
}

/* 自定义悬浮光标 */
.cursor-pointer {
  cursor: url(https://cdn.custom-cursor.com/db/4827/32/arrow2747.png), auto !important;
}

自定义footer

这个页脚是为了我自己的页面定制的
给网页计时器稍微排了一下
也给播放器歌词预留了空间

/* 自定义footer */
.footer {
  color: #ffffff;  /* 文字颜色设置为白色 */
  position: fixed;  /* 设置定位为固定位置 */
  left: 50%;  /* 距离左边50%的位置 */
  transform: translateX(-50%);  /* 通过transform属性水平居中 */
  bottom: 40px;  /* 距离底部40像素的位置 */
  width: 100%;  /* 宽度100% */
  height: auto;  /* 高度自动调整 */
  min-height: 50px;  /* 最小高度为50像素 */
  z-index: 9999;  /* 设置层级为9999 */
  display: flex;  /* 使用弹性盒子布局 */
  justify-content: center;  /* 在主轴上居中对齐 */
  align-items: center;  /* 在交叉轴上居中对齐 */
  flex-direction: column;  /* 设置主轴为垂直方向,使子元素纵向排列 */
  line-height: 1.8;  /* 行高为1.8倍 */
  pointer-events: none;  /* 不接受鼠标事件 */
}

背景线条样式

代码由Sun-Panel 交流2群 香水 提供


/* 背景线条样式 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 */
}

/* 伪元素创建另一种背景线条样式 */
.w-full .font-semibold:after {
  position: absolute;  /* 设置为绝对定位 */
  width: 40px;  /* 宽度为40像素 */
  display: block;  /* 设置为块级元素 */
  height: 40px;  /* 高度为40像素 */
  border: 4px solid #ffffff3b;  /* 边框为4像素的实线,颜色为淡白色带透明度的3b */
  content: "";  /* 伪元素内容为空 */
  border-radius: 50%;  /* 边框半径为50%,形成圆形 */
  top: -19px;  /* 距离顶部-19像素的位置 */
  right: 48px;  /* 距离右边48像素的位置 */
  z-index: -1;  /* 设置层级为-1,将其放在内容之后 */
}

/* 设置图标信息框的圆角样式 */
.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像素 */
}

鼠标悬停动画

鼠标悬停时图标摇晃并且颜色变深
这段代码已经适配了详细图标和小图标
他们的摇晃程度都不一样


/*鼠标悬停动画 */

/* 当鼠标悬停在图标信息框上时触发动画 */
/* 详细图标摇晃动画 */
.icon-info-box .rounded-2xl:hover {
  background: rgba(42, 42, 42, 0.7) !important;/* 背景颜色变成深灰色 */
  -webkit-animation: info-shake-bounce .5s alternate !important;
  -moz-animation: info-shake-bounce .5s alternate !important;
  -o-animation: info-shake-bounce .5s alternate !important;
  animation: info-shake-bounce .5s alternate !important;
}

/* 小图标摇晃动画 */
.icon-small-box .rounded-2xl:hover {
  background: rgba(42, 42, 42, 0.7) !important;/* 背景颜色变成深灰色 */
  -webkit-animation: small-shake-bounce .5s alternate !important;
  -moz-animation: small-shake-bounce .5s alternate !important;
  -o-animation: small-shake-bounce .5s alternate !important;
  animation: small-shake-bounce .5s alternate !important;
}

/* 定义摇详细图标晃弹跳动画的关键帧 */
@keyframes info-shake-bounce {

  0%,
  100% {
    transform: rotate(0);
  }

  25% {
    transform: rotate(10deg);
  }

  50% {
    transform: rotate(-10deg);
  }

  75% {
    transform: rotate(2.5deg);
  }

  85% {
    transform: rotate(-2.5deg);
  }
}

/* 定义摇小图标晃弹跳动画的关键帧 */
@keyframes small-shake-bounce {

  0%,
  100% {
    transform: rotate(0);
  }

  25% {
    transform: rotate(15deg);
  }

  50% {
    transform: rotate(-15deg);
  }

  75% {
    transform: rotate(5deg);
  }

  85% {
    transform: rotate(5deg);
  }
}

JS 相关

多js加载

用于加载多个js文件
加载多js应该还有很多办法
我这不是唯一办法,你们也可以自行发挥
用的js文件很少的话可以略过多js加载

// 定义函数 loadMultipleResources,用于加载多个资源
function loadMultipleResources(resources, callback) {
  var loadedCount = 0;  // 已加载的资源计数

  // 定义内部函数 loadResource,用于加载单个资源
  function loadResource(resource, index) {
    var element;

    if (resource.endsWith('.js')) {
      // 如果资源是 JavaScript 文件
      element = document.createElement('script');  // 创建 script 元素
      element.src = resource;  // 设置 script 元素的 src 属性为资源路径
      element.onload = function () {
        loadedCount++;  // 每次资源加载完成时增加计数
        if (loadedCount === resources.length) {
          // 如果所有文件都已加载完成,则执行回调函数
          callback();
        }
      };
    }

    document.head.appendChild(element);  // 将创建的 script 元素添加到文档头部
  }

  // 遍历资源数组,逐个加载资源
  for (var i = 0; i < resources.length; i++) {
    loadResource(resources[i], i);
  }
}

// 定义一个包含多个资源路径的数组
var resources = [
  // jquery库
  'https://myhkw.cn/player/js/jquery.min.js',
  // 也可以使用本地jquery库
  //'./custom/jquery.min.js',
   // mp4动态背景
  './custom/Random video bg.js',
  // 页面雪花特效
  './custom/Snowflakes.js',
  // 鼠标点击特效
  './custom/Mouse.js',
  // 音乐播放器
  './custom/Music player.js',
  // 网页计时器
  './custom/Sitetime.js',
];

// 调用 loadMultipleResources 函数,传入资源数组和回调函数
loadMultipleResources(resources, function () {
  // 所有资源加载完成后执行的回调函数
  console.log('所有资源已加载');
});

MP4动态视频背景

使用js实现的动态视频背景,由一群 jackloves111 提供

document.addEventListener('DOMContentLoaded', (event) => {  
    // 用于添加视频背景的函数  
    const addVideoBackground = (wallpaperDiv) => {  
        // 创建video元素  
        const video = document.createElement('video');  
  
        // 设置视频属性  
        video.autoplay = true; // 使用属性而不是setAttribute,因为autoplay是一个布尔属性  
        video.loop = true;  
        video.muted = true;  
        video.playsInline = true; // 注意这里是驼峰式写法,但在HTML中应使用playsinline  
  
        // 应用CSS样式到video元素  
        video.style.position = 'absolute';  
        video.style.top = '0';  
        video.style.left = '0';  
        video.style.width = '100%';  
        video.style.height = '100%';  
        video.style.objectFit = 'cover';  
  
        // 定义多个视频源  
        const videoSources = [  
            '/uploads/%E5%8A%A8%E6%80%81%E5%A3%81%E7%BA%B8-01.mp4',  
            '/uploads/%E5%8A%A8%E6%80%81%E5%A3%81%E7%BA%B8-02.mp4',
            '/uploads/%E5%8A%A8%E6%80%81%E5%A3%81%E7%BA%B8-03.mp4',
            '/uploads/%E5%8A%A8%E6%80%81%E5%A3%81%E7%BA%B8-04.mp4',
            '/uploads/%E5%8A%A8%E6%80%81%E5%A3%81%E7%BA%B8-05.mp4',
            // '/uploads/%E5%8A%A8%E6%80%81%E5%A3%81%E7%BA%B8-06.mp4',
            // '/uploads/%E5%8A%A8%E6%80%81%E5%A3%81%E7%BA%B8-07.mp4',
            // '/uploads/%E5%8A%A8%E6%80%81%E5%A3%81%E7%BA%B8-08.mp4',
            // '/uploads/%E5%8A%A8%E6%80%81%E5%A3%81%E7%BA%B8-09.mp4'
            // 在这里可以添加更多的视频源  
        ];  
  
        // 从视频源数组中随机选择一个  
        const randomSource = videoSources[Math.floor(Math.random() * videoSources.length)];  
  
        // 创建source元素并设置随机选择的视频源  
        const source = document.createElement('source');  
        source.src = randomSource;  
        source.type = 'video/mp4';  
  
        // 将source元素添加到video元素中  
        video.appendChild(source);  
  
        // 监听视频加载元数据事件,尝试播放视频  
        video.addEventListener('loadedmetadata', () => {  
            video.play().catch((error) => {  
                // 如果播放失败,可以在这里处理错误,例如显示一个备用图片或消息  
                console.error('视频播放失败:', error);  
            });  
        });  
  
        // 将video元素添加到指定的wallpaperDiv中  
        wallpaperDiv.appendChild(video);  
    };  
  
    // 使用MutationObserver监视DOM变化  
    const observer = new MutationObserver((mutationsList, observer) => {  
        // 查找匹配的.cover.wallpaper元素  
        const wallpaperDiv = document.querySelector('.cover.wallpaper');  
  
        if (wallpaperDiv && !wallpaperDiv.querySelector('video')) {  
            // 添加视频背景  
            addVideoBackground(wallpaperDiv);  
            // 注意:我们不再断开观察者,以便它能够继续监视未来的变化  
        }  
    });  
  
    // 启动观察者监视document.body的变化  
    observer.observe(document.body, { childList: true, subtree: true });  
});

页面雪花特效

不建议雪花生成毫秒数低于100
可能会对移动端或老旧设备造成卡顿

function snow() {
    //  1、定义一片雪花模板
    var flake = document.createElement('div');
    // 定义雪花字符 ❄❉❅❆✻✼❇❈❊✥✺
    flake.innerHTML = '❄';
    flake.style.cssText = 'position:absolute;color:#fff;';

    //获取页面的高度 相当于雪花下落结束时Y轴的位置
    var documentHieght = window.innerHeight;
    //获取页面的宽度,利用这个数来算出,雪花开始时left的值
    var documentWidth = window.innerWidth;

    //定义生成一片雪花的毫秒数,不建议低于100
    var millisec =200;
    //2、设置第一个定时器,周期性定时器,每隔一段时间(millisec)生成一片雪花;
    setInterval(function() { //页面加载之后,定时器就开始工作
        //随机生成雪花下落 开始 时left的值,相当于开始时X轴的位置
        var startLeft = Math.random() * documentWidth;

        //随机生成雪花下落 结束 时left的值,相当于结束时X轴的位置
        var endLeft = Math.random() * documentWidth;

        //随机生成雪花大小
        var flakeSize = 3 + 20 * Math.random();

        //随机生成雪花下落持续时间,时间越大下落越慢
        var durationTime = 6000 + 10000 * Math.random();

        //随机生成雪花下落 开始 时的透明度
        var startOpacity = 0.7 + 0.3 * Math.random();

        //随机生成雪花下落 结束 时的透明度
        var endOpacity = 0.2 + 0.2 * Math.random();

        //克隆一个雪花模板
        var cloneFlake = flake.cloneNode(true);

        //第一次修改样式,定义克隆出来的雪花的样式
        cloneFlake.style.cssText += `
                left: ${startLeft}px;
                opacity: ${startOpacity};
                font-size:${flakeSize}px;
                top:-25px;
                    transition:${durationTime}ms;`;

        //拼接到页面中
        document.body.appendChild(cloneFlake);

        //设置第二个定时器,一次性定时器,
        //当第一个定时器生成雪花,并在页面上渲染出来后,修改雪花的样式,让雪花动起来;
        setTimeout(function() {
            //第二次修改样式
            cloneFlake.style.cssText += `
                        left: ${endLeft}px;
                        top:${documentHieght}px;
                        opacity:${endOpacity};`;

            //4、设置第三个定时器,当雪花落下后,删除雪花。
            setTimeout(function() {
                cloneFlake.remove();
            }, durationTime);
        }, 0);

    }, millisec);
}
snow();

// 点击特效
点击特效是出自我的与末的个人引导页

class Circle {
    constructor({ origin, speed, color, angle, context }) {
        this.origin = origin; // 初始位置
        this.position = { ...this.origin }; // 当前位置
        this.color = color; // 颜色
        this.speed = speed; // 速度
        this.angle = angle; // 角度
        this.context = context; // 绘制上下文
        this.renderCount = 0; // 渲染计数
    }

    draw() {
        // 绘制圆形
        this.context.fillStyle = this.color;
        this.context.beginPath();
        this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2);
        this.context.fill();
    }

    move() {
        // 移动圆形
        this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x;
        this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3);
        this.renderCount++;
    }
}

class Boom {
    constructor({ origin, context, circleCount = 10, area }) {
        this.origin = origin; // 初始位置
        this.context = context; // 绘制上下文
        this.circleCount = circleCount; // 圆形数量
        this.area = area; // 区域
        this.stop = false; // 停止标志
        this.circles = []; // 圆形数组
    }

    randomArray(range) {
        // 从数组中随机取值
        const length = range.length;
        const randomIndex = Math.floor(length * Math.random());
        return range[randomIndex];
    }

    randomColor() {
        // 随机生成颜色
        const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
        return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range);
    }

    randomRange(start, end) {
        // 在范围内生成随机数
        return (end - start) * Math.random() + start;
    }

    init() {
        // 初始化Boom对象
        for (let i = 0; i < this.circleCount; i++) {
            const circle = new Circle({
                context: this.context,
                origin: this.origin,
                color: this.randomColor(),
                angle: this.randomRange(Math.PI - 1, Math.PI + 1),
                speed: this.randomRange(1, 6)
            });
            this.circles.push(circle);
        }
    }

    move() {
        // 移动所有圆形,并检测是否超出区域
        this.circles.forEach((circle, index) => {
            if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
                return this.circles.splice(index, 1);
            }
            circle.move();
        });
        if (this.circles.length === 0) {
            this.stop = true;
        }
    }

    draw() {
        // 绘制所有圆形
        this.circles.forEach(circle => circle.draw());
    }
}

class CursorSpecialEffects {
    constructor() {
        // 鼠标特效主类
        this.computerCanvas = document.createElement('canvas'); // 计算用Canvas
        this.renderCanvas = document.createElement('canvas'); // 渲染用Canvas

        this.computerContext = this.computerCanvas.getContext('2d'); // 计算用上下文
        this.renderContext = this.renderCanvas.getContext('2d'); // 渲染用上下文

        this.globalWidth = window.innerWidth; // 全局宽度
        this.globalHeight = window.innerHeight; // 全局高度

        this.booms = []; // Boom对象数组
        this.running = false; // 运行标志
    }

    handleMouseDown(e) {
        // 处理鼠标点击事件
        const boom = new Boom({
            origin: { x: e.clientX, y: e.clientY },
            context: this.computerContext,
            area: {
                width: this.globalWidth,
                height: this.globalHeight
            }
        });
        boom.init();
        this.booms.push(boom);
        this.running || this.run();
    }

    handlePageHide() {
        // 处理页面隐藏事件
        this.booms = [];
        this.running = false;
    }

    init() {
        // 初始化方法
        const style = this.renderCanvas.style;
        style.position = 'fixed';
        style.top = style.left = 0;
        style.zIndex = '999999999999999999999999999999999999999999';
        style.pointerEvents = 'none';

        style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth;
        style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight;

        document.body.append(this.renderCanvas);

        window.addEventListener('mousedown', this.handleMouseDown.bind(this));
        window.addEventListener('pagehide', this.handlePageHide.bind(this));
    }

    run() {
        // 运行方法
        this.running = true;
        if (this.booms.length === 0) {
            return this.running = false;
        }

        requestAnimationFrame(this.run.bind(this));

        this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight);
        this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight);

        this.booms.forEach((boom, index) => {
            if (boom.stop) {
                return this.booms.splice(index, 1);
            }
            boom.move();
            boom.draw();
        });
        this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight);
    }
}

const cursorSpecialEffects = new CursorSpecialEffects();
cursorSpecialEffects.init();

音乐播放器

播放器详见明月浩空网
这是一个专注于html音乐播放器10年的网站,基础功能都是免费!
或者前往自定义播放器高级功能查看

网页计时器

依然出自我的与末的个人引导页
展示此内容需要在Sun-Panel自定义页脚加上此代码

<span id="sitetime"></span>
function siteTime() {
  window.setTimeout(siteTime, 1000);

  var seconds = 1000;
  var minutes = seconds * 60;
  var hours = minutes * 60;
  var days = hours * 24;
  var years = days * 365;

  var targetDate = new Date(2023, 11, 18); // 注意月份是从0开始的,所以11表示12月
  var today = new Date();
  var diff = today - targetDate;

  // 计算已运行的年数
  var totalYears = Math.floor(diff / years);

  // 计算剩余时间
  var remainingTime = diff % years;

  var diffDays = Math.floor(remainingTime / days);
  remainingTime %= days;

  var diffHours = Math.floor(remainingTime / hours);
  remainingTime %= hours;

  var diffMinutes = Math.floor(remainingTime / minutes);
  remainingTime %= minutes;

  var diffSeconds = Math.floor(remainingTime / seconds);

  document.getElementById("sitetime").innerHTML = "网页已运营 " + totalYears + " 年 " + diffDays + " 天 " + diffHours + " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
}

siteTime();

结尾

目前暂时也就更新了这一些东西,这些都是我目前正在使用的功能以及样式

还是开头那句话,可以参考不建议完全复制,毕竟每个人的需求都是不一样的

注释我也都完全打上了,还有不懂或者不理解的地方可以QQ咨询我

如果你有好的想法或者代码,也可以分享出来,非常欢迎!

42

评论区