Implement HTMLCanvasElement rendering

This commit is contained in:
Niklas von Hertzen 2017-08-03 20:57:55 +08:00
parent f2b8c16c2c
commit fe97851988
4 changed files with 31 additions and 12 deletions

View File

@ -12,7 +12,7 @@ import BezierCurve from './BezierCurve';
import type NodeContainer from './NodeContainer';
import type TextContainer from './TextContainer';
import type {ImageStore} from './ImageLoader';
import type {ImageStore, ImageElement} from './ImageLoader';
import type StackingContext from './StackingContext';
import {
@ -192,7 +192,7 @@ export default class CanvasRenderer {
}
}
resizeImage(image: HTMLImageElement, size: Size) {
resizeImage(image: ImageElement, size: Size) {
if (image.width === size.width && image.height === size.height) {
return image;
}

View File

@ -1,11 +1,11 @@
/* @flow */
'use strict';
import type NodeContainer from './NodeContainer';
import type Options from './index';
import type Logger from './Logger';
type ImageCache = {[string]: Promise<Image>};
export type ImageElement = Image | HTMLCanvasElement;
type ImageCache = {[string]: Promise<ImageElement>};
export default class ImageLoader {
origin: string;
@ -13,12 +13,14 @@ export default class ImageLoader {
_link: HTMLAnchorElement;
cache: ImageCache;
logger: Logger;
_index: number;
constructor(options: Options, logger: Logger) {
this.options = options;
this.origin = this.getOrigin(window.location.href);
this.cache = {};
this.logger = logger;
this._index = 0;
}
loadImage(src: string): ?string {
@ -33,6 +35,12 @@ export default class ImageLoader {
}
}
loadCanvas(node: HTMLCanvasElement): string {
const key = String(this._index++);
this.cache[key] = Promise.resolve(node);
return key;
}
isInlineImage(src: string): boolean {
return /data:image\/.*;base64,/i.test(src);
}
@ -86,14 +94,14 @@ export default class ImageLoader {
export class ImageStore {
_keys: Array<string>;
_images: Array<HTMLImageElement>;
_images: Array<ImageElement>;
constructor(keys: Array<string>, images: Array<HTMLImageElement>) {
constructor(keys: Array<string>, images: Array<ImageElement>) {
this._keys = keys;
this._images = images;
}
get(key: string): ?HTMLImageElement {
get(key: string): ?ImageElement {
const index = this._keys.indexOf(key);
return index === -1 ? null : this._images[index];
}

View File

@ -102,9 +102,7 @@ export default class NodeContainer {
node.style.transform = 'matrix(1,0,0,1,0,0)';
}
this.image =
// $FlowFixMe
node.tagName === 'IMG' ? imageLoader.loadImage(node.currentSrc || node.src) : null;
this.image = getImage(node, imageLoader);
this.bounds = parseBounds(node);
this.curvedBounds = parseBoundCurves(
this.bounds,
@ -172,3 +170,16 @@ export default class NodeContainer {
);
}
}
const getImage = (node: HTMLElement, imageLoader: ImageLoader): ?string => {
switch (node.tagName) {
case 'IMG':
// $FlowFixMe
return imageLoader.loadImage(node.currentSrc || node.src);
case 'CANVAS':
// $FlowFixMe
return imageLoader.loadCanvas(node);
}
return null;
};

View File

@ -2,7 +2,7 @@
'use strict';
import type {Bounds, BoundCurves, Path} from '../Bounds';
import type ImageLoader from '../ImageLoader';
import type ImageLoader, {ImageElement} from '../ImageLoader';
import Color from '../Color';
import Length from '../Length';
@ -82,7 +82,7 @@ class BackgroundSize {
export const calculateBackgroundSize = (
backgroundImage: BackgroundImage,
image: HTMLImageElement,
image: ImageElement,
bounds: Bounds
): Size => {
let width = 0;