@idraw/renderer 0.2.0-alpha.26 → 0.3.0-0.3.0-beta.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/esm/constant/element.d.ts +2 -0
- package/dist/esm/constant/element.js +10 -0
- package/dist/esm/constant/static.d.ts +11 -0
- package/dist/esm/constant/static.js +13 -0
- package/dist/esm/index.d.ts +26 -0
- package/dist/esm/index.js +137 -0
- package/dist/esm/lib/calculate.d.ts +5 -0
- package/dist/esm/lib/calculate.js +64 -0
- package/dist/esm/lib/diff.d.ts +6 -0
- package/dist/esm/lib/diff.js +82 -0
- package/dist/esm/lib/draw/base.d.ts +5 -0
- package/dist/esm/lib/draw/base.js +89 -0
- package/dist/esm/lib/draw/circle.d.ts +2 -0
- package/dist/esm/lib/draw/circle.js +28 -0
- package/dist/esm/lib/draw/html.d.ts +3 -0
- package/dist/esm/lib/draw/html.js +9 -0
- package/dist/esm/lib/draw/image.d.ts +3 -0
- package/dist/esm/lib/draw/image.js +9 -0
- package/dist/esm/lib/draw/index.d.ts +3 -0
- package/dist/esm/lib/draw/index.js +55 -0
- package/dist/esm/lib/draw/rect.d.ts +2 -0
- package/dist/esm/lib/draw/rect.js +4 -0
- package/dist/esm/lib/draw/svg.d.ts +3 -0
- package/dist/esm/lib/draw/svg.js +9 -0
- package/dist/esm/lib/draw/text.d.ts +3 -0
- package/dist/esm/lib/draw/text.js +128 -0
- package/dist/esm/lib/index.d.ts +6 -0
- package/dist/esm/lib/index.js +6 -0
- package/dist/esm/lib/loader-event.d.ts +33 -0
- package/dist/esm/lib/loader-event.js +50 -0
- package/dist/esm/lib/loader.d.ts +25 -0
- package/dist/esm/lib/loader.js +246 -0
- package/dist/esm/lib/parse.d.ts +2 -0
- package/dist/esm/lib/parse.js +32 -0
- package/dist/esm/lib/renderer-event.d.ts +32 -0
- package/dist/esm/lib/renderer-event.js +50 -0
- package/dist/esm/lib/temp.d.ts +22 -0
- package/dist/esm/lib/temp.js +29 -0
- package/dist/esm/lib/transform.d.ts +4 -0
- package/dist/esm/lib/transform.js +20 -0
- package/dist/esm/lib/value.d.ts +2 -0
- package/dist/esm/lib/value.js +7 -0
- package/dist/esm/util/filter.d.ts +1 -0
- package/dist/esm/util/filter.js +3 -0
- package/dist/index.global.js +1198 -1549
- package/dist/index.global.min.js +1 -1
- package/package.json +9 -12
- package/dist/index.cjs.js +0 -1598
- package/dist/index.d.ts +0 -82
- package/dist/index.es.js +0 -1596
package/LICENSE
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare enum Mode {
|
|
2
|
+
NULL = "null",
|
|
3
|
+
SELECT_ELEMENT = "select-element",
|
|
4
|
+
SELECT_ELEMENT_LIST = "select-element-list",
|
|
5
|
+
SELECT_ELEMENT_WRAPPER_CONTROLLER = "select-element-wrapper-controller",
|
|
6
|
+
SELECT_AREA = "select-area"
|
|
7
|
+
}
|
|
8
|
+
export declare enum CursorStatus {
|
|
9
|
+
DRAGGING = "dragging",
|
|
10
|
+
NULL = "null"
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export var Mode;
|
|
2
|
+
(function (Mode) {
|
|
3
|
+
Mode["NULL"] = "null";
|
|
4
|
+
Mode["SELECT_ELEMENT"] = "select-element";
|
|
5
|
+
Mode["SELECT_ELEMENT_LIST"] = "select-element-list";
|
|
6
|
+
Mode["SELECT_ELEMENT_WRAPPER_CONTROLLER"] = "select-element-wrapper-controller";
|
|
7
|
+
Mode["SELECT_AREA"] = "select-area";
|
|
8
|
+
})(Mode || (Mode = {}));
|
|
9
|
+
export var CursorStatus;
|
|
10
|
+
(function (CursorStatus) {
|
|
11
|
+
CursorStatus["DRAGGING"] = "dragging";
|
|
12
|
+
CursorStatus["NULL"] = "null";
|
|
13
|
+
})(CursorStatus || (CursorStatus = {}));
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { IDrawData, IDrawContext } from '@idraw/types';
|
|
2
|
+
import { RendererEvent } from './lib/renderer-event';
|
|
3
|
+
type Options = {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
contextWidth?: number;
|
|
7
|
+
contextHeight?: number;
|
|
8
|
+
devicePixelRatio: number;
|
|
9
|
+
};
|
|
10
|
+
export default class Renderer extends RendererEvent {
|
|
11
|
+
private _queue;
|
|
12
|
+
private _ctx;
|
|
13
|
+
private _status;
|
|
14
|
+
private _loader;
|
|
15
|
+
private _opts?;
|
|
16
|
+
constructor(opts?: Options);
|
|
17
|
+
render(target: HTMLCanvasElement | IDrawContext, originData: IDrawData, opts?: {
|
|
18
|
+
changeResourceUUIDs?: string[];
|
|
19
|
+
}): void;
|
|
20
|
+
getContext(): IDrawContext | null;
|
|
21
|
+
thaw(): void;
|
|
22
|
+
private _freeze;
|
|
23
|
+
private _drawFrame;
|
|
24
|
+
private _retainQueueOneItem;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { createUUID, deepClone, Context } from '@idraw/util';
|
|
2
|
+
import { drawContext } from './lib/draw';
|
|
3
|
+
import Loader from './lib/loader';
|
|
4
|
+
import { RendererEvent } from './lib/renderer-event';
|
|
5
|
+
const { requestAnimationFrame } = window;
|
|
6
|
+
var DrawStatus;
|
|
7
|
+
(function (DrawStatus) {
|
|
8
|
+
DrawStatus["NULL"] = "null";
|
|
9
|
+
DrawStatus["FREE"] = "free";
|
|
10
|
+
DrawStatus["DRAWING"] = "drawing";
|
|
11
|
+
DrawStatus["FREEZE"] = "freeze";
|
|
12
|
+
})(DrawStatus || (DrawStatus = {}));
|
|
13
|
+
export default class Renderer extends RendererEvent {
|
|
14
|
+
constructor(opts) {
|
|
15
|
+
super();
|
|
16
|
+
this._queue = [];
|
|
17
|
+
this._ctx = null;
|
|
18
|
+
this._status = DrawStatus.NULL;
|
|
19
|
+
this._opts = opts;
|
|
20
|
+
this._loader = new Loader({
|
|
21
|
+
maxParallelNum: 6
|
|
22
|
+
});
|
|
23
|
+
this._loader.on('load', (res) => {
|
|
24
|
+
this._drawFrame();
|
|
25
|
+
this.trigger('load', { element: res.element });
|
|
26
|
+
});
|
|
27
|
+
this._loader.on('error', (res) => {
|
|
28
|
+
this.trigger('error', { element: res.element, error: res.error });
|
|
29
|
+
});
|
|
30
|
+
this._loader.on('complete', () => {
|
|
31
|
+
this.trigger('loadComplete', { t: Date.now() });
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
render(target, originData, opts) {
|
|
35
|
+
const { changeResourceUUIDs = [] } = opts || {};
|
|
36
|
+
this._status = DrawStatus.FREE;
|
|
37
|
+
const data = deepClone(originData);
|
|
38
|
+
if (Array.isArray(data.elements)) {
|
|
39
|
+
data.elements.forEach((elem) => {
|
|
40
|
+
if (!(typeof elem.uuid === 'string' && elem.uuid)) {
|
|
41
|
+
elem.uuid = createUUID();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
if (!this._ctx) {
|
|
46
|
+
if (this._opts &&
|
|
47
|
+
Object.prototype.toString.call(target) === '[object HTMLCanvasElement]') {
|
|
48
|
+
const { width, height, contextWidth, contextHeight, devicePixelRatio } = this._opts;
|
|
49
|
+
const canvas = target;
|
|
50
|
+
canvas.width = width * devicePixelRatio;
|
|
51
|
+
canvas.height = height * devicePixelRatio;
|
|
52
|
+
const ctx2d = canvas.getContext('2d');
|
|
53
|
+
this._ctx = new Context(ctx2d, {
|
|
54
|
+
width,
|
|
55
|
+
height,
|
|
56
|
+
contextWidth: contextWidth || width,
|
|
57
|
+
contextHeight: contextHeight || height,
|
|
58
|
+
devicePixelRatio
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
else if (target) {
|
|
62
|
+
this._ctx = target;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if ([DrawStatus.FREEZE].includes(this._status)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const _data = deepClone({ data });
|
|
69
|
+
this._queue.push(_data);
|
|
70
|
+
this._drawFrame();
|
|
71
|
+
this._loader.load(data, changeResourceUUIDs || []);
|
|
72
|
+
}
|
|
73
|
+
getContext() {
|
|
74
|
+
return this._ctx;
|
|
75
|
+
}
|
|
76
|
+
thaw() {
|
|
77
|
+
this._status = DrawStatus.FREE;
|
|
78
|
+
}
|
|
79
|
+
_freeze() {
|
|
80
|
+
this._status = DrawStatus.FREEZE;
|
|
81
|
+
}
|
|
82
|
+
_drawFrame() {
|
|
83
|
+
if (this._status === DrawStatus.FREEZE) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
requestAnimationFrame(() => {
|
|
87
|
+
if (this._status === DrawStatus.FREEZE) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const ctx = this._ctx;
|
|
91
|
+
let item = this._queue[0];
|
|
92
|
+
let isLastFrame = false;
|
|
93
|
+
if (this._queue.length > 1) {
|
|
94
|
+
item = this._queue.shift();
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
isLastFrame = true;
|
|
98
|
+
}
|
|
99
|
+
if (this._loader.isComplete() !== true) {
|
|
100
|
+
this._drawFrame();
|
|
101
|
+
if (item && ctx) {
|
|
102
|
+
drawContext(ctx, item.data, this._loader);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (item && ctx) {
|
|
106
|
+
drawContext(ctx, item.data, this._loader);
|
|
107
|
+
this._retainQueueOneItem();
|
|
108
|
+
if (!isLastFrame) {
|
|
109
|
+
this._drawFrame();
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
this._status = DrawStatus.FREE;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
this._status = DrawStatus.FREE;
|
|
117
|
+
}
|
|
118
|
+
this.trigger('drawFrame', { t: Date.now() });
|
|
119
|
+
if (this._loader.isComplete() === true &&
|
|
120
|
+
this._queue.length === 1 &&
|
|
121
|
+
this._status === DrawStatus.FREE) {
|
|
122
|
+
if (ctx && this._queue[0] && this._queue[0].data) {
|
|
123
|
+
drawContext(ctx, this._queue[0].data, this._loader);
|
|
124
|
+
}
|
|
125
|
+
this.trigger('drawFrameComplete', { t: Date.now() });
|
|
126
|
+
this._freeze();
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
_retainQueueOneItem() {
|
|
131
|
+
if (this._queue.length <= 1) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const lastOne = deepClone(this._queue[this._queue.length - 1]);
|
|
135
|
+
this._queue = [lastOne];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DataElement, DataElemDesc, Point } from '@idraw/types';
|
|
2
|
+
export declare function parseRadianToAngle(radian: number): number;
|
|
3
|
+
export declare function parseAngleToRadian(angle: number): number;
|
|
4
|
+
export declare function calcElementCenter(elem: DataElement<keyof DataElemDesc>): Point;
|
|
5
|
+
export declare function calcRadian(center: Point, start: Point, end: Point): number;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export function parseRadianToAngle(radian) {
|
|
2
|
+
return (radian / Math.PI) * 180;
|
|
3
|
+
}
|
|
4
|
+
export function parseAngleToRadian(angle) {
|
|
5
|
+
return (angle / 180) * Math.PI;
|
|
6
|
+
}
|
|
7
|
+
export function calcElementCenter(elem) {
|
|
8
|
+
const p = {
|
|
9
|
+
x: elem.x + elem.w / 2,
|
|
10
|
+
y: elem.y + elem.h / 2
|
|
11
|
+
};
|
|
12
|
+
return p;
|
|
13
|
+
}
|
|
14
|
+
export function calcRadian(center, start, end) {
|
|
15
|
+
const startAngle = calcLineAngle(center, start);
|
|
16
|
+
const endAngle = calcLineAngle(center, end);
|
|
17
|
+
if (endAngle !== null && startAngle !== null) {
|
|
18
|
+
if (startAngle > (Math.PI * 3) / 2 && endAngle < Math.PI / 2) {
|
|
19
|
+
return endAngle + (Math.PI * 2 - startAngle);
|
|
20
|
+
}
|
|
21
|
+
else if (endAngle > (Math.PI * 3) / 2 && startAngle < Math.PI / 2) {
|
|
22
|
+
return startAngle + (Math.PI * 2 - endAngle);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return endAngle - startAngle;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function calcLineAngle(center, p) {
|
|
33
|
+
const x = p.x - center.x;
|
|
34
|
+
const y = center.y - p.y;
|
|
35
|
+
if (x === 0) {
|
|
36
|
+
if (y < 0) {
|
|
37
|
+
return Math.PI / 2;
|
|
38
|
+
}
|
|
39
|
+
else if (y > 0) {
|
|
40
|
+
return Math.PI * (3 / 2);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else if (y === 0) {
|
|
44
|
+
if (x < 0) {
|
|
45
|
+
return Math.PI;
|
|
46
|
+
}
|
|
47
|
+
else if (x > 0) {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (x > 0 && y < 0) {
|
|
52
|
+
return Math.atan(Math.abs(y) / Math.abs(x));
|
|
53
|
+
}
|
|
54
|
+
else if (x < 0 && y < 0) {
|
|
55
|
+
return Math.PI - Math.atan(Math.abs(y) / Math.abs(x));
|
|
56
|
+
}
|
|
57
|
+
else if (x < 0 && y > 0) {
|
|
58
|
+
return Math.PI + Math.atan(Math.abs(y) / Math.abs(x));
|
|
59
|
+
}
|
|
60
|
+
else if (x > 0 && y > 0) {
|
|
61
|
+
return Math.PI * 2 - Math.atan(Math.abs(y) / Math.abs(x));
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DataElement, IDrawData, DataElemDesc } from '@idraw/types';
|
|
2
|
+
export declare function isChangeImageElementResource(before: DataElement<'image'>, after: DataElement<'image'>): boolean;
|
|
3
|
+
export declare function isChangeSVGElementResource(before: DataElement<'svg'>, after: DataElement<'svg'>): boolean;
|
|
4
|
+
export declare function isChangeHTMLElementResource(before: DataElement<'html'>, after: DataElement<'html'>): boolean;
|
|
5
|
+
export declare function diffElementResourceChange(before: DataElement<keyof DataElemDesc>, after: DataElement<keyof DataElemDesc>): string | null;
|
|
6
|
+
export declare function diffElementResourceChangeList(before: IDrawData, after: IDrawData): string[];
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export function isChangeImageElementResource(before, after) {
|
|
2
|
+
var _a, _b;
|
|
3
|
+
return ((_a = before === null || before === void 0 ? void 0 : before.desc) === null || _a === void 0 ? void 0 : _a.src) !== ((_b = after === null || after === void 0 ? void 0 : after.desc) === null || _b === void 0 ? void 0 : _b.src);
|
|
4
|
+
}
|
|
5
|
+
export function isChangeSVGElementResource(before, after) {
|
|
6
|
+
var _a, _b;
|
|
7
|
+
return ((_a = before === null || before === void 0 ? void 0 : before.desc) === null || _a === void 0 ? void 0 : _a.svg) !== ((_b = after === null || after === void 0 ? void 0 : after.desc) === null || _b === void 0 ? void 0 : _b.svg);
|
|
8
|
+
}
|
|
9
|
+
export function isChangeHTMLElementResource(before, after) {
|
|
10
|
+
var _a, _b, _c, _d, _e, _f;
|
|
11
|
+
return (((_a = before === null || before === void 0 ? void 0 : before.desc) === null || _a === void 0 ? void 0 : _a.html) !== ((_b = after === null || after === void 0 ? void 0 : after.desc) === null || _b === void 0 ? void 0 : _b.html) ||
|
|
12
|
+
((_c = before === null || before === void 0 ? void 0 : before.desc) === null || _c === void 0 ? void 0 : _c.width) !== ((_d = after === null || after === void 0 ? void 0 : after.desc) === null || _d === void 0 ? void 0 : _d.width) ||
|
|
13
|
+
((_e = before === null || before === void 0 ? void 0 : before.desc) === null || _e === void 0 ? void 0 : _e.height) !== ((_f = after === null || after === void 0 ? void 0 : after.desc) === null || _f === void 0 ? void 0 : _f.height));
|
|
14
|
+
}
|
|
15
|
+
export function diffElementResourceChange(before, after) {
|
|
16
|
+
let result = null;
|
|
17
|
+
let isChange = false;
|
|
18
|
+
switch (after.type) {
|
|
19
|
+
case 'image': {
|
|
20
|
+
isChange = isChangeImageElementResource(before, after);
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
case 'svg': {
|
|
24
|
+
isChange = isChangeSVGElementResource(before, after);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
case 'html': {
|
|
28
|
+
isChange = isChangeHTMLElementResource(before, after);
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
default:
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
if (isChange === true) {
|
|
35
|
+
result = after.uuid;
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
export function diffElementResourceChangeList(before, after) {
|
|
40
|
+
var _a;
|
|
41
|
+
const uuids = [];
|
|
42
|
+
const beforeMap = parseDataElementMap(before);
|
|
43
|
+
const afterMap = parseDataElementMap(after);
|
|
44
|
+
for (const uuid in afterMap) {
|
|
45
|
+
if (['image', 'svg', 'html'].includes((_a = afterMap[uuid]) === null || _a === void 0 ? void 0 : _a.type) !== true) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (beforeMap[uuid]) {
|
|
49
|
+
let isChange = false;
|
|
50
|
+
switch (beforeMap[uuid].type) {
|
|
51
|
+
case 'image': {
|
|
52
|
+
isChange = isChangeImageElementResource(beforeMap[uuid], afterMap[uuid]);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case 'svg': {
|
|
56
|
+
isChange = isChangeSVGElementResource(beforeMap[uuid], afterMap[uuid]);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case 'html': {
|
|
60
|
+
isChange = isChangeHTMLElementResource(beforeMap[uuid], afterMap[uuid]);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
default:
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
if (isChange === true) {
|
|
67
|
+
uuids.push(uuid);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
uuids.push(uuid);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return uuids;
|
|
75
|
+
}
|
|
76
|
+
function parseDataElementMap(data) {
|
|
77
|
+
const elemMap = {};
|
|
78
|
+
data.elements.forEach((elem) => {
|
|
79
|
+
elemMap[elem.uuid] = elem;
|
|
80
|
+
});
|
|
81
|
+
return elemMap;
|
|
82
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { IDrawContext, DataElement } from '@idraw/types';
|
|
2
|
+
export declare function clearContext(ctx: IDrawContext): void;
|
|
3
|
+
export declare function drawBgColor(ctx: IDrawContext, color: string): void;
|
|
4
|
+
export declare function drawBox(ctx: IDrawContext, elem: DataElement<'text' | 'rect'>, pattern: string | CanvasPattern | null): void;
|
|
5
|
+
export declare function drawBoxBorder(ctx: IDrawContext, elem: DataElement<'text' | 'rect'>): void;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { is, istype, isColorStr } from '@idraw/util';
|
|
2
|
+
import { rotateElement } from './../transform';
|
|
3
|
+
export function clearContext(ctx) {
|
|
4
|
+
ctx.setFillStyle('#000000');
|
|
5
|
+
ctx.setStrokeStyle('#000000');
|
|
6
|
+
ctx.setLineDash([]);
|
|
7
|
+
ctx.setGlobalAlpha(1);
|
|
8
|
+
ctx.setShadowColor('#00000000');
|
|
9
|
+
ctx.setShadowOffsetX(0);
|
|
10
|
+
ctx.setShadowOffsetY(0);
|
|
11
|
+
ctx.setShadowBlur(0);
|
|
12
|
+
}
|
|
13
|
+
export function drawBgColor(ctx, color) {
|
|
14
|
+
const size = ctx.getSize();
|
|
15
|
+
ctx.setFillStyle(color);
|
|
16
|
+
ctx.fillRect(0, 0, size.contextWidth, size.contextHeight);
|
|
17
|
+
}
|
|
18
|
+
export function drawBox(ctx, elem, pattern) {
|
|
19
|
+
clearContext(ctx);
|
|
20
|
+
drawBoxBorder(ctx, elem);
|
|
21
|
+
clearContext(ctx);
|
|
22
|
+
rotateElement(ctx, elem, () => {
|
|
23
|
+
const { x, y, w, h } = elem;
|
|
24
|
+
let r = elem.desc.borderRadius || 0;
|
|
25
|
+
r = Math.min(r, w / 2, h / 2);
|
|
26
|
+
if (w < r * 2 || h < r * 2) {
|
|
27
|
+
r = 0;
|
|
28
|
+
}
|
|
29
|
+
ctx.beginPath();
|
|
30
|
+
ctx.moveTo(x + r, y);
|
|
31
|
+
ctx.arcTo(x + w, y, x + w, y + h, r);
|
|
32
|
+
ctx.arcTo(x + w, y + h, x, y + h, r);
|
|
33
|
+
ctx.arcTo(x, y + h, x, y, r);
|
|
34
|
+
ctx.arcTo(x, y, x + w, y, r);
|
|
35
|
+
ctx.closePath();
|
|
36
|
+
if (typeof pattern === 'string') {
|
|
37
|
+
ctx.setFillStyle(pattern);
|
|
38
|
+
}
|
|
39
|
+
else if (['CanvasPattern'].includes(istype.type(pattern))) {
|
|
40
|
+
ctx.setFillStyle(pattern);
|
|
41
|
+
}
|
|
42
|
+
ctx.fill();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export function drawBoxBorder(ctx, elem) {
|
|
46
|
+
clearContext(ctx);
|
|
47
|
+
rotateElement(ctx, elem, () => {
|
|
48
|
+
if (!(elem.desc.borderWidth && elem.desc.borderWidth > 0)) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const bw = elem.desc.borderWidth;
|
|
52
|
+
let borderColor = '#000000';
|
|
53
|
+
if (isColorStr(elem.desc.borderColor) === true) {
|
|
54
|
+
borderColor = elem.desc.borderColor;
|
|
55
|
+
}
|
|
56
|
+
const x = elem.x - bw / 2;
|
|
57
|
+
const y = elem.y - bw / 2;
|
|
58
|
+
const w = elem.w + bw;
|
|
59
|
+
const h = elem.h + bw;
|
|
60
|
+
let r = elem.desc.borderRadius || 0;
|
|
61
|
+
r = Math.min(r, w / 2, h / 2);
|
|
62
|
+
if (r < w / 2 && r < h / 2) {
|
|
63
|
+
r = r + bw / 2;
|
|
64
|
+
}
|
|
65
|
+
const { desc } = elem;
|
|
66
|
+
if (desc.shadowColor !== undefined && isColorStr(desc.shadowColor)) {
|
|
67
|
+
ctx.setShadowColor(desc.shadowColor);
|
|
68
|
+
}
|
|
69
|
+
if (desc.shadowOffsetX !== undefined && is.number(desc.shadowOffsetX)) {
|
|
70
|
+
ctx.setShadowOffsetX(desc.shadowOffsetX);
|
|
71
|
+
}
|
|
72
|
+
if (desc.shadowOffsetY !== undefined && is.number(desc.shadowOffsetY)) {
|
|
73
|
+
ctx.setShadowOffsetY(desc.shadowOffsetY);
|
|
74
|
+
}
|
|
75
|
+
if (desc.shadowBlur !== undefined && is.number(desc.shadowBlur)) {
|
|
76
|
+
ctx.setShadowBlur(desc.shadowBlur);
|
|
77
|
+
}
|
|
78
|
+
ctx.beginPath();
|
|
79
|
+
ctx.setLineWidth(bw);
|
|
80
|
+
ctx.setStrokeStyle(borderColor);
|
|
81
|
+
ctx.moveTo(x + r, y);
|
|
82
|
+
ctx.arcTo(x + w, y, x + w, y + h, r);
|
|
83
|
+
ctx.arcTo(x + w, y + h, x, y + h, r);
|
|
84
|
+
ctx.arcTo(x, y + h, x, y, r);
|
|
85
|
+
ctx.arcTo(x, y, x + w, y, r);
|
|
86
|
+
ctx.closePath();
|
|
87
|
+
ctx.stroke();
|
|
88
|
+
});
|
|
89
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { rotateElement } from './../transform';
|
|
2
|
+
import { clearContext } from './base';
|
|
3
|
+
export function drawCircle(ctx, elem) {
|
|
4
|
+
clearContext(ctx);
|
|
5
|
+
rotateElement(ctx, elem, (ctx) => {
|
|
6
|
+
const { x, y, w, h, desc } = elem;
|
|
7
|
+
const { bgColor = '#000000', borderColor = '#000000', borderWidth = 0 } = desc;
|
|
8
|
+
const a = w / 2;
|
|
9
|
+
const b = h / 2;
|
|
10
|
+
const centerX = x + a;
|
|
11
|
+
const centerY = y + b;
|
|
12
|
+
if (borderWidth && borderWidth > 0) {
|
|
13
|
+
const ba = borderWidth / 2 + a;
|
|
14
|
+
const bb = borderWidth / 2 + b;
|
|
15
|
+
ctx.beginPath();
|
|
16
|
+
ctx.setStrokeStyle(borderColor);
|
|
17
|
+
ctx.setLineWidth(borderWidth);
|
|
18
|
+
ctx.ellipse(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI);
|
|
19
|
+
ctx.closePath();
|
|
20
|
+
ctx.stroke();
|
|
21
|
+
}
|
|
22
|
+
ctx.beginPath();
|
|
23
|
+
ctx.setFillStyle(bgColor);
|
|
24
|
+
ctx.ellipse(centerX, centerY, a, b, 0, 0, 2 * Math.PI);
|
|
25
|
+
ctx.closePath();
|
|
26
|
+
ctx.fill();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { rotateElement } from '../transform';
|
|
2
|
+
export function drawHTML(ctx, elem, loader) {
|
|
3
|
+
const content = loader.getContent(elem.uuid);
|
|
4
|
+
rotateElement(ctx, elem, () => {
|
|
5
|
+
if (content) {
|
|
6
|
+
ctx.drawImage(content, elem.x, elem.y, elem.w, elem.h);
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { rotateElement } from '../transform';
|
|
2
|
+
export function drawImage(ctx, elem, loader) {
|
|
3
|
+
const content = loader.getContent(elem.uuid);
|
|
4
|
+
rotateElement(ctx, elem, () => {
|
|
5
|
+
if (content) {
|
|
6
|
+
ctx.drawImage(content, elem.x, elem.y, elem.w, elem.h);
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { isColorStr } from '@idraw/util';
|
|
2
|
+
import { clearContext, drawBgColor } from './base';
|
|
3
|
+
import { drawRect } from './rect';
|
|
4
|
+
import { drawImage } from './image';
|
|
5
|
+
import { drawSVG } from './svg';
|
|
6
|
+
import { drawHTML } from './html';
|
|
7
|
+
import { drawText } from './text';
|
|
8
|
+
import { drawCircle } from './circle';
|
|
9
|
+
export function drawContext(ctx, data, loader) {
|
|
10
|
+
var _a;
|
|
11
|
+
clearContext(ctx);
|
|
12
|
+
const size = ctx.getSize();
|
|
13
|
+
ctx.clearRect(0, 0, size.contextWidth, size.contextHeight);
|
|
14
|
+
if (typeof data.bgColor === 'string' && isColorStr(data.bgColor)) {
|
|
15
|
+
drawBgColor(ctx, data.bgColor);
|
|
16
|
+
}
|
|
17
|
+
if (!(data.elements.length > 0)) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
for (let i = 0; i < data.elements.length; i++) {
|
|
21
|
+
const elem = data.elements[i];
|
|
22
|
+
if (((_a = elem === null || elem === void 0 ? void 0 : elem.operation) === null || _a === void 0 ? void 0 : _a.invisible) === true) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
switch (elem.type) {
|
|
26
|
+
case 'rect': {
|
|
27
|
+
drawRect(ctx, elem);
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
case 'text': {
|
|
31
|
+
drawText(ctx, elem, loader);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case 'image': {
|
|
35
|
+
drawImage(ctx, elem, loader);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case 'svg': {
|
|
39
|
+
drawSVG(ctx, elem, loader);
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case 'html': {
|
|
43
|
+
drawHTML(ctx, elem, loader);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
case 'circle': {
|
|
47
|
+
drawCircle(ctx, elem);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
default: {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { rotateElement } from '../transform';
|
|
2
|
+
export function drawSVG(ctx, elem, loader) {
|
|
3
|
+
const content = loader.getContent(elem.uuid);
|
|
4
|
+
rotateElement(ctx, elem, () => {
|
|
5
|
+
if (content) {
|
|
6
|
+
ctx.drawImage(content, elem.x, elem.y, elem.w, elem.h);
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
}
|