Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,13 @@ You may experience loss of parts of the image if set to `true` and you are expor

Defaults to `false`

### waitForAnimationFrameAcquired

When supplied, the library will wait for the next animation frame to be acquired before rendering the image.
This is useful when you want to achieve a smooth transition when rendering the image.

Defaults to `false`

### type

A string indicating the image format. The default type is image/png; that type is also used if the given type isn't supported.
Expand Down
10 changes: 5 additions & 5 deletions src/clone-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
import { getMimeType } from './mimes'
import { resourceToDataURL } from './dataurl'

async function cloneCanvasElement(canvas: HTMLCanvasElement) {
async function cloneCanvasElement(canvas: HTMLCanvasElement, options: Options) {
const dataURL = canvas.toDataURL()
if (dataURL === 'data:,') {
return canvas.cloneNode(false) as HTMLCanvasElement
}
return createImage(dataURL)
return createImage(dataURL, options)

Check warning on line 17 in src/clone-node.ts

View check run for this annotation

Codecov / codecov/patch

src/clone-node.ts#L17

Added line #L17 was not covered by tests
}

async function cloneVideoElement(video: HTMLVideoElement, options: Options) {
Expand All @@ -25,13 +25,13 @@
canvas.height = video.clientHeight
ctx?.drawImage(video, 0, 0, canvas.width, canvas.height)
const dataURL = canvas.toDataURL()
return createImage(dataURL)
return createImage(dataURL, options)
}

const poster = video.poster
const contentType = getMimeType(poster)
const dataURL = await resourceToDataURL(poster, contentType, options)
return createImage(dataURL)
return createImage(dataURL, options)
}

async function cloneIFrameElement(iframe: HTMLIFrameElement, options: Options) {
Expand All @@ -55,7 +55,7 @@
options: Options,
): Promise<HTMLElement> {
if (isInstanceOfElement(node, HTMLCanvasElement)) {
return cloneCanvasElement(node)
return cloneCanvasElement(node, options)

Check warning on line 58 in src/clone-node.ts

View check run for this annotation

Codecov / codecov/patch

src/clone-node.ts#L58

Added line #L58 was not covered by tests
}

if (isInstanceOfElement(node, HTMLVideoElement)) {
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export async function toCanvas<T extends HTMLElement>(
): Promise<HTMLCanvasElement> {
const { width, height } = getImageSize(node, options)
const svg = await toSvg(node, options)
const img = await createImage(svg)
const img = await createImage(svg, options)

const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')!
Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ export interface Options {
* A boolean to turn off auto scaling for truly massive images..
*/
skipAutoScale?: boolean
/**
* An option for rendering the image only when the image is visible on the frame.
* This might be useful for performance reasons when rendering a large number of images.
*/
waitForAnimationFrameAcquired?: boolean
/**
* A string indicating the image format. The default type is image/png; that type is also used if the given type isn't supported.
*/
Expand Down
11 changes: 9 additions & 2 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,19 @@ export function canvasToBlob(
})
}

export function createImage(url: string): Promise<HTMLImageElement> {
export function createImage(
url: string,
options: Options = {},
): Promise<HTMLImageElement> {
return new Promise((resolve, reject) => {
const img = new Image()
img.onload = () => {
img.decode().then(() => {
requestAnimationFrame(() => resolve(img))
if (options.waitForAnimationFrameAcquired) {
requestAnimationFrame(() => resolve(img))
} else {
resolve(img)
}
})
}
img.onerror = reject
Expand Down
Loading