您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Allows you to draw directly on webpages when you press Shift+Alt+D
当前为
- // ==UserScript==
- // @name Draw on Page
- // @version 1.2
- // @description Allows you to draw directly on webpages when you press Shift+Alt+D
- // @author someRandomGuy2
- // @match *://*/*
- // @grant none
- // @license Apache-2.0
- // @namespace https://greasyfork.org/users/117222
- // ==/UserScript==
- (function() {
- 'use strict';
- let container;
- let drawingCanvas;
- let contextMenuContainer;
- let contextMenu;
- let enabled = false;
- let color = "#ff0000";
- const brushes = {
- pen: function(X, startX, startY, endX, endY, pressure) {
- X.fillStyle = color;
- const movementX = endX - startX;
- const movementY = endY - startY;
- const step = 2;
- const distance = Math.sqrt(movementX * movementX + movementY * movementY);
- const size = 4 * pressure;
- const halfSize = size / 2;
- const distanceStep = Math.max(0.2, halfSize);
- for (let i = 0; i < distance; i += distanceStep) {
- const x = startX * (1 - i / distance) + endX * (i / distance);
- const y = startY * (1 - i / distance) + endY * (i / distance);
- X.fillRect(x - halfSize, y - halfSize, size, size);
- }
- X.fillRect(endX - halfSize, endY - halfSize, size, size);
- },
- eraser: function(X, startX, startY, endX, endY, pressure) {
- const movementX = endX - startX;
- const movementY = endY - startY;
- const step = 2;
- const distance = Math.sqrt(movementX * movementX + movementY * movementY);
- const size = 50 * pressure;
- const halfSize = size / 2;
- const distanceStep = Math.max(0.2, halfSize);
- for (let i = 0; i < distance; i += distanceStep) {
- const x = startX * (1 - i / distance) + endX * (i / distance);
- const y = startY * (1 - i / distance) + endY * (i / distance);
- X.clearRect(x - halfSize, y - halfSize, size, size);
- }
- X.clearRect(endX - halfSize, endY - halfSize, size, size);
- },
- };
- function toggleDrawable() {
- initIfNotAlready();
- if (enabled) {
- enabled = false;
- container.classList.add("tm-drawing-canvas-fallthrough");
- } else {
- enabled = true;
- container.classList.remove("tm-drawing-canvas-fallthrough");
- }
- }
- function initIfNotAlready() {
- if (container) { return; }
- container = document.createElement("div");
- container.classList.add("tm-drawing-canvas-container");
- drawingCanvas = document.createElement("canvas");
- drawingCanvas.classList.add("tm-drawing-canvas");
- container.appendChild(drawingCanvas);
- drawingCanvas.width = innerWidth * devicePixelRatio;
- drawingCanvas.height = innerHeight * devicePixelRatio;
- const X = drawingCanvas.getContext("2d");
- contextMenuContainer = document.createElement("div");
- contextMenuContainer.classList.add("tm-drawing-canvas-context-menu-container");
- contextMenu = document.createElement("div");
- contextMenuContainer.appendChild(contextMenu);
- contextMenu.classList.add("tm-drawing-canvas-context-menu");
- const clearCanvasOption = document.createElement("div");
- clearCanvasOption.innerText = "Clear canvas";
- contextMenu.appendChild(clearCanvasOption);
- const saveCanvasOption = document.createElement("div");
- saveCanvasOption.innerText = "Save canvas";
- contextMenu.appendChild(saveCanvasOption);
- const changeColor = document.createElement("div");
- const colorPicker = document.createElement("input");
- colorPicker.type = "color";
- colorPicker.value = color;
- changeColor.appendChild(colorPicker);
- contextMenu.appendChild(changeColor);
- const dropShadowToggle = document.createElement("div");
- dropShadowToggle.innerText = "Toggle drop shadow";
- contextMenu.appendChild(dropShadowToggle);
- let mouseDown = false;
- drawingCanvas.addEventListener("pointerdown", function() { mouseDown = true; });
- drawingCanvas.addEventListener("pointerup", function() { mouseDown = false; });
- drawingCanvas.addEventListener("pointermove", function(event) {
- if (!mouseDown) { return; }
- const brush = event.shiftKey ? brushes.eraser : brushes.pen;
- const scaleX = drawingCanvas.width / innerWidth;
- const scaleY = drawingCanvas.height / innerHeight;
- const startX = (event.x - event.movementX) * scaleX;
- const startY = (event.y - event.movementY) * scaleY;
- const endX = event.x * scaleX;
- const endY = event.y * scaleY;
- brush(X, startX, startY, endX, endY, event.pressure);
- });
- drawingCanvas.addEventListener("contextmenu", function(event) {
- contextMenu.style.top = event.clientY + "px";
- contextMenu.style.left = event.clientX + "px";
- container.appendChild(contextMenuContainer);
- event.preventDefault();
- });
- function addContextMenuItemClickListener(elm, func) {
- elm.addEventListener("click", func);
- elm.addEventListener("mouseup", ev => func(ev, true));
- }
- function closeContextMenu() {
- container.removeChild(contextMenuContainer);
- }
- addContextMenuItemClickListener(contextMenuContainer, function(event, mouseupShortcutClick) {
- if (mouseupShortcutClick) {
- if (event.target != contextMenuContainer && event.target != contextMenu) {
- closeContextMenu();
- }
- } else {
- closeContextMenu();
- }
- });
- addContextMenuItemClickListener(clearCanvasOption, function() {
- // clear canvas
- X.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height);
- drawingCanvas.width = innerWidth * devicePixelRatio;
- drawingCanvas.height = innerHeight * devicePixelRatio;
- });
- addContextMenuItemClickListener(saveCanvasOption, function() {
- drawingCanvas.toBlob(blob => open(URL.createObjectURL(blob)))
- });
- addContextMenuItemClickListener(dropShadowToggle, function() {
- drawingCanvas.classList.toggle("no-drop-shadow");
- });
- addContextMenuItemClickListener(changeColor, function(event, mouseupShortcutClick) {
- if (event.target == changeColor || mouseupShortcutClick) {
- colorPicker.click();
- }
- event.stopPropagation();
- });
- colorPicker.addEventListener("change", function() {
- color = colorPicker.value;
- closeContextMenu();
- });
- drawingCanvas.addEventListener("touchmove", function(event) { });
- const style = document.createElement("style");
- style.innerHTML = `
- .tm-drawing-canvas-container {
- z-index: 99999;
- position: fixed;
- top: 0;
- left: 0;
- width: 100vw;
- height: 100vh;
- font-size: 14px;
- font-family: sans;
- line-height: 1.15;
- color: #000;
- }
- .tm-drawing-canvas-container.tm-drawing-canvas-fallthrough {
- pointer-events: none;
- }
- .tm-drawing-canvas {
- position: aboslute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- cursor: crosshair;
- filter: drop-shadow(0px 0px 8px background);
- }
- .tm-drawing-canvas.no-drop-shadow {
- filter: none;
- }
- .tm-drawing-canvas-context-menu-container {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- }
- .tm-drawing-canvas-context-menu {
- position: absolute;
- display: inline-block;
- background-color: #fff;
- padding-top: 4px;
- padding-bottom: 4px;
- margin-top: 1px;
- border: 1px solid #00000040;
- box-shadow: #00000038 0px 1px 16px, #0000002e 0px 1px 8px;
- }
- .tm-drawing-canvas-context-menu div {
- padding: 4px;
- cursor: pointer;
- }
- .tm-drawing-canvas-context-menu div:hover {
- background-color: #ccc;
- }
- `;
- document.head.appendChild(style);
- document.body.appendChild(container);
- }
- addEventListener("keydown", function(event) {
- if (event.code == "KeyD" && event.altKey && event.shiftKey) {
- toggleDrawable();
- }
- });
- })();