此处为全站公告,通常对读者进行申明或对该WIKI某些规则进行公告,请在确认后修改本通告。本WIKI编辑权限开放,欢迎收藏起来防止迷路,也希望有爱的小伙伴和我们一起编辑哟~

全站通知:

用户:7709386/StellaSoraCursor.js

来自星塔旅人WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Internet Explorer或Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
  • Opera:Ctrl-F5
$(() => {
    (window.RLQ = window.RLQ || []).push(() => {
        // 配置鼠标触摸效果列表
        const CURSOR_TOUCH_EFFECT_LIST = [
            { name: "默认", key: "default", value: "某月某日" },
            { name: "圣诞", key: "christmas", value: "12月25日" }
        ]

        // 生成随机元素的数量
        const RANDOM_ELEMENT_COUNT = 5;
        // 当鼠标按下多少延迟后执行鼠标移动事件 ms
        const HOLD_MOUSE_DOWN_DELAY = 100;
        // 鼠标移动事件节流阀延迟 ms
        const THROTTLE_DELAY = 10;
        // 鼠标按下时添加随机元素的延迟 ms 
        const RANDOM_ELEMENT_DELAY = 100;
        // Timer: 鼠标按下计时器 用于延迟触发move事件
        let triggerMouseMoveEventTimer = null;
        // Timer: 添加随机元素计时器 用于控制鼠标按下时添加的随机元素
        let addHoldRandomElementTimer = null;
        // Timer: 鼠标移动中的节流阀计时器 用于控制鼠标移动中的拖尾效果
        let throttleTimer = null;
        // 记录按下鼠标时该点的位置信息 用于控制按下时随机添加元素的位置
        let holdELementPos = { x: 0, y: 0 };
        // 记录鼠标按下不松时处于移动中的经过节流的事件处理函数
        let holdMovingThrottleHandler = null;
        // 模板中设置的点击效果根节点 模板默认加载 default 效果 其他效果另加css
        let rootTouchEffectElement = null;
        let isMouseDown = false;

        // 将中文日期格式转换为 Date 对象
        const parseChineseDate = (dateStr) => {
            const [month, day] = dateStr.split("月").map(part =>
                parseInt(part.replace("日", ""))
            );
            return new Date(new Date().getFullYear(), month - 1, day);
        }

        // 获取当前鼠标触摸效果的key 对应css的类名 用于切换不同的效果
        const getCurrentTouchEffectKey = (data) => {
            const now = new Date();

            for (const item of data) {
                try {
                    const targetDate = parseChineseDate(item.value);
                    const endDate = new Date(targetDate);
                    // 特殊日期触发的鼠标效果延迟 7 天
                    endDate.setDate(targetDate.getDate() + 7);

                    if (now >= targetDate && now < endDate) {
                        return item.key
                    }
                } catch (e) {
                    console.warn(`parseChineseDate ${item.value} failed:`, e);
                    return data[0].key;
                }
            }

            return data[0].key;;
        }

        // 设置鼠标触摸效果的页面根节点
        const setRootTouchEffectElement = () => {
            const key = getCurrentTouchEffectKey(CURSOR_TOUCH_EFFECT_LIST);
            rootTouchEffectElement = document.createElement("div");
            rootTouchEffectElement.className = `stellasora-cursor-touch-effect ${key}`
            document.body.prepend(rootTouchEffectElement);
        }
		
		const clearTimer = () => {
            clearInterval(addHoldRandomElementTimer);
		    addHoldRandomElementTimer = null;
		    document.removeEventListener("mousemove", holdMovingThrottleHandler);
		}
		
        // 鼠标按下处理函数 添加点击效果
        let mouseDownHandler = (event) => {
            const touchEffectGroup = document.createElement("div");
            touchEffectGroup.className = "touch-effect-group";

            const touchEffectBackground = document.createElement("div");
            touchEffectBackground.className = "touch-effect-background";

            const touchEffectScaleElement1 = document.createElement("div");
            touchEffectScaleElement1.className = "touch-effect-scale-element-1";

            const touchEffectScaleElement2 = document.createElement("div");
            touchEffectScaleElement2.className = "touch-effect-scale-element-2";
            touchEffectScaleElement2.style.transform = "rotate(" + Math.random() * 360 + "deg)";

            touchEffectGroup.style.left = event.clientX + "px";
            touchEffectGroup.style.top = event.clientY + "px";

            touchEffectGroup.appendChild(touchEffectBackground)
            touchEffectGroup.appendChild(touchEffectScaleElement1)
            touchEffectGroup.appendChild(touchEffectScaleElement2)

            // 添加触发鼠标按下时的随机元素效果
            for (let i = 0; i < RANDOM_ELEMENT_COUNT; i++) {
                const touchEffectRandomElement = document.createElement("div");
                touchEffectRandomElement.className = "touch-effect-random-element";

                const angle = Math.random() * Math.PI * 2;
                const distance = 30 + Math.random() * 100;
                const scale = 0.5 + Math.random();

                const x = Math.round(distance * Math.cos(angle));
                const y = Math.round(distance * Math.sin(angle));

                touchEffectRandomElement.style.left = "50%";
                touchEffectRandomElement.style.top = "50%";
                touchEffectRandomElement.style.backgroundImage = `var(--random-bg-${Math.floor(Math.random() * 4) + 1})`;

                touchEffectRandomElement.style.setProperty("--x", `${x}px`);
                touchEffectRandomElement.style.setProperty("--y", `${y}px`);
                touchEffectRandomElement.style.setProperty("--scale", scale);

                touchEffectRandomElement.style.animationDuration = `${0.5 + Math.random() * 0.5}s`;

                touchEffectGroup.appendChild(touchEffectRandomElement);
            }

            // 添加到模板根节点 延迟销毁
            rootTouchEffectElement.appendChild(touchEffectGroup);
            setTimeout(() => touchEffectGroup.remove(), 1000);
        }

        // 鼠标移动处理函数 添加拖尾效果
        let mouseMoveHandler = (event) => {
            const followElement = document.createElement("div");
            followElement.className = "touch-effect-follow-element";

            followElement.style.left = event.clientX + "px";
            followElement.style.top = event.clientY + "px";

            // 移动事件记录移动后的位置信息 用于控制鼠标按住时新添加的随机元素
            holdELementPos.x = event.clientX;
            holdELementPos.y = event.clientY;

            const rand = Math.floor(Math.random() * 4) + 1;
            followElement.style.backgroundImage = `var(--random-bg-${rand})`;

            const rotate = `rotate(${Math.round(Math.random() * 360)}deg)`;
            followElement.style.setProperty("--follow-rotate", rotate);

            rootTouchEffectElement.appendChild(followElement);
            setTimeout(() => followElement.remove(), 1100);
        }

        const addEventMouseDown = () => {
            document.addEventListener("mousedown", (event) => {
                if (event.button !== 0) return;
				isMouseDown = true;
				
                mouseDownHandler(event);
                
                if (addHoldRandomElementTimer) {
			        clearInterval(addHoldRandomElementTimer);
			    }

                // 当鼠标按下时记录当前位置 用于控制按下时添加的随机元素位置
                holdELementPos.x = event.clientX;
                holdELementPos.y = event.clientY;

                // 鼠标按下时不停的添加随机元素 需要在鼠标抬起后销毁
                addHoldRandomElementTimer = setInterval(() => {
                    for (let i = 0; i < RANDOM_ELEMENT_COUNT; i++) {
                        const holdElement = document.createElement("div");

                        holdElement.className = "touch-effect-hold-element";
                        holdElement.style.left = holdELementPos.x + "px";
                        holdElement.style.top = holdELementPos.y + "px";

                        const bgIdx = Math.floor(Math.random() * 4) + 1;
                        const rotate = Math.random() * 360;
                        const scale = 0.5 + Math.random();

                        holdElement.style.backgroundImage = `var(--random-bg-${bgIdx})`;
                        holdElement.style.transform = `translate(-50%, -50%) scale(${scale}) rotate(${rotate}deg)`;

                        rootTouchEffectElement.appendChild(holdElement);

                        setTimeout(() => holdElement.remove(), RANDOM_ELEMENT_DELAY)
                    }
                }, RANDOM_ELEMENT_DELAY)

                // 当鼠标按下多少延迟后能触发鼠标移动事件处理函数
                triggerMouseMoveEventTimer = setTimeout(() => {
                    // 记录节流处理函数
                    holdMovingThrottleHandler = (event) => {
                        if (throttleTimer) { return; }

                        throttleTimer = setTimeout(() => {
                            throttleTimer = null;
                        }, THROTTLE_DELAY);

                        mouseMoveHandler(event);
                    };
                    // 添加经过节流的鼠标移动处理函数
                    document.addEventListener("mousemove", holdMovingThrottleHandler);
                }, HOLD_MOUSE_DOWN_DELAY);
            });
        }

        const addEventMouseUp = () => {
            document.addEventListener("mouseup", (event) => {
                if (event.button !== 0) return;
                isMouseDown = false;
                clearTimeout(triggerMouseMoveEventTimer);
                clearTimer();
                document.removeEventListener("mousemove", holdMovingThrottleHandler)
            });
        }

        const main = () => {
            setRootTouchEffectElement();
            addEventMouseDown();
            addEventMouseUp();
            
			window.addEventListener("beforeunload", () => {
			    clearTimer();
			});

			document.addEventListener("visibilitychange", () => {
			    if (document.hidden) {
			        clearTimer();
			    }
			});
			
			document.addEventListener("mouseleave", () => {
			    isMouseDown = false;
			    clearTimer();
			});
        }

        main()

    })
})