您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
实现灰机汉化组漫画网站(yoedge.com)的横屏阅读模式
当前为
// ==UserScript== // @name yoedge-horizontal-screen // @namespace https://github.com/Lockvictor // @author Lockvictor // @description 实现灰机汉化组漫画网站(yoedge.com)的横屏阅读模式 // @homepage https://github.com/Lockvictor/yoedge-horizontal-screen // @match http://*.yoedge.com/smp-app/* // @version 1.0.5 // @grant none // ==/UserScript== const canvasObj = document.getElementsByTagName('canvas')[0]; const containerObj = canvasObj.parentElement; const MANGA_ASPECT_RATIO = 1.5; //漫画宽高比 const DEFAULT_SCALE_RATIO = 0.6; //默认缩放比例 const MAX_SCALE_RATIO = 1; //最大缩放比例,与屏幕等宽 const MIN_SCALE_RATIO = parseInt(canvasObj.style.width) / screen.width; //最小缩放比例,与屏幕等高 const SCALE_STEP = 0.05; const PAGE_BUTTON_AREA_RATIO = 0.1; //顶部和底部响应翻页事件的区域比例,10% const SCROLLBY_RATIO = 0.15; //快捷键滚动屏幕比例 var gMangaAreaRatio = DEFAULT_SCALE_RATIO; //漫画宽度占屏幕宽度的比例 (function () { 'use strict'; // 调整工具按钮,把position由absolute改为fixed固定在右下角 // 工具按钮延迟加载,因此采用定时检测 var settingButtonFlag; settingButtonFlag = setInterval(function () { var normalButton = document.getElementById('normal-button'); var settingButton = normalButton.parentElement; if (settingButton !== null) { settingButton.style.position = 'fixed'; // 把弹出的工具栏也改为fixed固定在右下角 // 每次点击工具按钮弹出工具栏时都会计算工具栏的位置,所以只能把修改注册到click事件中 normalButton.addEventListener('click', function (event) { var toolContainer = document.getElementsByClassName('tool-container')[0]; toolContainer.style.position = 'fixed'; toolContainer.style.top = ''; toolContainer.style.bottom = '0.5%'; }); clearInterval(settingButtonFlag); } }, 1000); // 调整container和canvas containerObj.style.width = '100%'; containerObj.style.height = 'auto'; containerObj.style.margin = '0'; containerObj.style.textAlign = 'center'; scaleCanvas(0); // 添加mask覆盖canvas,屏蔽原有事件,以便实现自定义点击翻页和缩放 addCanvasMask(); // 修正最后一页的弹出导航框被mask遮盖的问题 fixModalBehavior(); // 自定义缩放、滚动、翻页快捷键 customizeShortcut(); })(); function scaleCanvas(increment) { var expectedScaleRatio = gMangaAreaRatio + increment; if (increment > 0) { gMangaAreaRatio = (expectedScaleRatio >= MAX_SCALE_RATIO) ? MAX_SCALE_RATIO : expectedScaleRatio; } else if (increment < 0) { gMangaAreaRatio = (expectedScaleRatio <= MIN_SCALE_RATIO) ? MIN_SCALE_RATIO : expectedScaleRatio; } var newWidth = screen.width * gMangaAreaRatio; var newHeight = newWidth * MANGA_ASPECT_RATIO; canvasObj.style.width = newWidth + 'px'; canvasObj.style.height = newHeight + 'px'; var canvasMask = document.getElementById('canvasMask'); if (canvasMask !== null) { canvasMask.style.width = newWidth + 'px'; canvasMask.style.height = newHeight + 'px'; canvasMask.style.marginLeft = - newWidth / 2 + 'px'; } } function addCanvasMask() { var canvasWidth = screen.width * gMangaAreaRatio; var canvasHeight = canvasWidth * MANGA_ASPECT_RATIO; var canvasMask = document.createElement('div'); canvasMask.id = 'canvasMask'; canvasMask.style.width = canvasWidth + 'px'; canvasMask.style.height = canvasHeight + 'px'; canvasMask.style.zIndex = 1; canvasMask.style.position = 'absolute'; canvasMask.style.top = '0'; canvasMask.style.left = '50%'; canvasMask.style.marginLeft = - canvasWidth / 2 + 'px'; // canvasMask.style.backgroundColor = 'rgba(211, 211, 211, 0.3)'; //添加鼠标点击翻页事件 canvasMask.addEventListener('mouseup', function (event) { var canvasHeight = screen.width * gMangaAreaRatio * MANGA_ASPECT_RATIO; var pageButtonAreaHeight = canvasHeight * PAGE_BUTTON_AREA_RATIO; if (event.layerY <= pageButtonAreaHeight) { prePage() } else if (event.layerY >= (canvasHeight - pageButtonAreaHeight)) { nextPage() } }); containerObj.appendChild(canvasMask); } function fixModalBehavior() { var modalInner = document.getElementsByClassName('modal__inner')[0]; var modalLabel = modalInner.previousElementSibling; modalInner.style.zIndex = '2'; // 把click事件传给label,该label对应一个checkbox,可以控制弹出框的显隐 modalInner.addEventListener('click', function (event) { modalLabel.dispatchEvent(new MouseEvent(event.type, event)); }); } function customizeShortcut() { // 漫画缩放、滚动、翻页 // 缩放和滚动都可以持续响应,于是注册到keydown document.addEventListener('keydown', function (event) { switch (event.key) { case '=': scaleCanvas(SCALE_STEP); break; case '-': scaleCanvas(-SCALE_STEP); break; case '0': gMangaAreaRatio = DEFAULT_SCALE_RATIO; scaleCanvas(0); break; case 'j': smoothyScrollBy(0, screen.width * gMangaAreaRatio * MANGA_ASPECT_RATIO * SCROLLBY_RATIO); break; case 'k': smoothyScrollBy(0, -screen.width * gMangaAreaRatio * MANGA_ASPECT_RATIO * SCROLLBY_RATIO); break; default: break; } }); // 翻页和跳转下一话是单次响应,注册到keyup document.addEventListener('keyup', function (event) { switch (event.key) { case 'h': prePage(); break; case 'l': nextPage(); break; case 'n': smp.toolbar.nextApp(); break; default: break; } }); } function prePage() { if (0 != smp.controller.now && !smp.controller.loading && !smp.controller.quickPlay()) { smp.controller.prePage(); smoothyScrollTo(0, document.body.scrollHeight); } } function nextPage() { if (!smp.controller.loading && !smp.controller.quickPlay()) { smp.controller.nextPage(); smoothyScrollTo(0, 0); } } function smoothyScrollBy(offsetX, offsetY) { try { window.scrollBy({ top: offsetY, left: offsetX, behavior: 'smooth' }); } catch (error) { window.scrollBy(offsetX, offsetY); } } function smoothyScrollTo(x, y) { try { window.scrollTo({ top: y, left: x, behavior: 'smooth' }); } catch (error) { window.scrollTo(x, y); } }