CNBlogs SimpleMemory Theme Customization with Live2D, Audio Player, and Canvas Animations

Prerequisites

Enable JavaScript permissions for your CNBlogs account. Submit a request to the administrators justifying the need, such as implementing image zoom capabilities or enhancing code block aesthetics.

Styling Configuration

Access the CSS file at https://blog-static.cnblogs.com/files/blogs/690708/css.txt.css. Copy the entire content using keyboard shortcuts (Ctrl+A) to avoid missing any styles. Navigate to the CNBlogs settings dashboard, locate the custom CSS section, and paste the copied styles. Ensure the "Disable Template CSS" option is activated before saving.

Sidebar Customization

Insert the following code into the Blog Sidebar Announcement field. Update the configuration object parameters to reflect your personal details.

<script type="text/javascript">
    window.cnblogsConfig = {
        GhVersions    : 'v1.3.3',
        blogUser      : "your_username",
        blogAvatar    : "https://your-avatar-url.jpg",
        blogStartDate : "2021-6-17",
    }
</script>
<script src="https://blog-static.cnblogs.com/files/blogs/665069/simpleMemory.min.js" defer></script>

<script src="https://eqcn.ajz.miesnfu.com/wp-content/plugins/wp-3d-pony/live2dw/lib/L2Dwidget.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://blog-static.cnblogs.com/files/blogs/690708/waifu1.css"/>
<link rel="stylesheet" type="text/css" href="https://files.cnblogs.com/files/yjlblog/flat-ui.min.css"/>

<script type="text/javascript">
    const mascotWrapper = document.createElement('div');
    mascotWrapper.id = 'waifu';
    mascotWrapper.className = 'waifu';
    mascotWrapper.innerHTML = `
        <div class="waifu-tips" style="opacity: 1;"></div>
        <canvas id="live2d" width="280" height="250" class="live2d"></canvas>
        <div class="waifu-tool">
            <span class="fui-home"></span>
            <span class="fui-chat"></span>
            <span class="fui-eye"></span>
            <span class="fui-user"></span>
            <span class="fui-photo"></span>
            <span class="fui-info-circle"></span>
            <span class="fui-cross"></span>
        </div>
    `;
    document.body.appendChild(mascotWrapper);
    initModel();
</script>
<script src="https://blog-static.cnblogs.com/files/clwydjgs/live2d.js"></script>
<script src="https://blog-static.cnblogs.com/files/clwydjgs/waifu-tips.js"></script>

Page Header Configuration

Add the dynamic particle network background script to the Header HTML section.

<script>
(function() {
    const getAttr = (el, attr, fallback) => el.getAttribute(attr) || fallback;
    const fetchScriptConfig = () => {
        const scriptTags = document.getElementsByTagName("script");
        const lastScript = scriptTags[scriptTags.length - 1];
        return {
            idx: scriptTags.length,
            depth: getAttr(lastScript, "zIndex", -1),
            visibility: getAttr(lastScript, "opacity", 0.5),
            rgbColor: getAttr(lastScript, "color", "0,0,0"),
            particleTotal: getAttr(lastScript, "count", 99)
        };
    };

    const resizeCanvas = () => {
        canvasWidth = canvasEl.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
        canvasHeight = canvasEl.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    };

    const drawParticles = () => {
        ctx.clearRect(0, 0, canvasWidth, canvasHeight);
        let distX, distY, distanceSq;
        
        particles.forEach((p, i) => {
            p.x += p.vx;
            p.y += p.vy;
            p.vx *= (p.x > canvasWidth || p.x < 0) ? -1 : 1;
            p.vy *= (p.y > canvasHeight || p.y < 0) ? -1 : 1;
            ctx.fillRect(p.x - 0.5, p.y - 0.5, 1, 1);

            for (let j = i + 1; j < allPoints.length; j++) {
                const p2 = allPoints[j];
                if (p2.x !== null && p2.y !== null) {
                    distX = p.x - p2.x;
                    distY = p.y - p2.y;
                    distanceSq = distX * distX + distY * distY;
                    
                    if (distanceSq < p2.maxDist) {
                        if (p2 === mousePointer && distanceSq >= p2.maxDist / 2) {
                            p.x -= 0.03 * distX;
                            p.y -= 0.03 * distY;
                        }
                        const ratio = (p2.maxDist - distanceSq) / p2.maxDist;
                        ctx.beginPath();
                        ctx.lineWidth = ratio / 2;
                        ctx.strokeStyle = `rgba(${config.rgbColor},${ratio + 0.2})`;
                        ctx.moveTo(p.x, p.y);
                        ctx.lineTo(p2.x, p2.y);
                        ctx.stroke();
                    }
                }
            }
        });
        animFrame(drawParticles);
    };

    let canvasWidth, canvasHeight, allPoints;
    const canvasEl = document.createElement("canvas");
    const config = fetchScriptConfig();
    const ctx = canvasEl.getContext("2d");
    const animFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || ((cb) => window.setTimeout(cb, 1000 / 45));
    const mousePointer = { x: null, y: null, maxDist: 20000 };

    canvasEl.id = `particle_bg_${config.idx}`;
    canvasEl.style.cssText = `position:fixed;top:0;left:0;z-index:${config.depth};opacity:${config.visibility}`;
    document.body.appendChild(canvasEl);
    resizeCanvas();
    
    window.onresize = resizeCanvas;
    window.onmousemove = (e) => {
        e = e || window.event;
        mousePointer.x = e.clientX;
        mousePointer.y = e.clientY;
    };
    window.onmouseout = () => {
        mousePointer.x = null;
        mousePointer.y = null;
    };

    const particles = [];
    for (let k = 0; k < config.particleTotal; k++) {
        particles.push({ 
            x: Math.random() * canvasWidth, 
            y: Math.random() * canvasHeight, 
            vx: 2 * Math.random() - 1, 
            vy: 2 * Math.random() - 1, 
            maxDist: 6000 
        });
    }

    allPoints = particles.concat([mousePointer]);
    setTimeout(() => drawParticles(), 100);
})();
</script>

Page Footer Configuration

Implement the swimming fish animation and the background audio player in the Footer HTML section.

<div id="jsi-flying-fish-container" class="container"></div>
<script src="https://blog-static.cnblogs.com/files/elkyo/fish.js"></script>
<style>
@media only screen and (max-width: 767px) {
    #sidebar_search_box input[type=text] { width: calc(100% - 24px); }
}
</style>

<canvas width="1777" height="841" style="position: fixed; left: 0px; top: 0px; z-index: 2147483647; pointer-events: none;"></canvas>
<script src="https://blog-static.cnblogs.com/files/elkyo/mouse-click.js"></script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer@1.10.0/dist/APlayer.min.css">
<script src="https://blog-static.cnblogs.com/files/yjlaugus/APlayer.min.js"></script>
<div id="audio-player-el" class="aplayer" 
     data-id="6828041575" 
     data-server="netease" 
     data-type="playlist" 
     data-fixed="true" 
     data-listfolded="true" 
     data-order="random" 
     data-theme="#F58EA8">
</div>
<script src="https://unpkg.com/meting@1.2/dist/Meting.min.js"></script>

Tags: CnBlogs Theme Customization Live2D javascript css

Posted on Sat, 06 Jun 2026 18:11:47 +0000 by amwd07