mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
refactor: move Context to @idraw/util
This commit is contained in:
parent
947c636745
commit
04960a7cd0
10 changed files with 76 additions and 294 deletions
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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,
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
49
packages/util/__tests__/lib/data.ts
Normal file
49
packages/util/__tests__/lib/data.ts
Normal 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;
|
||||
};
|
||||
|
|
@ -37,5 +37,5 @@ export default {
|
|||
data: {
|
||||
deepClone,
|
||||
},
|
||||
Context,
|
||||
Context: Context,
|
||||
};
|
||||
|
|
@ -38,6 +38,9 @@ class Context implements TypeContext {
|
|||
scrollY: 0,
|
||||
};
|
||||
}
|
||||
getContext(): CanvasRenderingContext2D {
|
||||
return this._ctx;
|
||||
}
|
||||
|
||||
resetSize(opts: TypeBoardSizeOptions) {
|
||||
this._opts = {...this._opts, ...opts};
|
||||
|
|
|
|||
Loading…
Reference in a new issue