Weread gamepad control

使用xbox 游戏手柄控制微信读书翻页和滚动

当前为 2024-10-27 提交的版本,查看 最新版本

// ==UserScript==
// @name        Weread gamepad control
// @namespace   Violentmonkey Scripts
// @match       https://weread.qq.com/web/reader/*
// @grant       none
// @version     1.0
// @author      -
// @license     GPL 3.0
// @description 使用xbox 游戏手柄控制微信读书翻页和滚动
// ==/UserScript==

var gamepadAPI = {
    job: 0,

    update: function () {
        // 清除按钮缓存
        gamepadAPI.buttonsCache = [];
        // 从上一帧中移动按钮状态到缓存中
        for (var k = 0; k < gamepadAPI.buttonsStatus.length; k++) {
            gamepadAPI.buttonsCache[k] = gamepadAPI.buttonsStatus[k];
        }
        // 清除按钮状态
        gamepadAPI.buttonsStatus = [];
        // 获取 gamepad 对象
        var c = navigator.getGamepads()[0];

        // 遍历按键,并将按下的按钮加到数组中
        var pressed = [];
        if (c.buttons) {
            for (var b = 0, t = c.buttons.length; b < c.buttons.length; b++) {
                if (c.buttons[b].pressed) {
                    // console.log("buttons pressed " + gamepadAPI.buttons[b])
                    pressed.push(gamepadAPI.buttons[b]);
                }
            }
        }
        // 遍历坐标值并加到数组中
        var axes = [];
        if (c.axes) {
            for (var a = 0, x = c.axes.length; a < x; a++) {
                if (Math.abs(c.axes[a]) > 0.7) {
                    console.log("axes pressed " + gamepadAPI.axes[a])
                }
                axes.push(c.axes[a].toFixed(2));
            }
        }
        // 分配接收到的值
        gamepadAPI.axesStatus = axes;
        gamepadAPI.buttonsStatus = pressed;
        // 返回按钮以便调试
        return pressed;
    },

    buttonPressed: function (button, hold, released) {
        var newPress = false;
        var newRelease = false;

        // 轮询按下的按钮
        for (var i = 0, s = gamepadAPI.buttonsStatus.length; i < s; i++) {
            // 如果我们找到我们想要的按钮
            if (gamepadAPI.buttonsStatus[i] == button) {
                // 设置布尔变量(newPress)为 true
                newPress = true;
                // 如果我们想检查按住还是单次按下
                if (!hold) {
                    // 从上一帧轮询缓存状态
                    for (var j = 0, p = gamepadAPI.buttonsCache.length; j < p; j++) {
                        // 如果按钮(之前)已经被按下了则忽略新的按下状态
                        if (gamepadAPI.buttonsCache[j] == button) {
                            newPress = false;
                        }
                    }
                }
            }
        }

        // 检查是不是放开按钮
        if (released) {
            for (var j = 0, p = gamepadAPI.buttonsCache.length; j < p; j++) {
                if (gamepadAPI.buttonsCache[j] == button) {
                    // 检查当前帧中按钮是否未被按下
                    if (!gamepadAPI.buttonsStatus.includes(button)) {
                        newRelease = true;
                    }
                }
            }
        }

        return { pressed: newPress, released: newRelease };
    },

    buttons: [
        'A', 'B', 'X', 'Y',
        'LB', 'RB', 'LT', 'RT',
        'Option', 'Start',
        'Axis-Left', 'Axis-Right',
        'DPad-Up', 'DPad-Down', 'DPad-Left', 'DPad-Right',
    ],
    axes: [
        'Left H', 'Left V',
        'Right H', 'Right V',
    ],
    buttonsCache: [],
    buttonsStatus: [],
    axesStatus: [],
};

(function () {
    'use strict';
    window.addEventListener("gamepadconnected", (evt) => {
        console.log('控制器已连接。');

        let next = () => document.querySelector(".renderTarget_pager_button_right").click()
        let prev = () => document.querySelector(".renderTarget_pager_button:not(.renderTarget_pager_button_right)").click()

        let keyboard_down_press = () => {
            var event = new KeyboardEvent('keydown', { bubbles: true, cancelable: true, key: "ArrowDown", code: 40 });
            document.dispatchEvent(event);
        }

        let keyboard_down_release = () => {
            var event = new KeyboardEvent('keyup', { bubbles: true, cancelable: true, key: "ArrowDown", code: 40 });
            document.dispatchEvent(event);
        }

        gamepadAPI.job = setInterval(() => {
            gamepadAPI.update()
            // 明确调用 buttonPressed 并传递按钮名称
            if (gamepadAPI.buttonPressed('A').pressed) {
                next()
            }
            // if (gamepadAPI.buttonPressed('A', true).pressed) {
            //     console.log('A 按钮被持续按下');
            // }
            // if (gamepadAPI.buttonPressed('A', false, true).released) {
            //     console.log('A 按钮被放开');
            // }

            if (gamepadAPI.buttonPressed('B').pressed) {
                prev();
            }

            if (gamepadAPI.buttonPressed('DPad-Up').pressed) {
                prev();
            }
            if (gamepadAPI.buttonPressed('DPad-Up', true).pressed) {
                const hasVerticalScrollbar = document.documentElement.scrollHeight > document.documentElement.clientHeight;
                if (hasVerticalScrollbar) {
                    window.scrollTo({
                        //60 fps
                        top: window.scrollY - (300 / 60),
                        behavior: 'instant'
                    });
                }
            }
            if (gamepadAPI.buttonPressed('DPad-Down').pressed) {
                next();
            }
            if (gamepadAPI.buttonPressed('DPad-Down', true).pressed) {
                const hasVerticalScrollbar = document.documentElement.scrollHeight > document.documentElement.clientHeight;
                if (hasVerticalScrollbar) {
                    window.scrollTo({
                        //60 fps
                        top: window.scrollY + (300 / 60),
                        behavior: 'instant'
                    });
                }
            }
            if (gamepadAPI.buttonPressed('DPad-Left').pressed) {
                prev();
            }
            if (gamepadAPI.buttonPressed('DPad-Right').pressed) {
                next();
            }
        }, 16)
    });

    window.addEventListener("gamepaddisconnected", (evt) => {
        console.log('控制器已断开。');
        clearInterval(gamepadAPI.job)
    });

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址