mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
refactor: move context to util
This commit is contained in:
parent
feeff73013
commit
f9a28c3bad
3 changed files with 288 additions and 1 deletions
|
|
@ -22,6 +22,9 @@
|
|||
"homepage": "https://github.com/idrawjs/idraw#readme",
|
||||
"author": "chenshenhai",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@idraw/types": "^0.2.0-alpha.16"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { createUUID } from './lib/uuid';
|
|||
import { deepClone } from './lib/data';
|
||||
import istype from './lib/istype';
|
||||
import { loadImage, loadSVG, loadHTML } from './lib/loader';
|
||||
import Context from './lib/context';
|
||||
|
||||
export default {
|
||||
time: {
|
||||
|
|
@ -31,5 +32,6 @@ export default {
|
|||
istype,
|
||||
data: {
|
||||
deepClone,
|
||||
}
|
||||
},
|
||||
Context,
|
||||
};
|
||||
282
packages/util/src/lib/context.ts
Normal file
282
packages/util/src/lib/context.ts
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
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;
|
||||
Loading…
Reference in a new issue