diff --git a/README.md b/README.md index 782d2525..4c83429f 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,9 @@ All the top level functions accept DOM node and rendering options, and return a - [toSvg](#toSvg) - [toJpeg](#toJpeg) - [toBlob](#toBlob) +- [toImage](#toImage) - [toCanvas](#toCanvas) +- [toCanvasList](#toCanvasList) - [toPixelData](#toPixelData) Go with the following examples. @@ -114,6 +116,16 @@ htmlToImage.toBlob(document.getElementById('my-node')) }); ``` +#### toImage +Get a HTMLImageElement, which is a svg image that you can scale it to a big size and it will not blurred. + +```js +htmlToImage.toImage(document.getElementById('my-node')) + .then(function (img) { + document.body.appendChild(img); + }); +``` + #### toCanvas Get a HTMLCanvasElement, and display it right away: @@ -124,6 +136,17 @@ htmlToImage.toCanvas(document.getElementById('my-node')) }); ``` +#### toCanvasList +Get a array of HTMLCanvasElement. Not like `toCanvas` which is limited by [canvas size](https://jhildenbiddle.github.io/canvas-size/#/?id=test-results), + `toCanvasList` can get rid of the limitation of canvas size, so this can export a very large html: + +```js +htmlToImage.toCanvasList(document.getElementById('my-node')) + .then(function (canvasList) { + canvasList.map(canvas => document.body.appendChild(canvas)); + }); +``` + #### toPixelData Get the raw pixel data as a [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) with every 4 array elements representing the RGBA data of a pixel: @@ -292,6 +315,15 @@ A string indicating the image format. The default type is image/png; that type i When supplied, the toCanvas function will return a blob matching the given image type and quality. Defaults to `image/png` + + +### usePageCss + +Use `true` to add a `\n${node1.outerHTML}` + ) +} + +export async function toImage( + node: T, + options: Options = {}, +): Promise { + setDoc(node.ownerDocument) + const svg = await toSvg(node, options) + return svgUrlToImg(svg, options) +} + export async function toCanvas( node: T, options: Options = {}, ): Promise { - const { width, height } = getImageSize(node, options) - const svg = await toSvg(node, options) - const img = await createImage(svg) + const doc = node.ownerDocument + setDoc(doc) + try { + const img = await toImage(node, options) + const { width, height } = getImageSize(node, options, img) + const canvas = doc.createElement('canvas') + const context = canvas.getContext('2d', { willReadFrequently: true })! + const ratio = options.pixelRatio || getPixelRatio() + const canvasWidth = options.canvasWidth || width + const canvasHeight = options.canvasHeight || height - const canvas = document.createElement('canvas') - const context = canvas.getContext('2d')! - const ratio = options.pixelRatio || getPixelRatio() - const canvasWidth = options.canvasWidth || width - const canvasHeight = options.canvasHeight || height + canvas.width = canvasWidth * ratio + canvas.height = canvasHeight * ratio - canvas.width = canvasWidth * ratio - canvas.height = canvasHeight * ratio + if (!options.skipAutoScale) { + checkCanvasDimensions(canvas) + } + canvas.style.width = `${canvasWidth}` + canvas.style.height = `${canvasHeight}` - if (!options.skipAutoScale) { - checkCanvasDimensions(canvas) - } - canvas.style.width = `${canvasWidth}` - canvas.style.height = `${canvasHeight}` + if (options.backgroundColor) { + context.fillStyle = options.backgroundColor + context.fillRect(0, 0, canvas.width, canvas.height) + } + + context.drawImage(img, 0, 0, canvas.width, canvas.height) - if (options.backgroundColor) { - context.fillStyle = options.backgroundColor - context.fillRect(0, 0, canvas.width, canvas.height) + return canvas + } finally { + setDoc(document) } +} - context.drawImage(img, 0, 0, canvas.width, canvas.height) +export async function toCanvasList( + node: T, + options: Options = {}, +): Promise> { + const doc = node.ownerDocument + setDoc(doc) + try { + const img = await toImage(node, options) + const { width, height } = getImageSize(node, options, img) + const ratio = options.pixelRatio || getPixelRatio() + let canvasWidth = (options.canvasWidth || width) * ratio + let canvasHeight = (options.canvasHeight || height) * ratio + const dimensionLimit = getDimensionLimit() + if (canvasWidth > dimensionLimit) { + canvasHeight *= dimensionLimit / canvasWidth + canvasWidth = dimensionLimit + } - return canvas + const result: Array = [] + const scale = canvasWidth / img.width + for (let curY = 0; curY < canvasHeight; curY += dimensionLimit) { + const canvas = doc.createElement('canvas') + const context = canvas.getContext('2d', { willReadFrequently: true })! + const height1 = Math.min(canvasHeight - curY, dimensionLimit) + canvas.width = canvasWidth + canvas.height = height1 + if (options.backgroundColor) { + context.fillStyle = options.backgroundColor + context.fillRect(0, 0, canvas.width, canvas.height) + } + context.drawImage( + img, + 0, + curY / scale, + canvasWidth / scale, + height1 / scale, + 0, + 0, + canvasWidth, + height1, + ) + result.push(canvas) + } + return result + }finally { + setDoc(document) //避免引用所致内存溢出 + } +} +export async function toDataUrl(node: T, options: Options = {}) { + var canvas = await toCanvas(node, options) + return canvas.toDataURL() + //const list = await toCanvasList(node, options) + //if(list.length == 1) return list[0].toDataURL() + // const imgs = list.map(canvas => { + // var img = node.ownerDocument.createElement('img') + // img.src = canvas.toDataURL() + // return new Promise(((resolve, reject) => { + // img.onload = resolve + // img.onerror = reject + // }).then(_=>img) + // }) + // Promise.all(imgs).then(loaded=>{ + // const width = loaded[0].width + // const height = loaded.reduce((c, total) => c + total, 0) + // }) } export async function toPixelData( @@ -93,9 +195,9 @@ export async function toBlob( return blob } -export async function getFontEmbedCSS( - node: T, - options: Options = {}, -): Promise { - return getWebFontCSS(node, options) -} +// export async function getFontEmbedCSS( +// node: T, +// options: Options = {}, +// ): Promise { +// return getWebFontCSS(node, options) +// } diff --git a/src/types.ts b/src/types.ts index b511363f..9cf7f745 100644 --- a/src/types.ts +++ b/src/types.ts @@ -91,4 +91,14 @@ export interface Options { * */ fetchRequestInit?: RequestInit + /* + * Use a