您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
-
当前为
// ==UserScript== // @name rendero-info // @namespace what.ever // @match https://www.renderosity.com/rr/mod/* // @match https://www.renderotica.com/store/sku/* // @grant GM_xmlhttpRequest // @version 1.0 // @author - // @description - // ==/UserScript== const W = 380; const H = 494; let info = null; // get info try { if(location.host.includes('renderosity')){ info = { store: 'Renderosity', title: document.querySelector('.title-header').innerHTML.split('<small>')[0].trim(), productID: document.querySelector('.mainImage').href.replace(/.+?product_(\d+).+/, '$1'), venderName: [] } for(let a of document.querySelectorAll('.title-header > small > a')){ if(a.innerText.length > 0){ info.venderName.push(a.innerText); } } }else if(location.host.includes('renderotica')){ info = { store: 'Renderotica', title: document.querySelector('.product-info > h1').innerText.trim(), productID: document.querySelector('.product-info > p > span').innerText.trim(), venderName: [] } for(let a of document.querySelectorAll('.product-info > p > a')){ info.venderName.push(a.innerText); } // wrap cover with lightbox const pImg = document.querySelector('.primary-image > img'); const a = document.createElement('a'); a.href = pImg.src; a.dataset.lightbox = 'image'; pImg.parentNode.append(a); a.append(pImg); } } catch (error) { console.error(`can't get product info\n`, error); return; } // add switcher for info panel addBtn('📃', switchInfoPanel); addBtn('✂', clipImage); function switchInfoPanel(){ const infoPanel = document.querySelector('#ro-info-panel') || createInfoPanel(); if(infoPanel.style.display === 'block'){ infoPanel.style.display = 'none'; }else{ infoPanel.style.display = 'block'; } } function createInfoPanel(){ const infoPanel = document.createElement('div'); infoPanel.id = 'ro-info-panel'; infoPanel.innerHTML = ` <div class="ro-title"> Product Name: <input type="text" class="value"> <button class="ro-copy">copy</button> </div> <div class="ro-vender"> Vender Name: <input type="text" class="value"> <button class="ro-copy">copy</button> </div> <div class="ro-store"> Store Name: <input type="text" class="value"> <button class="ro-copy">copy</button> </div> <div class="ro-id"> Product ID: <input type="text" class="value"> <button class="ro-copy">copy</button> </div> `; // add style addStyle(` #ro-info-panel{ position: fixed; top: 10rem; right: 3rem; z-index: 1; background-color: #fff6; padding: 1rem; border-radius: .5rem; text-align: right; } #ro-info-panel > div{ margin: 5px; } .ro-copy{ margin-left: 5px; cursor: pointer; } `); // fill info panel infoPanel.querySelector('.ro-title > .value').value = info.title; infoPanel.querySelector('.ro-vender > .value').value = info.venderName.join(','); infoPanel.querySelector('.ro-store > .value').value = info.store; infoPanel.querySelector('.ro-id > .value').value = info.productID; // bind listener infoPanel.addEventListener('click', ev=>{ const t = ev.target; if(t.classList.contains('ro-copy')){ t.previousElementSibling.select(); if(document.execCommand('copy')) console.log('copied.'); } }) // show node document.body.append(infoPanel); return infoPanel; } function clipImage(){ const imgBox = document.querySelector('#lightbox'); const img = imgBox.querySelector('img'); if(imgBox.style.display !== 'block'){ alert('please select an image'); return; } // get select box let selectBox = document.querySelector('#ro-select-box'); if(!selectBox){ createSelectBox(); }else if(selectBox.style.display === 'none'){ selectBox.style.display = 'block'; }else{ clip(); selectBox.style.display = 'none'; } function createSelectBox(){ let selectBox = document.createElement('div'); selectBox.id = 'ro-select-box'; // add style addStyle(` #ro-select-box{ position: absolute; z-index: 99; cursor: move; border: 2px dashed #fff; } `); selectBox.style.width = W + 'px'; selectBox.style.height = H + 'px'; selectBox.style.top = '0px'; selectBox.style.left = '0px'; imgBox.querySelector('img').after(selectBox); selectBox.addEventListener('mousedown', ev=>{ const t = ev.target; if(t.id !== 'ro-select-box') return; selectBox.addEventListener('mousemove', handleDragBox); }); document.body.addEventListener('mouseup', ev=>{ selectBox.removeEventListener('mousemove', handleDragBox); }); selectBox.addEventListener('contextmenu', ev=>{ ev.preventDefault(); selectBox.style.display = 'none'; }); // create resize corner const resizeCorner = document.createElement('div'); resizeCorner.id = 'resize-corner'; addStyle(` #resize-corner{ width: 20px; height: 20px; background: red; position: absolute; bottom: -5px; right: -5px; cursor: se-resize; border-radius: 10px; } `); resizeCorner.addEventListener('mousedown', ev=>{ document.body.addEventListener('mousemove', handleResize); }); document.body.addEventListener('mouseup', ev=>{ document.body.removeEventListener('mousemove', handleResize); }); selectBox.append(resizeCorner); function handleDragBox(ev){ // console.log('dragging'); const t = ev.target; const x0 = parseFloat(t.style.left.replace('px', '')); const y0 = parseFloat(t.style.top.replace('px', '')); t.style.left = x0 + ev.movementX + 'px'; t.style.top = y0 + ev.movementY + 'px'; } function handleResize(ev){ // console.log('resizing'); const t = ev.target; const x = ev.movementX; const y = x / W * H; const w0 = parseFloat(selectBox.style.width.replace('px', '')); const h0 = parseFloat(selectBox.style.height.replace('px', '')); console.log(x,y,w0,h0); selectBox.style.width = w0 + x + 'px'; selectBox.style.height = h0 + y + 'px'; } } function clip(ev){ // get img // can't use original img, blocked by CORS GM_xmlhttpRequest({ url: img.src, method: 'GET', responseType: 'blob', onerror: console.error, onload: result=>{ createImageBitmap(result.response).then( bitmap=>{ const ratio = bitmap.height / img.parentElement.clientHeight; const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const sx = ratio * parseFloat(selectBox.style.left.replace('px', '')); const sy = ratio * parseFloat(selectBox.style.top.replace('px', '')); const sw = ratio * parseFloat(selectBox.style.width.replace('px', '')); const sh = ratio * parseFloat(selectBox.style.height.replace('px', '')); canvas.width = W; canvas.height = H; ctx.drawImage(bitmap, sx, sy, sw, sh, 0, 0, W, H); ctx.imageSmoothingQuality = 'high'; // ctx.imageSmoothingEnabled = false; const a = document.createElement('a'); a.download = info.title + '.jpg'; a.href = canvas.toDataURL('image/jpeg', 0.9); a.click(); } ); } }); } } function addStyle(css){ const elm = document.createElement('style'); elm.textContent = css; document.head.append(elm); return elm; } function addBtn(icon, callback){ let ctn = document.body.querySelector('#my-btn-container'); if(!ctn){ ctn = document.createElement('div'); ctn.id = 'my-btn-container'; addStyle(` #my-btn-container{ position: fixed; bottom: 80px; right: 80px; z-index: 20000; } #my-btn-container > div{ background: #fff8; border-radius: 10px; border: 2px solid #0008; padding: 5px; margin: 5px 0; font-size: 20px; cursor: pointer; user-select: none; text-align: center; } `); document.body.append(ctn); } const btn = document.createElement('div'); btn.innerText = icon; btn.addEventListener('click', callback); ctn.append(btn); return btn; }