async version of canvas

This commit is contained in:
Preet Shihn
2018-06-17 01:01:56 -07:00
parent 89fbef0e05
commit d0660149f3
5 changed files with 214 additions and 12 deletions

76
srcts/canvas-async.ts Normal file
View File

@@ -0,0 +1,76 @@
import { RoughCanvas } from './canvas';
import { Config, Options, Drawable } from './core';
import { RoughGeneratorAsync } from './generator-async';
import { Point } from './geometry';
export class RoughCanvasAsync extends RoughCanvas {
private genAsync: RoughGeneratorAsync;
constructor(canvas: HTMLCanvasElement, config?: Config) {
super(canvas, config);
this.genAsync = new RoughGeneratorAsync(config || null, this.canvas);
}
// @ts-ignore
async line(x1: number, y1: number, x2: number, y2: number, options?: Options): Promise<Drawable> {
const d = await this.genAsync.line(x1, y1, x2, y2, options);
this.draw(d);
return d;
}
// @ts-ignore
async rectangle(x: number, y: number, width: number, height: number, options?: Options): Promise<Drawable> {
const d = await this.genAsync.rectangle(x, y, width, height, options);
this.draw(d);
return d;
}
// @ts-ignore
async ellipse(x: number, y: number, width: number, height: number, options?: Options): Promise<Drawable> {
const d = await this.genAsync.ellipse(x, y, width, height, options);
this.draw(d);
return d;
}
// @ts-ignore
async circle(x: number, y: number, diameter: number, options?: Options): Promise<Drawable> {
const d = await this.genAsync.circle(x, y, diameter, options);
this.draw(d);
return d;
}
// @ts-ignore
async linearPath(points: Point[], options?: Options): Promise<Drawable> {
const d = await this.genAsync.linearPath(points, options);
this.draw(d);
return d;
}
// @ts-ignore
async polygon(points: Point[], options?: Options): Promise<Drawable> {
const d = await this.genAsync.polygon(points, options);
this.draw(d);
return d;
}
// @ts-ignore
async arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed: boolean = false, options?: Options): Promise<Drawable> {
const d = await this.genAsync.arc(x, y, width, height, start, stop, closed, options);
this.draw(d);
return d;
}
// @ts-ignore
async curve(points: Point[], options?: Options): Promise<Drawable> {
const d = await this.genAsync.curve(points, options);
this.draw(d);
return d;
}
// @ts-ignore
async path(d: string, options?: Options): Promise<Drawable> {
const drawing = await this.genAsync.path(d, options);
this.draw(drawing);
return drawing;
}
}

View File

