Skip to content

Instantly share code, notes, and snippets.

@dragon-fish
Last active February 21, 2024 11:49
Show Gist options
  • Save dragon-fish/953199ecdaa8a060f6174f2e94b5e366 to your computer and use it in GitHub Desktop.
Save dragon-fish/953199ecdaa8a060f6174f2e94b5e366 to your computer and use it in GitHub Desktop.
clickToSaveCanvas
;(() => {
if (window.clickToSaveCanvas) {
return window.clickToSaveCanvas()
}
/**
* @param {HTMLCanvasElement} canvas
*/
async function canvasToBlob(canvas) {
return new Promise((resolve) => {
canvas.toBlob((blob) => {
resolve(blob)
})
})
}
/**
* @param {Blob} blob
* @param {string} filename
*/
function saveBlob(blob, filename) {
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = filename
a.click()
URL.revokeObjectURL(url)
}
/**
* @param {MouseEvent} e
* @returns {HTMLCanvasElement|null}
*/
function getCanvasFromMouseEvent(e) {
const target = e.target
if (target instanceof HTMLCanvasElement) {
return target
}
const childCanvas = target.querySelector('canvas')
if (childCanvas instanceof HTMLCanvasElement) {
return childCanvas
}
// find max 3 parent levels
let loop = 3
let parent = target.parentElement
while (loop > 0 && parent) {
if (parent instanceof HTMLCanvasElement) {
return parent
}
loop--
parent = parent.parentElement
}
return null
}
/**
* @param {MouseEvent} e
*/
async function clickEventHandler(e) {
document.body.removeEventListener('click', clickEventHandler)
const canvas = getCanvasFromMouseEvent(e)
if (canvas) {
const blob = await canvasToBlob(canvas)
let filename = `${canvas.id || document.title}-${Date.now()}`
filename = prompt('截图保存为:', filename)?.trim() || filename
filename = filename.trim().replace(/\s+/g, '_')
saveBlob(blob, `${filename}.png`)
}
}
function clickToSaveCanvas() {
document.body.removeEventListener('click', clickEventHandler)
document.body.addEventListener('click', clickEventHandler)
}
// expose
Object.defineProperties(window, {
clickToSaveCanvas: {
value: clickToSaveCanvas,
writable: false,
enumerable: true,
configurable: false,
},
})
return window.clickToSaveCanvas()
})()
javascript:(()=>{if(window.clickToSaveCanvas)return window.clickToSaveCanvas();async function e(n){document.body.removeEventListener("click",e);const t=function(e){const n=e.target;if(n instanceof HTMLCanvasElement)return n;const t=n.querySelector("canvas");if(t instanceof HTMLCanvasElement)return t;let c=3,o=n.parentElement;for(;c>0&&o;){if(o instanceof HTMLCanvasElement)return o;c--,o=o.parentElement}return null}(n);if(t){const e=await async function(e){return new Promise((n=>{e.toBlob((e=>{n(e)}))}))}(t);let n=`${t.id||document.title}-${Date.now()}`;n=prompt("截图保存为:",n)?.trim()||n,n=n.trim().replace(/\s+/g,"_"),function(e,n){const t=URL.createObjectURL(e),c=document.createElement("a");c.href=t,c.download=n,c.click(),URL.revokeObjectURL(t)}(e,`${n}.png`)}}Object.defineProperties(window,{clickToSaveCanvas:{value:function(){document.body.removeEventListener("click",e),document.body.addEventListener("click",e)},writable:!1,enumerable:!0,configurable:!1}}),window.clickToSaveCanvas()})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment