refactor: move Context to @idraw/util

This commit is contained in:
chenshenhai 2021-11-15 20:27:52 +08:00
parent 947c636745
commit 04960a7cd0
10 changed files with 76 additions and 294 deletions

View file

@ -1,11 +1,9 @@
import {
TypeScreenPosition, TypeScreenSize, TypeScreenContext, TypePoint, TypePointCursor,
TypeBoardOptions, TypeBoardSizeOptions, TypePlugin, } from '@idraw/types';
TypeBoardOptions, TypeBoardSizeOptions, TypePlugin, TypeContext } from '@idraw/types';
import util from '@idraw/util';
// import { Watcher } from './lib/watcher';
import { ScreenWatcher } from './lib/screen-watcher';
import { setStyle } from './lib/style';
import Context from './lib/context';
import { TypeBoardEventArgMap } from './lib/event';
import { Scroller } from './lib/scroller';
import { Screen } from './lib/screen';
@ -17,6 +15,7 @@ import {
_screen, _tempData
} from './names';
const { Context } = util;
const { throttle } = util.time;
type PrivateOptions = TypeBoardOptions & {
@ -29,7 +28,7 @@ class Board {
private [_mount]: HTMLDivElement;
private [_opts]: PrivateOptions;
private [_hasRendered] = false;
private [_ctx]: Context;
private [_ctx]: TypeContext;
private [_displayCtx]: CanvasRenderingContext2D;
private [_originCtx]: CanvasRenderingContext2D;
// private [_watcher]: Watcher;
@ -70,7 +69,7 @@ class Board {
return this[_originCtx];
}
getContext(): Context {
getContext(): TypeContext {
return this[_ctx];
}

View file

@ -1,282 +0,0 @@
import { TypeContext, TypeBoardSizeOptions } from '@idraw/types';
type Options = {
width: number;
height: number;
contextWidth: number;
contextHeight: number;
devicePixelRatio: number;
}
type Transform = {
scale?: number;
scrollX?: number;
scrollY?: number;
}
type PrivateTransform = {
scale: number;
scrollX: number;
scrollY: number;
}
class Context implements TypeContext {
private _opts: Options;
private _ctx: CanvasRenderingContext2D;
private _transform: PrivateTransform;
// private _scale: number;
// private _scrollX: number;
// private _scrollY: number;
constructor(ctx: CanvasRenderingContext2D, opts: Options) {
this._opts = opts;
this._ctx = ctx;
this._transform = {
scale: 1,
scrollX: 0,
scrollY: 0,
};
}
resetSize(opts: TypeBoardSizeOptions) {
this._opts = {...this._opts, ...opts};
}
calcDeviceNum(num: number): number {
return num * this._opts.devicePixelRatio;
}
calcScreenNum(num: number): number {
return num / this._opts.devicePixelRatio;
}
getSize() {
return {
width: this._opts.width,
height: this._opts.height,
contextWidth: this._opts.contextWidth,
contextHeight: this._opts.contextHeight,
devicePixelRatio: this._opts.devicePixelRatio,
};
}
setTransform(config: Transform) {
this._transform = {...this._transform, ...config};
}
getTransform() {
return {
scale: this._transform.scale,
scrollX: this._transform.scrollX,
scrollY: this._transform.scrollY,
};
}
setFillStyle(color: string | CanvasPattern | CanvasGradient) {
this._ctx.fillStyle = color;
}
fill(fillRule?: CanvasFillRule | undefined) {
return this._ctx.fill(fillRule || 'nonzero');
}
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean | undefined): void {
return this._ctx.arc(this._doSize(x), this._doSize(y), this._doSize(radius), startAngle, endAngle, anticlockwise);
}
rect(x: number, y: number, w: number, h: number) {
return this._ctx.rect(this._doSize(x), this._doSize(y), this._doSize(w), this._doSize(h));
}
fillRect(x: number, y: number, w: number, h: number) {
return this._ctx.fillRect(
this._doSize(x),
this._doSize(y),
this._doSize(w),
this._doSize(h)
);
}
clearRect(x: number, y: number, w: number, h: number) {
return this._ctx.clearRect(
this._doSize(x),
this._doSize(y),
this._doSize(w),
this._doSize(h)
);
}
beginPath() {
return this._ctx.beginPath();
}
closePath() {
return this._ctx.closePath();
}
lineTo(x: number, y: number) {
return this._ctx.lineTo(this._doSize(x), this._doSize(y));
}
moveTo(x: number, y: number) {
return this._ctx.moveTo(this._doSize(x), this._doSize(y));
}
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void {
return this._ctx.arcTo(this._doSize(x1), this._doSize(y1), this._doSize(x2), this._doSize(y2), this._doSize(radius));
}
setLineWidth(w: number) {
return this._ctx.lineWidth = this._doSize(w);
}
setLineDash(nums: number[]) {
return this._ctx.setLineDash(nums.map(n => this._doSize(n)));
}
isPointInPath(x: number, y: number) {
return this._ctx.isPointInPath(this._doX(x), this._doY(y));
}
isPointInPathWithoutScroll(x: number, y: number) {
return this._ctx.isPointInPath(this._doSize(x), this._doSize(y));
}
setStrokeStyle(color: string) {
this._ctx.strokeStyle = color;
}
stroke() {
return this._ctx.stroke();
}
translate(x: number, y: number) {
return this._ctx.translate(this._doSize(x), this._doSize(y));
}
rotate(angle: number) {
return this._ctx.rotate(angle);
}
drawImage(...args: any[]) {
const image: CanvasImageSource = args[0];
const sx: number = args[1];
const sy: number = args[2];
const sw: number = args[3];
const sh: number = args[4];
const dx: number = args[args.length - 4];
const dy: number = args[args.length - 3];
const dw: number = args[args.length - 2];
const dh: number = args[args.length - 1];
if (args.length === 9) {
return this._ctx.drawImage(image, this._doSize(sx), this._doSize(sy), this._doSize(sw), this._doSize(sh), this._doSize(dx), this._doSize(dy), this._doSize(dw), this._doSize(dh));
} else {
return this._ctx.drawImage(image,this._doSize(dx), this._doSize(dy), this._doSize(dw), this._doSize(dh));
}
}
createPattern(image: CanvasImageSource, repetition: string | null): CanvasPattern | null {
return this._ctx.createPattern(image, repetition);
}
measureText(text: string): TextMetrics {
return this._ctx.measureText(text);
}
setTextAlign(align: CanvasTextAlign): void {
this._ctx.textAlign = align;
}
fillText(text: string, x: number, y: number, maxWidth?: number | undefined): void {
if (maxWidth !== undefined) {
return this._ctx.fillText(text, this._doSize(x), this._doSize(y), this._doSize(maxWidth));
} else {
return this._ctx.fillText(text, this._doSize(x), this._doSize(y));
}
}
strokeText(text: string, x: number, y: number, maxWidth?: number | undefined): void {
if (maxWidth !== undefined) {
return this._ctx.strokeText(text, this._doSize(x), this._doSize(y), this._doSize(maxWidth));
} else {
return this._ctx.strokeText(text, this._doSize(x), this._doSize(y));
}
}
setFont(opts: { fontSize: number, fontFamily?: string, fontWeight?: 'bold' }): void {
const strList: string[] = [];
if (opts.fontWeight === 'bold') {
strList.push(`${opts.fontWeight}`);
}
strList.push(`${this._doSize(opts.fontSize || 12)}px`);
strList.push(`${opts.fontFamily || 'sans-serif'}`);
this._ctx.font = `${strList.join(' ')}`;
// console.log('this._ctx.font =',this._ctx.font);
}
setTextBaseline(baseline: CanvasTextBaseline): void {
this._ctx.textBaseline = baseline;
}
setGlobalAlpha(alpha: number): void {
this._ctx.globalAlpha = alpha;
}
save() {
this._ctx.save();
}
restore() {
this._ctx.restore();
}
scale(ratioX: number, ratioY: number) {
this._ctx.scale(ratioX, ratioY);
}
setShadowColor(color: string): void {
this._ctx.shadowColor = color;
}
setShadowOffsetX(offsetX: number): void {
this._ctx.shadowOffsetX = this._doSize(offsetX);
}
setShadowOffsetY(offsetY: number): void {
this._ctx.shadowOffsetY = this._doSize(offsetY);
}
setShadowBlur(blur: number): void {
this._ctx.shadowBlur = this._doSize(blur);
}
ellipse(
x: number,y: number, radiusX: number, radiusY: number,
rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean | undefined
) {
this._ctx.ellipse(this._doSize(x), this._doSize(y), this._doSize(radiusX), this._doSize(radiusY), rotation, startAngle, endAngle, counterclockwise)
}
private _doSize(num: number) {
return this._opts.devicePixelRatio * num;
}
private _doX(x: number) {
const { scale, scrollX } = this._transform;
const _x = (x - scrollX) / scale;
return this._doSize(_x);
}
private _doY(y: number) {
const { scale, scrollY } = this._transform;
const _y = (y - scrollY) / scale;
return this._doSize(_y);
}
}
export default Context;

View file

@ -1,9 +1,11 @@
import { TypePlugin, TypeBoardOptions } from '@idraw/types';
import Context from './context';
import { TypePlugin, TypeBoardOptions, TypeContext } from '@idraw/types';
import util from '@idraw/util';
const Context = util.Context;
type TempDataDesc = {
plugins: TypePlugin[],
ctx: Context,
ctx: TypeContext,
}

View file

@ -1,9 +1,12 @@
const _canvas = Symbol('_canvas');
const _displayCanvas = Symbol('_displayCanvas');
const _maskCanvas = Symbol('_maskCanvas');
const _mount = Symbol('_mount');
const _opts = Symbol('_opts');
const _hasRendered = Symbol('_hasRendered');
const _ctx = Symbol('_ctx');
const _maskCtx = Symbol('_maskCtx');
const _displayCtx = Symbol('_displayCtx');
const _originCtx = Symbol('_originCtx');
const _watcher = Symbol('_watcher');
@ -23,5 +26,5 @@ export {
_canvas, _displayCanvas, _mount, _opts, _hasRendered, _ctx, _displayCtx,
_originCtx, _watcher, _render, _parsePrivateOptions, _scroller,
_initEvent, _doScrollX, _doScrollY, _doMoveScroll, _resetContext,
_screen, _tempData,
_screen, _tempData, _maskCtx, _maskCanvas,
};

View file

@ -1,4 +1,5 @@
interface TypeContext {
getContext(): CanvasRenderingContext2D;
setTransform(config: {
scale?: number;
scrollX?: number;
@ -16,6 +17,13 @@ interface TypeContext {
contextHeight: number;
devicePixelRatio: number;
};
resetSize(opts: {
width?: number;
height?: number;
contextWidth?: number;
contextHeight?: number;
devicePixelRatio?: number;
}): void;
calcDeviceNum(num: number): number;
calcScreenNum(num: number): number;

View file

@ -1,6 +1,6 @@
import Context from './../../src/lib/context';
import util from '@idraw/util'
import { getData } from './../data';
import util from './../../src'
import { getData } from './data';
const { deepClone } = util.data;

View file

@ -0,0 +1,49 @@
export function getData() {
const data = {
elements: [
{
x: 10,
y: 10,
w: 200,
h: 120,
type: 'rect',
desc: {
color: '#f0f0f0',
}
},
{
x: 80,
y: 80,
w: 200,
h: 120,
type: 'rect',
desc: {
color: '#cccccc',
}
},
{
x: 160,
y: 160,
w: 200,
h: 120,
type: 'rect',
desc: {
color: '#c0c0c0',
}
},
{
x: 400 - 10,
y: 300 - 10,
w: 200,
h: 100,
type: 'rect',
desc: {
color: '#e0e0e0',
}
}
]
}
return data;
};

View file

@ -37,5 +37,5 @@ export default {
data: {
deepClone,
},
Context,
Context: Context,
};

View file

@ -38,6 +38,9 @@ class Context implements TypeContext {
scrollY: 0,
};
}
getContext(): CanvasRenderingContext2D {
return this._ctx;
}
resetSize(opts: TypeBoardSizeOptions) {
this._opts = {...this._opts, ...opts};