@@ -6,8 +6,8 @@ import { Point } from './geometry';
const hasDocument = typeof document !== 'undefined';
export class RoughCanvas {
private canvas: HTMLCanvasElement;
private ctx: CanvasRenderingContext2D;
protected canvas: HTMLCanvasElement;
protected ctx: CanvasRenderingContext2D;
private gen: RoughGenerator;
constructor(canvas: HTMLCanvasElement, config?: Config) {

125
srcts/generator-async.ts Normal file
View File

@@ -0,0 +1,125 @@
import { RoughGenerator } from './generator';
import { Options, Drawable, OpSet } from './core';
import { Point } from './geometry.js';
export class RoughGeneratorAsync extends RoughGenerator {
// @ts-ignore
async line(x1: number, y1: number, x2: number, y2: number, options?: Options): Promise<Drawable> {
const o = this._options(options);
return this._drawable('line', [await this.lib.line(x1, y1, x2, y2, o)], o);
}
// @ts-ignore
async rectangle(x: number, y: number, width: number, height: number, options?: Options): Promise<Drawable> {
const o = this._options(options);
const paths = [];
if (o.fill) {
const points: Point[] = [[x, y], [x + width, y], [x + width, y + height], [x, y + height]];
if (o.fillStyle === 'solid') {
paths.push(await this.lib.solidFillPolygon(points, o));
} else {
paths.push(await this.lib.patternFillPolygon(points, o));
}
}
paths.push(await this.lib.rectangle(x, y, width, height, o));
return this._drawable('rectangle', paths, o);
}
// @ts-ignore
async ellipse(x: number, y: number, width: number, height: number, options?: Options): Promise<Drawable> {
const o = this._options(options);
const paths = [];
if (o.fill) {
if (o.fillStyle === 'solid') {
const shape = await this.lib.ellipse(x, y, width, height, o);
shape.type = 'fillPath';
paths.push(shape);
} else {
paths.push(await this.lib.patternFillEllipse(x, y, width, height, o));
}
}
paths.push(await this.lib.ellipse(x, y, width, height, o));
return this._drawable('ellipse', paths, o);
}
// @ts-ignore
async circle(x: number, y: number, diameter: number, options?: Options): Promise<Drawable> {
const ret = await this.ellipse(x, y, diameter, diameter, options);
ret.shape = 'circle';
return ret;
}
// @ts-ignore
async linearPath(points: Point[], options?: Options): Promise<Drawable> {
const o = this._options(options);
return this._drawable('linearPath', [await this.lib.linearPath(points, false, o)], o);
}
// @ts-ignore
async polygon(points: Point[], options?: Options): Promise<Drawable> {
const o = this._options(options);
const paths = [];
if (o.fill) {
if (o.fillStyle === 'solid') {
paths.push(await this.lib.solidFillPolygon(points, o));
} else {
paths.push(await this.lib.patternFillPolygon(points, o));
}
}
paths.push(await this.lib.linearPath(points, true, o));
return this._drawable('polygon', paths, o);
}
// @ts-ignore
async arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed: boolean = false, options?: Options): Promise<Drawable> {
const o = this._options(options);
const paths = [];
if (closed && o.fill) {
if (o.fillStyle === 'solid') {
const shape = await this.lib.arc(x, y, width, height, start, stop, true, false, o);
shape.type = 'fillPath';
paths.push(shape);
} else {
paths.push(await this.lib.patternFillArc(x, y, width, height, start, stop, o));
}
}
paths.push(await this.lib.arc(x, y, width, height, start, stop, closed, true, o));
return this._drawable('arc', paths, o);
}
// @ts-ignore
async curve(points: Point[], options?: Options): Promise<Drawable> {
const o = this._options(options);
return this._drawable('curve', [await this.lib.curve(points, o)], o);
}
// @ts-ignore
async path(d: string, options?: Options): Promise<Drawable> {
const o = this._options(options);
const paths: OpSet[] = [];
if (!d) {
return this._drawable('path', paths, o);
}
if (o.fill) {
if (o.fillStyle === 'solid') {
const shape: OpSet = { type: 'path2Dfill', path: d, ops: [] };
paths.push(shape);
} else {
const size = this.computePathSize(d);
const points: Point[] = [
[0, 0],
[size[0], 0],
[size[0], size[1]],
[0, size[1]]
];
const shape = await this.lib.patternFillPolygon(points, o);
shape.type = 'path2Dpattern';
shape.size = size;
shape.path = d;
paths.push(shape);
}
}
paths.push(await this.lib.svgPath(d, o));
return this._drawable('path', paths, o);
}
}

View File

@@ -31,15 +31,15 @@ export class RoughGenerator {
}
}
private _options(options?: Options): Options {
protected _options(options?: Options): Options {
return options ? Object.assign({}, this.defaultOptions, options) : this.defaultOptions;
}
private _drawable(shape: string, sets: OpSet[], options: Options): Drawable {
protected _drawable(shape: string, sets: OpSet[], options: Options): Drawable {
return { shape, sets: sets || [], options: options || this.defaultOptions };
}
private get lib(): RoughRenderer {
protected get lib(): RoughRenderer {
if (!this.renderer) {
this.renderer = new RoughRenderer();
}
@@ -61,7 +61,7 @@ export class RoughGenerator {
return [100, 100];
}
private computePathSize(d: string): Point {
protected computePathSize(d: string): Point {
let size: Point = [0, 0];
if (hasSelf && self.document) {
try {

View File

@@ -2,11 +2,13 @@ import { Config, DrawingSurface } from './core';
import { RoughCanvas } from './canvas';
import { RoughRenderer } from './renderer';
import { RoughGenerator } from './generator';
import { RoughGeneratorAsync } from './generator-async';
import { RoughCanvasAsync } from './canvas-async';
export default {
canvas(canvas: HTMLCanvasElement, config?: Config): RoughCanvas {
canvas(canvas: HTMLCanvasElement, config?: Config) {
if (config && config.async) {
// TODO:
return new RoughCanvasAsync(canvas, config);
}
return new RoughCanvas(canvas, config);
},
@@ -16,10 +18,9 @@ export default {
},
generator(config: Config | null, surface: DrawingSurface) {
// if (config && config.async) {
// return new RoughGeneratorAsync(config, size);
// }
// return new RoughGenerator(config, size);
if (config && config.async) {
return new RoughGeneratorAsync(config, surface);
}
return new RoughGenerator(config, surface);
}
};