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 NodeContainer from './NodeContainer';
import type TextContainer from './TextContainer'; import type TextContainer from './TextContainer';
import type {ImageStore} from './ImageLoader'; import type {ImageStore, ImageElement} from './ImageLoader';
import type StackingContext from './StackingContext'; import type StackingContext from './StackingContext';
import { 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) { if (image.width === size.width && image.height === size.height) {
return image; return image;
} }

View File

@ -1,11 +1,11 @@
/* @flow */ /* @flow */
'use strict'; 'use strict';
import type NodeContainer from './NodeContainer';
import type Options from './index'; import type Options from './index';
import type Logger from './Logger'; import type Logger from './Logger';
type ImageCache = {[string]: Promise<Image>}; export type ImageElement = Image | HTMLCanvasElement;
type ImageCache = {[string]: Promise<ImageElement>};
export default class ImageLoader { export default class ImageLoader {
origin: string; origin: string;
@ -13,12 +13,14 @@ export default class ImageLoader {
_link: HTMLAnchorElement; _link: HTMLAnchorElement;
cache: ImageCache; cache: ImageCache;
logger: Logger; logger: Logger;
_index: number;
constructor(options: Options, logger: Logger) { constructor(options: Options, logger: Logger) {
this.options = options; this.options = options;
this.origin = this.getOrigin(window.location.href); this.origin = this.getOrigin(window.location.href);
this.cache = {}; this.cache = {};
this.logger = logger; this.logger = logger;
this._index = 0;
} }
loadImage(src: string): ?string { 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 { isInlineImage(src: string): boolean {
return /data:image\/.*;base64,/i.test(src); return /data:image\/.*;base64,/i.test(src);
} }
@ -86,14 +94,14 @@ export default class ImageLoader {
export class ImageStore { export class ImageStore {
_keys: Array<string>; _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._keys = keys;
this._images = images; this._images = images;
} }
get(key: string): ?HTMLImageElement { get(key: string): ?ImageElement {
const index = this._keys.indexOf(key); const index = this._keys.indexOf(key);
return index === -1 ? null : this._images[index]; 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)'; node.style.transform = 'matrix(1,0,0,1,0,0)';
} }
this.image = this.image = getImage(node, imageLoader);
// $FlowFixMe
node.tagName === 'IMG' ? imageLoader.loadImage(node.currentSrc || node.src) : null;
this.bounds = parseBounds(node); this.bounds = parseBounds(node);
this.curvedBounds = parseBoundCurves( this.curvedBounds = parseBoundCurves(
this.bounds, 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'; 'use strict';
import type {Bounds, BoundCurves, Path} from '../Bounds'; import type {Bounds, BoundCurves, Path} from '../Bounds';
import type ImageLoader from '../ImageLoader'; import type ImageLoader, {ImageElement} from '../ImageLoader';
import Color from '../Color'; import Color from '../Color';
import Length from '../Length'; import Length from '../Length';
@ -82,7 +82,7 @@ class BackgroundSize {
export const calculateBackgroundSize = ( export const calculateBackgroundSize = (
backgroundImage: BackgroundImage, backgroundImage: BackgroundImage,
image: HTMLImageElement, image: ImageElement,
bounds: Bounds bounds: Bounds
): Size => { ): Size => {
let width = 0; let width = 0;