mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
fix: typescript options type definition (#1861)
This commit is contained in:
parent
28dc05c4a3
commit
cae44a6f0a
@ -61,7 +61,7 @@ export class CacheStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ResourceOptions {
|
export interface ResourceOptions {
|
||||||
imageTimeout: number;
|
imageTimeout: number;
|
||||||
useCORS: boolean;
|
useCORS: boolean;
|
||||||
allowTaint: boolean;
|
allowTaint: boolean;
|
||||||
|
99
src/index.ts
99
src/index.ts
@ -4,25 +4,22 @@ import {Parser} from './css/syntax/parser';
|
|||||||
import {CloneOptions, DocumentCloner} from './dom/document-cloner';
|
import {CloneOptions, DocumentCloner} from './dom/document-cloner';
|
||||||
import {isBodyElement, isHTMLElement, parseTree} from './dom/node-parser';
|
import {isBodyElement, isHTMLElement, parseTree} from './dom/node-parser';
|
||||||
import {Logger} from './core/logger';
|
import {Logger} from './core/logger';
|
||||||
import {CacheStorage} from './core/cache-storage';
|
import {CacheStorage, ResourceOptions} from './core/cache-storage';
|
||||||
import {CanvasRenderer, RenderOptions} from './render/canvas/canvas-renderer';
|
import {CanvasRenderer, RenderOptions} from './render/canvas/canvas-renderer';
|
||||||
import {ForeignObjectRenderer} from './render/canvas/foreignobject-renderer';
|
import {ForeignObjectRenderer} from './render/canvas/foreignobject-renderer';
|
||||||
|
|
||||||
export type Options = CloneOptions &
|
export type Options = CloneOptions &
|
||||||
RenderOptions & {
|
RenderOptions &
|
||||||
allowTaint: boolean;
|
ResourceOptions & {
|
||||||
backgroundColor: string;
|
backgroundColor: string;
|
||||||
foreignObjectRendering: boolean;
|
foreignObjectRendering: boolean;
|
||||||
imageTimeout: number;
|
|
||||||
logging: boolean;
|
logging: boolean;
|
||||||
proxy?: string;
|
|
||||||
removeContainer?: boolean;
|
removeContainer?: boolean;
|
||||||
useCORS: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseColor = (value: string): Color => color.parse(Parser.create(value).parseComponentValue());
|
const parseColor = (value: string): Color => color.parse(Parser.create(value).parseComponentValue());
|
||||||
|
|
||||||
const html2canvas = (element: HTMLElement, options: Options): Promise<HTMLCanvasElement> => {
|
const html2canvas = (element: HTMLElement, options: Partial<Options> = {}): Promise<HTMLCanvasElement> => {
|
||||||
return renderElement(element, options);
|
return renderElement(element, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,7 +27,7 @@ export default html2canvas;
|
|||||||
|
|
||||||
CacheStorage.setContext(window);
|
CacheStorage.setContext(window);
|
||||||
|
|
||||||
const renderElement = async (element: HTMLElement, opts: Options): Promise<HTMLCanvasElement> => {
|
const renderElement = async (element: HTMLElement, opts: Partial<Options>): Promise<HTMLCanvasElement> => {
|
||||||
const ownerDocument = element.ownerDocument;
|
const ownerDocument = element.ownerDocument;
|
||||||
|
|
||||||
if (!ownerDocument) {
|
if (!ownerDocument) {
|
||||||
@ -43,50 +40,43 @@ const renderElement = async (element: HTMLElement, opts: Options): Promise<HTMLC
|
|||||||
throw new Error(`Document is not attached to a Window`);
|
throw new Error(`Document is not attached to a Window`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOptions = {
|
const instanceName = (Math.round(Math.random() * 1000) + Date.now()).toString(16);
|
||||||
|
|
||||||
|
const {width, height, left, top} =
|
||||||
|
isBodyElement(element) || isHTMLElement(element) ? parseDocumentSize(ownerDocument) : parseBounds(element);
|
||||||
|
|
||||||
|
const defaultResourceOptions = {
|
||||||
allowTaint: false,
|
allowTaint: false,
|
||||||
backgroundColor: '#ffffff',
|
|
||||||
imageTimeout: 15000,
|
imageTimeout: 15000,
|
||||||
logging: true,
|
|
||||||
proxy: undefined,
|
proxy: undefined,
|
||||||
|
useCORS: false
|
||||||
|
};
|
||||||
|
|
||||||
|
const resourceOptions: ResourceOptions = {...defaultResourceOptions, ...opts};
|
||||||
|
|
||||||
|
const defaultOptions = {
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
cache: opts.cache ? opts.cache : CacheStorage.create(instanceName, resourceOptions),
|
||||||
|
logging: true,
|
||||||
removeContainer: true,
|
removeContainer: true,
|
||||||
foreignObjectRendering: false,
|
foreignObjectRendering: false,
|
||||||
scale: defaultView.devicePixelRatio || 1,
|
scale: defaultView.devicePixelRatio || 1,
|
||||||
useCORS: false,
|
|
||||||
windowWidth: defaultView.innerWidth,
|
windowWidth: defaultView.innerWidth,
|
||||||
windowHeight: defaultView.innerHeight,
|
windowHeight: defaultView.innerHeight,
|
||||||
scrollX: defaultView.pageXOffset,
|
scrollX: defaultView.pageXOffset,
|
||||||
scrollY: defaultView.pageYOffset
|
scrollY: defaultView.pageYOffset,
|
||||||
|
x: left,
|
||||||
|
y: top,
|
||||||
|
width: Math.ceil(width),
|
||||||
|
height: Math.ceil(height),
|
||||||
|
id: instanceName
|
||||||
};
|
};
|
||||||
|
|
||||||
const options: Options = {...defaultOptions, ...opts};
|
const options: Options = {...defaultOptions, ...resourceOptions, ...opts};
|
||||||
|
|
||||||
const windowBounds = new Bounds(options.scrollX, options.scrollY, options.windowWidth, options.windowHeight);
|
const windowBounds = new Bounds(options.scrollX, options.scrollY, options.windowWidth, options.windowHeight);
|
||||||
|
|
||||||
// http://www.w3.org/TR/css3-background/#special-backgrounds
|
|
||||||
const documentBackgroundColor = ownerDocument.documentElement
|
|
||||||
? parseColor(getComputedStyle(ownerDocument.documentElement).backgroundColor as string)
|
|
||||||
: COLORS.TRANSPARENT;
|
|
||||||
const bodyBackgroundColor = ownerDocument.body
|
|
||||||
? parseColor(getComputedStyle(ownerDocument.body).backgroundColor as string)
|
|
||||||
: COLORS.TRANSPARENT;
|
|
||||||
|
|
||||||
const backgroundColor =
|
|
||||||
element === ownerDocument.documentElement
|
|
||||||
? isTransparent(documentBackgroundColor)
|
|
||||||
? isTransparent(bodyBackgroundColor)
|
|
||||||
? options.backgroundColor
|
|
||||||
? parseColor(options.backgroundColor)
|
|
||||||
: null
|
|
||||||
: bodyBackgroundColor
|
|
||||||
: documentBackgroundColor
|
|
||||||
: options.backgroundColor
|
|
||||||
? parseColor(options.backgroundColor)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const instanceName = (Math.round(Math.random() * 1000) + Date.now()).toString(16);
|
|
||||||
Logger.create(instanceName);
|
Logger.create(instanceName);
|
||||||
const cache = CacheStorage.create(instanceName, options);
|
|
||||||
Logger.getInstance(instanceName).debug(`Starting document clone`);
|
Logger.getInstance(instanceName).debug(`Starting document clone`);
|
||||||
const documentCloner = new DocumentCloner(element, {
|
const documentCloner = new DocumentCloner(element, {
|
||||||
id: instanceName,
|
id: instanceName,
|
||||||
@ -102,22 +92,37 @@ const renderElement = async (element: HTMLElement, opts: Options): Promise<HTMLC
|
|||||||
|
|
||||||
const container = await documentCloner.toIFrame(ownerDocument, windowBounds);
|
const container = await documentCloner.toIFrame(ownerDocument, windowBounds);
|
||||||
|
|
||||||
const {width, height, left, top} =
|
// http://www.w3.org/TR/css3-background/#special-backgrounds
|
||||||
isBodyElement(clonedElement) || isHTMLElement(clonedElement)
|
const documentBackgroundColor = ownerDocument.documentElement
|
||||||
? parseDocumentSize(ownerDocument)
|
? parseColor(getComputedStyle(ownerDocument.documentElement).backgroundColor as string)
|
||||||
: parseBounds(clonedElement);
|
: COLORS.TRANSPARENT;
|
||||||
|
const bodyBackgroundColor = ownerDocument.body
|
||||||
|
? parseColor(getComputedStyle(ownerDocument.body).backgroundColor as string)
|
||||||
|
: COLORS.TRANSPARENT;
|
||||||
|
|
||||||
|
const bgColor = opts.backgroundColor;
|
||||||
|
const defaultBackgroundColor = typeof bgColor === 'string' ? parseColor(bgColor) : 0xffffffff;
|
||||||
|
|
||||||
|
const backgroundColor =
|
||||||
|
element === ownerDocument.documentElement
|
||||||
|
? isTransparent(documentBackgroundColor)
|
||||||
|
? isTransparent(bodyBackgroundColor)
|
||||||
|
? defaultBackgroundColor
|
||||||
|
: bodyBackgroundColor
|
||||||
|
: documentBackgroundColor
|
||||||
|
: defaultBackgroundColor;
|
||||||
|
|
||||||
const renderOptions = {
|
const renderOptions = {
|
||||||
id: instanceName,
|
id: instanceName,
|
||||||
cache,
|
cache: options.cache,
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
scale: options.scale,
|
scale: options.scale,
|
||||||
x: typeof options.x === 'number' ? options.x : left,
|
x: options.x,
|
||||||
y: typeof options.y === 'number' ? options.y : top,
|
y: options.y,
|
||||||
scrollX: options.scrollX,
|
scrollX: options.scrollX,
|
||||||
scrollY: options.scrollY,
|
scrollY: options.scrollY,
|
||||||
width: typeof options.width === 'number' ? options.width : Math.ceil(width),
|
width: options.width,
|
||||||
height: typeof options.height === 'number' ? options.height : Math.ceil(height),
|
height: options.height,
|
||||||
windowWidth: options.windowWidth,
|
windowWidth: options.windowWidth,
|
||||||
windowHeight: options.windowHeight
|
windowHeight: options.windowHeight
|
||||||
};
|
};
|
||||||
@ -131,7 +136,7 @@ const renderElement = async (element: HTMLElement, opts: Options): Promise<HTMLC
|
|||||||
} else {
|
} else {
|
||||||
Logger.getInstance(instanceName).debug(`Document cloned, using computed rendering`);
|
Logger.getInstance(instanceName).debug(`Document cloned, using computed rendering`);
|
||||||
|
|
||||||
CacheStorage.attachInstance(cache);
|
CacheStorage.attachInstance(options.cache);
|
||||||
Logger.getInstance(instanceName).debug(`Starting DOM parsing`);
|
Logger.getInstance(instanceName).debug(`Starting DOM parsing`);
|
||||||
const root = parseTree(clonedElement);
|
const root = parseTree(clonedElement);
|
||||||
CacheStorage.detachInstance();
|
CacheStorage.detachInstance();
|
||||||
|
@ -39,11 +39,14 @@ import {SelectElementContainer} from '../../dom/elements/select-element-containe
|
|||||||
import {IFrameElementContainer} from '../../dom/replaced-elements/iframe-element-container';
|
import {IFrameElementContainer} from '../../dom/replaced-elements/iframe-element-container';
|
||||||
import {TextShadow} from '../../css/property-descriptors/text-shadow';
|
import {TextShadow} from '../../css/property-descriptors/text-shadow';
|
||||||
|
|
||||||
|
export type RenderConfigurations = RenderOptions & {
|
||||||
|
backgroundColor: Color | null;
|
||||||
|
};
|
||||||
|
|
||||||
export interface RenderOptions {
|
export interface RenderOptions {
|
||||||
id: string;
|
id: string;
|
||||||
scale: number;
|
scale: number;
|
||||||
canvas?: HTMLCanvasElement;
|
canvas?: HTMLCanvasElement;
|
||||||
backgroundColor: Color | null;
|
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
scrollX: number;
|
scrollX: number;
|
||||||
@ -60,11 +63,11 @@ const MASK_OFFSET = 10000;
|
|||||||
export class CanvasRenderer {
|
export class CanvasRenderer {
|
||||||
canvas: HTMLCanvasElement;
|
canvas: HTMLCanvasElement;
|
||||||
ctx: CanvasRenderingContext2D;
|
ctx: CanvasRenderingContext2D;
|
||||||
options: RenderOptions;
|
options: RenderConfigurations;
|
||||||
private readonly _activeEffects: IElementEffect[] = [];
|
private readonly _activeEffects: IElementEffect[] = [];
|
||||||
private readonly fontMetrics: FontMetrics;
|
private readonly fontMetrics: FontMetrics;
|
||||||
|
|
||||||
constructor(options: RenderOptions) {
|
constructor(options: RenderConfigurations) {
|
||||||
this.canvas = options.canvas ? options.canvas : document.createElement('canvas');
|
this.canvas = options.canvas ? options.canvas : document.createElement('canvas');
|
||||||
this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D;
|
this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {RenderOptions} from './canvas-renderer';
|
import {RenderConfigurations} from './canvas-renderer';
|
||||||
import {Logger} from '../../core/logger';
|
import {Logger} from '../../core/logger';
|
||||||
import {createForeignObjectSVG} from '../../core/features';
|
import {createForeignObjectSVG} from '../../core/features';
|
||||||
import {asString} from '../../css/types/color';
|
import {asString} from '../../css/types/color';
|
||||||
@ -6,9 +6,9 @@ import {asString} from '../../css/types/color';
|
|||||||
export class ForeignObjectRenderer {
|
export class ForeignObjectRenderer {
|
||||||
canvas: HTMLCanvasElement;
|
canvas: HTMLCanvasElement;
|
||||||
ctx: CanvasRenderingContext2D;
|
ctx: CanvasRenderingContext2D;
|
||||||
options: RenderOptions;
|
options: RenderConfigurations;
|
||||||
|
|
||||||
constructor(options: RenderOptions) {
|
constructor(options: RenderConfigurations) {
|
||||||
this.canvas = options.canvas ? options.canvas : document.createElement('canvas');
|
this.canvas = options.canvas ? options.canvas : document.createElement('canvas');
|
||||||
this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D;
|
this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
Loading…
Reference in New Issue
Block a user