// ==UserScript==
// @name Custom-Cursor | 自定义鼠标
// @namespace http://tampermonkey.net/
// @version 1.0.2
// @description custom cursor in page / 自定义鼠标
// @license MIT
// @email lindaoqiang98@gmail.com
// @author DQLean
// @match *://*/*
// @icon http://tampermonkey.net/favicon.ico
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
(function () {
'use strict';
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./data.js":
/*!*****************!*\
!*** ./data.js ***!
\*****************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({\r\n \"n-resize\": {\r\n list: [],\r\n index: 0,\r\n },\r\n \"s-resize\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"wait\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"nw-resize\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"se-resize\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"sw-resize\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"ne-resize\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"help\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"e-resize\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"w-resize\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"pointer\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"move\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"not-allowed\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"default\": {\r\n \"list\": [],\r\n \"index\": 2\r\n },\r\n \"copy\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"crosshair\": {\r\n list: [],\r\n index: -1,\r\n },\r\n \"text\": {\r\n list: [],\r\n index: -1,\r\n },\r\n});\n\n//# sourceURL=webpack:///./data.js?");
/***/
}),
/***/ "./i18n.js":
/*!*****************!*\
!*** ./i18n.js ***!
\*****************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"En\": () => (/* binding */ En),\n/* harmony export */ \"Zh\": () => (/* binding */ Zh),\n/* harmony export */ \"t\": () => (/* binding */ t)\n/* harmony export */ });\nconst lang = window.language || navigator.language || navigator.userLanguage;\r\n\r\nconst t = (val) => {\r\n if (lang.startsWith(\"zh\")) {\r\n return Zh[val] || val\r\n }\r\n if (lang.startsWith(\"en\")) {\r\n return En[val] || val\r\n }\r\n return val\r\n}\r\n\r\nconst En = {\r\n \"default\": \"Default\",\r\n \"pointer\": \"Pointer\",\r\n \"crosshair\": \"Crosshair\",\r\n \"move\": \"Move\",\r\n \"e-resize\": \"East Resize\",\r\n \"ne-resize\": \"North East Resize\",\r\n \"nw-resize\": \"North West Resize\",\r\n \"n-resize\": \"North Resize\",\r\n \"se-resize\": \"South East Resize\",\r\n \"sw-resize\": \"South West Resize\",\r\n \"s-resize\": \"South Resize\",\r\n \"w-resize\": \"West Resize\",\r\n \"text\": \"Text\",\r\n \"wait\": \"Wait\",\r\n \"help\": \"Help\",\r\n \"copy\": \"Copy\",\r\n \"not-allowed\": \"Not Allowed\",\r\n\r\n \"imageUploadLimit128\": \"Image upload limit is 128KB!\",\r\n \"imageUploadLimit64\": \"Image upload limit is 64KB!\",\r\n \"imageUploadLimit32\": \"Image upload limit is 32KB!\",\r\n \"imageUploadLimit16\": \"Image upload limit is 16KB!\",\r\n \"imageUploadLimit8\": \"Image upload limit is 8KB!\",\r\n\r\n \"imageLink\": \"Image Link\",\r\n \"pleaseClickToSelectCenter\": \"Please click to select center point (as mouse origin). Support keyboard direction key fine-tuning.\",\r\n \"imageTypeLimit\": \"Image must be .png or .cur format!\",\r\n\r\n \"confirm\": \"Confirm\",\r\n\r\n \"clickToUploadImage\": \"Click to upload image\",\r\n\r\n \"pleaseInputImageName\": \"Please input name\",\r\n\r\n \"setting\": \"Setting\",\r\n\r\n \"clear\": \"Clear Data\",\r\n}\r\n\r\nconst Zh = {\r\n \"default\": \"默认\",\r\n \"pointer\": \"指针\",\r\n \"crosshair\": \"十字线\",\r\n \"move\": \"移动\",\r\n \"e-resize\": \"向左调整\",\r\n \"ne-resize\": \"向左上调整\",\r\n \"nw-resize\": \"向右上调整\",\r\n \"n-resize\": \"向上调整\",\r\n \"se-resize\": \"向左下调整\",\r\n \"sw-resize\": \"向右下调整\",\r\n \"s-resize\": \"向下调整\",\r\n \"w-resize\": \"向右调整\",\r\n \"text\": \"文本\",\r\n \"wait\": \"等待\",\r\n \"help\": \"帮助\",\r\n \"copy\": \"复制\",\r\n \"not-allowed\": \"禁用\",\r\n\r\n \"imageUploadLimit128\": \"图片上传限制为128KB!\",\r\n \"imageUploadLimit64\": \"图片上传限制为64KB!\",\r\n \"imageUploadLimit32\": \"图片上传限制为32KB!\",\r\n \"imageUploadLimit16\": \"图片上传限制为16KB!\",\r\n \"imageUploadLimit8\": \"图片上传限制为8KB!\",\r\n\r\n \"imageLink\": \"图片链接\",\r\n \"pleaseClickToSelectCenter\": \"请点击选择中心点(作为鼠标原点),支持键盘方向键微调。\",\r\n \"imageTypeLimit\": \"图片必须为.png或者.cur格式!\",\r\n\r\n \"confirm\": \"确认\",\r\n\r\n \"clickToUploadImage\": \"点击上传图片\",\r\n\r\n \"pleaseInputImageName\": \"请输入名称\",\r\n\r\n \"setting\": \"设置\",\r\n\r\n \"clear\": \"清除数据\",\r\n}\n\n//# sourceURL=webpack:///./i18n.js?");
/***/
}),
/***/ "./index.js":
/*!******************!*\
!*** ./index.js ***!
\******************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _data_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./data.js */ \"./data.js\");\n/* harmony import */ var _i18n_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./i18n.js */ \"./i18n.js\");\n\r\n\r\n\r\n\r\nconst cursors = (() => {\r\n try {\r\n return GM_getValue(\"cursorData\", _data_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])\r\n } catch {\r\n return _data_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"] || {}\r\n }\r\n})()\r\n\r\ntry {\r\n GM_registerMenuCommand((0,_i18n_js__WEBPACK_IMPORTED_MODULE_1__.t)(\"setting\"), createMenu)\r\n}catch{}\r\n\r\nconst cursorKeys = [\r\n \"default\", \"crosshair\", \"pointer\", \"move\",\r\n \"e-resize\", \"ne-resize\", \"nw-resize\", \"n-resize\", \"se-resize\", \"sw-resize\", \"s-resize\", \"w-resize\",\r\n \"text\", \"wait\", \"help\", \"copy\", \"not-allowed\"\r\n]\r\n\r\nconst excludeTags = [\r\n \"script\", \"meta\", \"head\", \"title\", \"link\", \"style\"\r\n]\r\n\r\nlet isMenuShow = false\r\n\r\nwindow.addEventListener(\"keydown\", (e) => {\r\n const { key } = e\r\n if (key === \"F9\") {\r\n createMenu()\r\n }\r\n})\r\n\r\nlet closeBtnID = \"\"\r\n\r\nfunction getImageBase64(url, size = 32) {\r\n return new Promise((resolve, reject) => {\r\n const img = new Image()\r\n img.onload = () => {\r\n const canvas = document.createElement(\"canvas\")\r\n if (img.width > img.height) {\r\n canvas.width = size\r\n canvas.height = size * img.height / img.width\r\n } else {\r\n canvas.width = size * img.width / img.height\r\n canvas.height = size\r\n }\r\n const ctx = canvas.getContext(\"2d\")\r\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height)\r\n const dataURL = canvas.toDataURL()\r\n resolve(dataURL)\r\n }\r\n img.src = url\r\n })\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el \r\n */\r\nasync function renderChild(el) {\r\n const name = el.nodeName.toLocaleLowerCase()\r\n const type = el.nodeType\r\n if (!excludeTags.includes(name) && el instanceof Element) {\r\n let cursorVal = getComputedStyle(el).getPropertyValue(\"cursor\").toLowerCase()\r\n const originalCursor = el.getAttribute(\"original-cursor\")\r\n if (originalCursor) cursorVal = originalCursor\r\n try {\r\n if (cursorVal === \"\" || cursorVal === \"auto\") {\r\n if (cursors.default) {\r\n const cursor = cursors.default\r\n if (cursor.index != void 0 && cursor.index >= 0 && cursor.index < cursor.list.length) {\r\n const source = cursor.list[cursor.index].source || \"\"\r\n const center = cursor.list[cursor.index].center || [0, 0]\r\n if (!originalCursor) el.setAttribute(\"original-cursor\", cursorVal)\r\n el.style.cursor = `url(${source\r\n }) ${center[0]} ${center[1]}, auto`\r\n }\r\n }\r\n } else {\r\n for (let key of cursorKeys) {\r\n const _key = key.toLowerCase()\r\n if (cursorVal === _key) {\r\n if (cursors[_key]) {\r\n const cursor = cursors[_key]\r\n if (cursor.index != void 0 && cursor.index >= 0 && cursor.index < cursor.list.length) {\r\n const source = cursor.list[cursor.index].source || \"\"\r\n const center = cursor.list[cursor.index].center || [0, 0]\r\n if (!originalCursor) el.setAttribute(\"original-cursor\", cursorVal)\r\n el.style.cursor = `url(${source\r\n }) ${center[0]} ${center[1]}, auto`\r\n }\r\n }\r\n break\r\n }\r\n }\r\n }\r\n } catch (err) {\r\n console.error(\"『custom-cursor』\", err)\r\n }\r\n }\r\n if (el.childNodes) {\r\n for (const child of el.childNodes) {\r\n await renderChild(child)\r\n }\r\n }\r\n}\r\n\r\nrenderChild(document)\r\n\r\n/**\r\n * @param {HTMLElement} el \r\n */\r\nasync function removeRender(el) {\r\n const name = el.nodeName.toLocaleLowerCase()\r\n const type = el.nodeType\r\n if (!excludeTags.includes(name) && el instanceof Element) {\r\n const cursor = getComputedStyle(el).getPropertyValue(\"cursor\").toLowerCase()\r\n const originalCursor = el.getAttribute(\"original-cursor\")\r\n if (cursor.startsWith(\"url\")) {\r\n el.style.cursor = originalCursor || \"\"\r\n }\r\n }\r\n if (el.childNodes) {\r\n for (const child of el.childNodes) {\r\n await removeRender(child)\r\n }\r\n }\r\n}\r\n\r\nasync function reRenderPage() {\r\n await removeRender(document)\r\n await renderChild(document)\r\n}\r\n\r\nfunction createCloseBtn() {\r\n if (!closeBtnID) {\r\n closeBtnID = \"cursor-\" + Date.now() + (\"\" + Math.random()).replace(\".\", \"\")\r\n const styleEl = document.createElement(\"style\")\r\n styleEl.appendChild(document.createTextNode(`\r\n .${closeBtnID} {\r\n position: absolute !important;\r\n right: 0 !important;\r\n top: 0 !important;\r\n overflow: hidden !important;\r\n border: none !important;\r\n padding: 0 !important;\r\n width: 2em !important; height: 2em !important;\r\n border-radius: 50% !important;\r\n background: transparent !important;\r\n color: #1da1f2 !important;\r\n font: inherit !important;\r\n font-size: 16px !important;\r\n text-indent: 100% !important;\r\n cursor: pointer !important;\r\n }\r\n \r\n .${closeBtnID}:hover {\r\n background: rgba(29, 161, 142, .1)\r\n }\r\n \r\n .${closeBtnID}:before, .${closeBtnID}:after {\r\n position: absolute !important;\r\n top: 15% !important; left: calc(50% - .0625em) !important;\r\n width: .125em !important; height: 70% !important;\r\n border-radius: .125em !important;\r\n transform: rotate(45deg) !important;\r\n background: currentcolor !important;\r\n content: ''\r\n }\r\n \r\n .${closeBtnID}:after { transform: rotate(-45deg) !important; }\r\n `))\r\n document.head.appendChild(styleEl)\r\n }\r\n\r\n const closeBtn = document.createElement(\"button\")\r\n closeBtn.className = closeBtnID\r\n return closeBtn\r\n}\r\n\r\nasync function createMenu() {\r\n if (isMenuShow) return\r\n isMenuShow = true\r\n const createSelectBox = (cursorKey, cursorOpt, callback) => {\r\n const box = document.createElement(\"div\")\r\n box.style.cssText = `\r\n display: inline-flex !important;\r\n justify-content: center !important;\r\n align-items: center !important;\r\n background-color: #464879 !important;\r\n color: #fff !important;\r\n padding-left: 8px !important;\r\n border-radius: 4px !important;\r\n overflow: hidden !important;\r\n margin: 4px 2px !important;\r\n `\r\n\r\n const select = document.createElement(\"select\")\r\n select.style.cssText = `\r\n cursor: pointer !important;\r\n display: inline-block !important;\r\n position: relative !important;\r\n font-size: 16px !important;\r\n color: #fff !important;\r\n width: 240px !important;\r\n height: 40px !important;\r\n padding-left: 8px !important;\r\n background-color: #5D7DB3 !important;\r\n outline: none !important;\r\n border: none !important;\r\n margin-left: 4px !important;\r\n word-break: break-all !important;\r\n text-overflow: clip !important;\r\n `\r\n\r\n const { list, index } = cursorOpt\r\n if (Array.isArray(list) && list.length > 0) {\r\n for (let option of list) {\r\n const op = document.createElement(\"option\")\r\n op.value = option.source\r\n op.innerText = option.name\r\n select.appendChild(op)\r\n }\r\n if (index >= 0 && index < list.length) {\r\n select.value = list[index].source\r\n }\r\n }\r\n\r\n select.onchange = (e) => {\r\n const val = e.target.value\r\n if (Array.isArray(list)) {\r\n const index = list.findIndex(item => item.source === val)\r\n callback(index)\r\n } else {\r\n callback(-1)\r\n }\r\n }\r\n\r\n const label = document.createElement(\"label\")\r\n label.innerText = (0,_i18n_js__WEBPACK_IMPORTED_MODULE_1__.t)(cursorKey)\r\n label.style.cssText = `\r\n width: 84px !important;\r\n text-overflow: clip !important;\r\n text-align: center !important;\r\n cursor: ${cursorKey} !important;\r\n `\r\n label.title = (0,_i18n_js__WEBPACK_IMPORTED_MODULE_1__.t)(\"clickToUploadImage\")\r\n label.onclick = (e) => {\r\n createImageReader(cursorKey, ({ source, name, center }) => {\r\n const op = document.createElement(\"option\")\r\n op.value = source\r\n op.innerText = name\r\n select.appendChild(op)\r\n reRenderPage()\r\n })\r\n }\r\n\r\n box.appendChild(label)\r\n box.appendChild(select)\r\n\r\n return box\r\n }\r\n\r\n const container = document.createElement(\"div\")\r\n container.style.cssText = `\r\n display: inline !important;\r\n // flex-direction: column !important;\r\n // justify-content: center !important;\r\n // align-items: flex-start !important;\r\n width: 725px !important;\r\n position: fixed !important;\r\n top: 50% !important;\r\n left: 50% !important;\r\n transform: translate(-50%, -50%) !important;\r\n background-color: #B6CAD7 !important;\r\n padding: 32px 16px 16px 16px !important;\r\n border-radius: 6px !important;\r\n font-size: 14px !important;\r\n z-index: 99999 !important;\r\n `\r\n\r\n const clearBtn = document.createElement(\"button\")\r\n clearBtn.innerText = (0,_i18n_js__WEBPACK_IMPORTED_MODULE_1__.t)(\"clear\")\r\n clearBtn.style.cssText = `\r\n cursor: pointer !important;\r\n display: block !important;\r\n position: relative !important;\r\n font-size: 14px !important;\r\n color: #fff !important;\r\n width: 160px !important;\r\n height: 28px !important;\r\n padding-left: 8px !important;\r\n background-color: #c72121 !important;\r\n outline: none !important;\r\n border: none !important;\r\n margin: auto !important;\r\n word-break: break-all !important;\r\n text-overflow: clip !important;\r\n `\r\n clearBtn.onclick = () => {\r\n for (let key in cursors) {\r\n cursors[key] = {\r\n list: [],\r\n index: -1,\r\n }\r\n }\r\n reRenderPage()\r\n try { GM_setValue(\"cursorData\", cursors) } catch { }\r\n isMenuShow = false\r\n document.body.removeChild(container)\r\n }\r\n\r\n const closeBtn = createCloseBtn()\r\n\r\n container.appendChild(closeBtn)\r\n\r\n for (let key of cursorKeys) {\r\n if (!cursors[key]) continue\r\n container.appendChild(createSelectBox(key, cursors[key], (index) => {\r\n cursors[key].index = index\r\n reRenderPage()\r\n try { GM_setValue(\"cursorData\", cursors) } catch { }\r\n // window.location.reload()\r\n }))\r\n }\r\n\r\n container.appendChild(clearBtn)\r\n\r\n document.body.appendChild(container)\r\n closeBtn.onclick = () => {\r\n isMenuShow = false\r\n document.body.removeChild(container)\r\n }\r\n renderChild(container)\r\n}\r\n\r\nasync function createImageReader(cursorKey, callback = () => { }) {\r\n const box = document.createElement(\"div\")\r\n box.style.cssText = `\r\n padding-top: 16px !important;\r\n position: fixed !important;\r\n top: 50% !important;\r\n left: 50% !important;\r\n transform: translate(-50%, -50%) !important;\r\n min-height: 200px !important;\r\n background-color: #B6CAD7 !important;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n align-items: center !important;\r\n z-index: 99999 !important;\r\n `\r\n\r\n const uploadArea = document.createElement(\"div\")\r\n uploadArea.innerText = \"Drag To Upload\"\r\n uploadArea.style.cssText = `\r\n margin: 16px !important;\r\n width: 400px !important;\r\n height: 300px !important;\r\n font-size: 20px !important;\r\n text-align: center !important;\r\n line-height: 300px !important;\r\n border: 2px dashed #fff !important;\r\n background-color: #5D7DB3 !important;\r\n cursor: grab !important;\r\n `\r\n\r\n const linkInput = document.createElement(\"input\")\r\n linkInput.type = \"text\"\r\n linkInput.placeholder = (0,_i18n_js__WEBPACK_IMPORTED_MODULE_1__.t)(\"imageLink\") + \" [ENTER]\"\r\n linkInput.style.cssText = `\r\n margin: 16px !important;\r\n width: 400px !important;\r\n height: 40px !important;\r\n font-size: 20px !important;\r\n text-align: center !important;\r\n line-height: 40px !important;\r\n border: 2px dashed #fff !important;\r\n background-color: #5D7DB3 !important;\r\n cursor: text !important;\r\n `\r\n\r\n const closeBtn = createCloseBtn()\r\n\r\n const showImage = async (file) => {\r\n if (!file) return\r\n\r\n let image = new Image()\r\n if (typeof file === \"string\") {\r\n image.src = file\r\n } else if (file instanceof Image) {\r\n image.src = file.src\r\n } else {\r\n image.src = await getImageBase64(URL.createObjectURL(file))\r\n }\r\n\r\n image.onload = (e) => {\r\n box.removeChild(uploadArea)\r\n box.removeChild(linkInput)\r\n const tipBox = document.createElement(\"div\")\r\n tipBox.style.cssText = `\r\ntext-align: center !important;\r\nfont-size: 16px !important;\r\nmargin: 5px !important;\r\nline-height: 16px !important;\r\nuser-select: none !important; \r\n`\r\n tipBox.innerText = (0,_i18n_js__WEBPACK_IMPORTED_MODULE_1__.t)(\"pleaseClickToSelectCenter\")\r\n box.appendChild(tipBox)\r\n\r\n const canvas = document.createElement(\"canvas\")\r\n let w = image.naturalWidth\r\n let h = image.naturalHeight\r\n let mw = window.innerWidth - 80\r\n let mh = window.innerHeight - 80\r\n while (w >= mw || h >= mh) {\r\n w = w * 0.7\r\n h = h * 0.7\r\n }\r\n canvas.width = w\r\n canvas.height = h\r\n canvas.style.cssText = `\r\nmargin: 5px 16px !important;\r\nwidth: ${w}px !important;\r\nheight: ${h}px !important;\r\n`\r\n const ctx = canvas.getContext(\"2d\")\r\n ctx.drawImage(image, 0, 0, canvas.width, canvas.height)\r\n box.appendChild(canvas)\r\n const textLine = document.createElement(\"div\")\r\n textLine.style.cssText = `\r\ntext-align: center !important;\r\nfont-size: 14px !important;\r\ncolor: #fff !important;\r\nmargin: 5px !important;\r\nline-height: 16px !important;\r\nuser-select: none !important;\r\n`\r\n textLine.innerText = `X: 0 | Y: 0`\r\n box.appendChild(textLine)\r\n\r\n const nameInput = document.createElement(\"input\")\r\n nameInput.type = \"text\"\r\n nameInput.placeholder = (0,_i18n_js__WEBPACK_IMPORTED_MODULE_1__.t)(\"pleaseInputImageName\")\r\n nameInput.style.cssText = `\r\nmargin: 0px 16px !important;\r\nwidth: 80% !important;\r\nheight: 20px !important;\r\nfont-size: 14px !important;\r\ntext-align: center !important;\r\nborder: none !important;\r\nbackground-color: #e1e1e1 !important;\r\ncursor: text !important;\r\n `\r\n box.appendChild(nameInput)\r\n\r\n const ratioSelect = document.createElement(\"select\")\r\n ratioSelect.style.cssText = `\r\nmargin: 5px 16px !important;\r\nwidth: 80% !important;\r\nheight: 20px !important;\r\nfont-size: 14px !important;\r\ntext-align: center !important;\r\nborder: none !important;\r\nbackground-color: #e1e1e1 !important;\r\ncursor: pointer !important;\r\n`\r\n const ratioList = [\r\n { name: \"8x8\", value: 8 },\r\n { name: \"16x16\", value: 16 },\r\n { name: \"32x32\", value: 32 },\r\n { name: \"64x64\", value: 64 },\r\n { name: \"128x128\", value: 128 },\r\n // { name: \"256x256\", value: 256 },\r\n // { name: \"512x512\", value: 512 },\r\n ]\r\n for (let ratio of ratioList) {\r\n const op = document.createElement(\"option\")\r\n op.value = ratio.value\r\n op.innerText = ratio.name\r\n ratioSelect.appendChild(op)\r\n }\r\n ratioSelect.value = 32\r\n ratioSelect.onchange = async (e) => {\r\n if (typeof file === \"string\" || file instanceof Image) return\r\n const val = Number(e.target.value) || 32\r\n const _image = new Image()\r\n _image.src = await getImageBase64(URL.createObjectURL(file), val)\r\n _image.onload = () => {\r\n canvas.width = _image.naturalWidth\r\n canvas.height = _image.naturalHeight\r\n canvas.style.cssText = `\r\nmargin: 5px 16px !important;\r\nwidth: ${_image.naturalWidth}px !important;\r\nheight: ${_image.naturalHeight}px !important;\r\n`\r\n ctx.drawImage(_image, 0, 0, canvas.width, canvas.height)\r\n textLine.innerText = `X: 0 | Y: 0`\r\n }\r\n image = _image\r\n }\r\n box.appendChild(ratioSelect)\r\n\r\n const btnBox = document.createElement(\"div\")\r\n btnBox.style.cssText = `\r\ntext-align: center !important;\r\nfont-size: 14px !important;\r\ncolor: #6d6d6d !important;\r\nmargin: 5px 16px !important;\r\nline-height: 16px !important;\r\nuser-select: none !important;\r\ncursor: pointer !important;\r\nfont-weight: bold !important;\r\n`\r\n btnBox.innerText = (0,_i18n_js__WEBPACK_IMPORTED_MODULE_1__.t)(\"confirm\")\r\n\r\n box.appendChild(btnBox)\r\n\r\n const center = [0, 0]\r\n\r\n canvas.onclick = (e) => {\r\n const x = e.offsetX\r\n const y = e.offsetY\r\n center[0] = x\r\n center[1] = y\r\n textLine.innerText = `X: ${x} | Y: ${y}`\r\n ctx.clearRect(0, 0, canvas.width, canvas.height)\r\n ctx.drawImage(image, 0, 0, canvas.width, canvas.height)\r\n ctx.fillStyle = \"#ff0000\"\r\n ctx.fillRect(x - 5, y - 5, 10, 10)\r\n }\r\n // 监听上下左右键\r\n document.onkeydown = (e) => {\r\n // e.preventDefault()\r\n const drawPoint = () => {\r\n textLine.innerText = `X: ${center[0]} | Y: ${center[1]}`\r\n ctx.clearRect(0, 0, canvas.width, canvas.height)\r\n ctx.drawImage(image, 0, 0, canvas.width, canvas.height)\r\n ctx.fillStyle = \"#ff0000\"\r\n ctx.fillRect(center[0] - 5, center[1] - 5, 10, 10)\r\n }\r\n const { key } = e\r\n if (key === \"ArrowUp\") {\r\n center[1] -= 1\r\n drawPoint()\r\n } else if (key === \"ArrowDown\") {\r\n center[1] += 1\r\n drawPoint()\r\n } else if (key === \"ArrowLeft\") {\r\n center[0] -= 1\r\n drawPoint()\r\n } else if (key === \"ArrowRight\") {\r\n center[0] += 1\r\n drawPoint()\r\n }\r\n }\r\n\r\n btnBox.onclick = (e) => {\r\n cursors[cursorKey].list.push({\r\n source: image.src,\r\n name: nameInput.value || \"自定义\",\r\n center: center,\r\n })\r\n cursors[cursorKey].index = cursors[cursorKey].list.length - 1\r\n document.body.removeChild(box)\r\n document.onkeydown = null\r\n try { GM_setValue(\"cursorData\", cursors) } catch { }\r\n callback({\r\n source: image.src,\r\n name: nameInput.value || \"自定义\",\r\n center: center,\r\n })\r\n }\r\n\r\n renderChild(box)\r\n }\r\n }\r\n\r\n uploadArea.addEventListener('dragover', (e) => e.preventDefault())\r\n uploadArea.addEventListener('drop', (e) => {\r\n e.preventDefault()\r\n const { dataTransfer: { files = {} } = {} } = e || {}\r\n console.log('dropped: ', files)\r\n\r\n showImage(files[0])\r\n })\r\n uploadArea.addEventListener('click', (e) => {\r\n const input = document.createElement(\"input\")\r\n input.type = \"file\"\r\n input.accept = \"image/*\"\r\n input.onchange = (e) => {\r\n const file = e.target.files[0]\r\n // limit size to 128KB\r\n // if (file.size > 128 * 1024) {\r\n // alert(t(\"imageUploadLimit128\"))\r\n // return\r\n // }\r\n showImage(file)\r\n }\r\n input.click()\r\n })\r\n\r\n linkInput.addEventListener('paste', (e) => {\r\n const data = e.clipboardData || window.clipboardData\r\n const text = data.getData('text')\r\n const image = new Image()\r\n image.src = text\r\n image.onload = (e) => {\r\n showImage(image)\r\n }\r\n image.onerror = (e) => {\r\n alert(\"Image load failed!\")\r\n linkInput.value = \"\"\r\n }\r\n })\r\n\r\n\r\n\r\n box.appendChild(closeBtn)\r\n box.appendChild(uploadArea)\r\n box.appendChild(linkInput)\r\n\r\n document.body.appendChild(box)\r\n closeBtn.onclick = () => { document.body.removeChild(box) }\r\n renderChild(box)\r\n}\n\n//# sourceURL=webpack:///./index.js?");
/***/
})
/******/
});
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/
}
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/
};
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/
}
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for (var key in definition) {
/******/ if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/
}
/******/
}
/******/
};
/******/
})();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/
})();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/
}
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/
};
/******/
})();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/ var __webpack_exports__ = __webpack_require__("./index.js");
/******/
/******/
})()
;
})();