@idraw/renderer 0.4.0-beta.2 → 0.4.0-beta.20

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/README.md CHANGED
@@ -64,5 +64,5 @@ renderer.on('drawFrameComplete', (e) => {
64
64
 
65
65
  ## Documents
66
66
 
67
- - [Documents](https://idraw.js.org/docs/en/) | [中文文档](https://idraw.js.org/docs/zh/)
68
- - [Online Playground](https://idraw.js.org/playground/) | [在线API示例](https://idraw.js.org/playground/)
67
+ - [Documents](https://idrawjs.com/docs/en/) | [中文文档](https://idrawjs.com/docs/zh/)
68
+ - [Online Playground](https://idrawjs.com/playground/) | [在线API示例](https://idrawjs.com/playground/)
@@ -1,14 +1,25 @@
1
1
  import { ViewContext2D, Element, ElementType, ElementSize, ViewScaleInfo, ViewSizeInfo } from '@idraw/types';
2
- export declare function drawBox(ctx: ViewContext2D, viewElem: Element<ElementType>, opts: {
3
- originElem: Element<ElementType>;
2
+ export declare function getOpacity(elem: Element): number;
3
+ export declare function drawBox(ctx: ViewContext2D, viewElem: Element, opts: {
4
+ originElem: Element;
4
5
  calcElemSize: ElementSize;
5
6
  pattern?: string | CanvasPattern | null;
6
- renderContent: Function;
7
+ renderContent: () => void;
8
+ viewScaleInfo: ViewScaleInfo;
9
+ viewSizeInfo: ViewSizeInfo;
10
+ parentOpacity: number;
11
+ }): void;
12
+ export declare function drawBoxBackground(ctx: ViewContext2D, viewElem: Element<ElementType>, opts: {
13
+ pattern?: string | CanvasPattern | null;
14
+ viewScaleInfo: ViewScaleInfo;
15
+ viewSizeInfo: ViewSizeInfo;
16
+ }): void;
17
+ export declare function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>, opts: {
7
18
  viewScaleInfo: ViewScaleInfo;
8
19
  viewSizeInfo: ViewSizeInfo;
9
20
  }): void;
10
21
  export declare function drawBoxShadow(ctx: ViewContext2D, viewElem: Element<ElementType>, opts: {
11
22
  viewScaleInfo: ViewScaleInfo;
12
23
  viewSizeInfo: ViewSizeInfo;
13
- renderContent: Function;
24
+ renderContent: () => void;
14
25
  }): void;
@@ -1,31 +1,35 @@
1
1
  import { istype, isColorStr, generateSVGPath, rotateElement, is, getDefaultElementDetailConfig, calcViewBoxSize } from '@idraw/util';
2
2
  import { createColorStyle } from './color';
3
3
  const defaultElemConfig = getDefaultElementDetailConfig();
4
+ export function getOpacity(elem) {
5
+ var _a, _b, _c, _d;
6
+ let opacity = 1;
7
+ if (((_a = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _a === void 0 ? void 0 : _a.opacity) !== undefined && ((_b = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _b === void 0 ? void 0 : _b.opacity) >= 0 && ((_c = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _c === void 0 ? void 0 : _c.opacity) <= 1) {
8
+ opacity = (_d = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _d === void 0 ? void 0 : _d.opacity;
9
+ }
10
+ return opacity;
11
+ }
4
12
  export function drawBox(ctx, viewElem, opts) {
5
13
  const { pattern, renderContent, originElem, calcElemSize, viewScaleInfo, viewSizeInfo } = opts || {};
14
+ const { parentOpacity } = opts;
15
+ const opacity = getOpacity(originElem) * parentOpacity;
6
16
  drawClipPath(ctx, viewElem, {
7
17
  originElem,
8
18
  calcElemSize,
9
19
  viewScaleInfo,
10
20
  viewSizeInfo,
11
21
  renderContent: () => {
12
- var _a, _b;
13
- if (((_a = viewElem === null || viewElem === void 0 ? void 0 : viewElem.detail) === null || _a === void 0 ? void 0 : _a.opacity) !== undefined && ((_b = viewElem === null || viewElem === void 0 ? void 0 : viewElem.detail) === null || _b === void 0 ? void 0 : _b.opacity) >= 0) {
14
- ctx.globalAlpha = viewElem.detail.opacity;
15
- }
16
- else {
17
- ctx.globalAlpha = 1;
18
- }
22
+ ctx.globalAlpha = opacity;
19
23
  drawBoxBackground(ctx, viewElem, { pattern, viewScaleInfo, viewSizeInfo });
20
24
  renderContent === null || renderContent === void 0 ? void 0 : renderContent();
21
25
  drawBoxBorder(ctx, viewElem, { viewScaleInfo, viewSizeInfo });
22
- ctx.globalAlpha = 1;
26
+ ctx.globalAlpha = parentOpacity;
23
27
  }
24
28
  });
25
29
  }
26
30
  function drawClipPath(ctx, viewElem, opts) {
27
- const { renderContent, originElem, calcElemSize, viewScaleInfo, viewSizeInfo } = opts;
28
- const totalScale = viewScaleInfo.scale * viewSizeInfo.devicePixelRatio;
31
+ const { renderContent, originElem, calcElemSize, viewSizeInfo } = opts;
32
+ const totalScale = viewSizeInfo.devicePixelRatio;
29
33
  const { clipPath } = (originElem === null || originElem === void 0 ? void 0 : originElem.detail) || {};
30
34
  if (clipPath && calcElemSize && clipPath.commands) {
31
35
  const { x, y, w, h } = calcElemSize;
@@ -34,8 +38,8 @@ function drawClipPath(ctx, viewElem, opts) {
34
38
  const scaleH = h / originH;
35
39
  const viewOriginX = originX * scaleW;
36
40
  const viewOriginY = originY * scaleH;
37
- let internalX = x - viewOriginX;
38
- let internalY = y - viewOriginY;
41
+ const internalX = x - viewOriginX;
42
+ const internalY = y - viewOriginY;
39
43
  ctx.save();
40
44
  ctx.translate(internalX, internalY);
41
45
  ctx.scale(totalScale * scaleW, totalScale * scaleH);
@@ -53,14 +57,10 @@ function drawClipPath(ctx, viewElem, opts) {
53
57
  renderContent === null || renderContent === void 0 ? void 0 : renderContent();
54
58
  }
55
59
  }
56
- function drawBoxBackground(ctx, viewElem, opts) {
60
+ export function drawBoxBackground(ctx, viewElem, opts) {
57
61
  var _a, _b;
58
62
  const { pattern, viewScaleInfo, viewSizeInfo } = opts;
59
- let transform = [];
60
- let { borderRadius, borderWidth } = viewElem.detail;
61
- if (typeof borderWidth !== 'number') {
62
- borderRadius = 0;
63
- }
63
+ const transform = [];
64
64
  if (viewElem.detail.background || pattern) {
65
65
  const { x, y, w, h, radiusList } = calcViewBoxSize(viewElem, {
66
66
  viewScaleInfo,
@@ -118,20 +118,13 @@ function drawBoxBackground(ctx, viewElem, opts) {
118
118
  }
119
119
  }
120
120
  }
121
- function drawBoxBorder(ctx, viewElem, opts) {
122
- var _a, _b;
121
+ export function drawBoxBorder(ctx, viewElem, opts) {
123
122
  if (viewElem.detail.borderWidth === 0) {
124
123
  return;
125
124
  }
126
125
  if (!isColorStr(viewElem.detail.borderColor)) {
127
126
  return;
128
127
  }
129
- if (((_a = viewElem === null || viewElem === void 0 ? void 0 : viewElem.detail) === null || _a === void 0 ? void 0 : _a.opacity) !== undefined && ((_b = viewElem === null || viewElem === void 0 ? void 0 : viewElem.detail) === null || _b === void 0 ? void 0 : _b.opacity) >= 0) {
130
- ctx.globalAlpha = viewElem.detail.opacity;
131
- }
132
- else {
133
- ctx.globalAlpha = 1;
134
- }
135
128
  const { viewScaleInfo } = opts;
136
129
  const { scale } = viewScaleInfo;
137
130
  let borderColor = defaultElemConfig.borderColor;
@@ -262,7 +255,6 @@ function drawBoxBorder(ctx, viewElem, opts) {
262
255
  ctx.arcTo(x, y, x + w, y, radiusList[0]);
263
256
  ctx.closePath();
264
257
  ctx.stroke();
265
- ctx.globalAlpha = 1;
266
258
  }
267
259
  ctx.setLineDash([]);
268
260
  }
@@ -280,6 +272,12 @@ export function drawBoxShadow(ctx, viewElem, opts) {
280
272
  ctx.restore();
281
273
  }
282
274
  else {
275
+ ctx.save();
276
+ ctx.shadowColor = 'transparent';
277
+ ctx.shadowOffsetX = 0;
278
+ ctx.shadowOffsetY = 0;
279
+ ctx.shadowBlur = 0;
283
280
  renderContent();
281
+ ctx.restore();
284
282
  }
285
283
  }
@@ -1,49 +1,68 @@
1
- import { rotateElement } from '@idraw/util';
1
+ import { rotateElement, calcViewElementSize } from '@idraw/util';
2
2
  import { createColorStyle } from './color';
3
- import { drawBoxShadow } from './box';
3
+ import { drawBoxShadow, getOpacity } from './box';
4
4
  export function drawCircle(ctx, elem, opts) {
5
5
  const { detail, angle } = elem;
6
- const { background = '#000000', borderColor = '#000000', borderWidth = 0 } = detail;
7
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
8
- const { x, y, w, h } = calculator.elementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h }, viewScaleInfo, viewSizeInfo);
6
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
7
+ const { background = '#000000', borderColor = '#000000', boxSizing, borderWidth = 0 } = detail;
8
+ let bw = 0;
9
+ if (typeof borderWidth === 'number' && borderWidth > 0) {
10
+ bw = borderWidth;
11
+ }
12
+ else if (Array.isArray(borderWidth) && typeof borderWidth[0] === 'number' && borderWidth[0] > 0) {
13
+ bw = borderWidth[0];
14
+ }
15
+ bw = bw * viewScaleInfo.scale;
16
+ const { x, y, w, h } = calcViewElementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h }, { viewScaleInfo, viewSizeInfo }) || elem;
9
17
  const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
10
18
  rotateElement(ctx, { x, y, w, h, angle }, () => {
11
19
  drawBoxShadow(ctx, viewElem, {
12
20
  viewScaleInfo,
13
21
  viewSizeInfo,
14
22
  renderContent: () => {
15
- var _a, _b;
16
- const a = w / 2;
17
- const b = h / 2;
23
+ let a = w / 2;
24
+ let b = h / 2;
18
25
  const centerX = x + a;
19
26
  const centerY = y + b;
20
- if (((_a = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _a === void 0 ? void 0 : _a.opacity) !== undefined && ((_b = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _b === void 0 ? void 0 : _b.opacity) >= 0) {
21
- ctx.globalAlpha = elem.detail.opacity;
27
+ if (bw > 0) {
28
+ if (boxSizing === 'border-box') {
29
+ a = a - bw;
30
+ b = b - bw;
31
+ }
32
+ else if (boxSizing === 'center-line') {
33
+ a = a - bw / 2;
34
+ b = b - bw / 2;
35
+ }
36
+ else {
37
+ a = a - bw;
38
+ b = b - bw;
39
+ }
22
40
  }
23
- else {
24
- ctx.globalAlpha = 1;
25
- }
26
- if (typeof borderWidth === 'number' && borderWidth > 0) {
27
- const ba = borderWidth / 2 + a;
28
- const bb = borderWidth / 2 + b;
41
+ if (a >= 0 && b >= 0) {
42
+ const opacity = getOpacity(viewElem) * parentOpacity;
43
+ ctx.globalAlpha = opacity;
44
+ if (typeof bw === 'number' && bw > 0) {
45
+ const ba = bw / 2 + a;
46
+ const bb = bw / 2 + b;
47
+ ctx.beginPath();
48
+ ctx.strokeStyle = borderColor;
49
+ ctx.lineWidth = bw;
50
+ ctx.circle(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI);
51
+ ctx.closePath();
52
+ ctx.stroke();
53
+ }
29
54
  ctx.beginPath();
30
- ctx.strokeStyle = borderColor;
31
- ctx.lineWidth = borderWidth;
32
- ctx.circle(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI);
55
+ const fillStyle = createColorStyle(ctx, background, {
56
+ viewElementSize: { x, y, w, h },
57
+ viewScaleInfo,
58
+ opacity: ctx.globalAlpha
59
+ });
60
+ ctx.fillStyle = fillStyle;
61
+ ctx.circle(centerX, centerY, a, b, 0, 0, 2 * Math.PI);
33
62
  ctx.closePath();
34
- ctx.stroke();
63
+ ctx.fill();
64
+ ctx.globalAlpha = parentOpacity;
35
65
  }
36
- ctx.beginPath();
37
- const fillStyle = createColorStyle(ctx, background, {
38
- viewElementSize: { x, y, w, h },
39
- viewScaleInfo,
40
- opacity: ctx.globalAlpha
41
- });
42
- ctx.fillStyle = fillStyle;
43
- ctx.circle(centerX, centerY, a, b, 0, 0, 2 * Math.PI);
44
- ctx.closePath();
45
- ctx.fill();
46
- ctx.globalAlpha = 1;
47
66
  }
48
67
  });
49
68
  });
@@ -2,17 +2,23 @@ import { getDefaultElementDetailConfig } from '@idraw/util';
2
2
  import { drawElement } from './group';
3
3
  const defaultDetail = getDefaultElementDetailConfig();
4
4
  export function drawElementList(ctx, data, opts) {
5
+ var _a;
5
6
  const { elements = [] } = data;
7
+ const { parentOpacity } = opts;
6
8
  for (let i = 0; i < elements.length; i++) {
7
9
  const element = elements[i];
8
10
  const elem = Object.assign(Object.assign({}, element), {
9
11
  detail: Object.assign(Object.assign({}, defaultDetail), element === null || element === void 0 ? void 0 : element.detail)
10
12
  });
11
- if (!opts.calculator.isElementInView(elem, opts.viewScaleInfo, opts.viewSizeInfo)) {
12
- continue;
13
+ if (opts.forceDrawAll !== true) {
14
+ if (!((_a = opts.calculator) === null || _a === void 0 ? void 0 : _a.needRender(elem))) {
15
+ continue;
16
+ }
13
17
  }
14
18
  try {
15
- drawElement(ctx, elem, opts);
19
+ drawElement(ctx, elem, Object.assign(Object.assign({}, opts), {
20
+ parentOpacity
21
+ }));
16
22
  }
17
23
  catch (err) {
18
24
  console.error(err);
@@ -1,17 +1,22 @@
1
- import { rotateElement, calcViewBoxSize } from '@idraw/util';
1
+ import { rotateElement, calcViewBoxSize, calcViewElementSize } from '@idraw/util';
2
2
  import { drawCircle } from './circle';
3
3
  import { drawRect } from './rect';
4
4
  import { drawImage } from './image';
5
5
  import { drawText } from './text';
6
6
  import { drawSVG } from './svg';
7
7
  import { drawHTML } from './html';
8
- import { drawBox, drawBoxShadow } from './box';
8
+ import { drawBox, drawBoxShadow, getOpacity } from './box';
9
9
  import { drawPath } from './path';
10
10
  export function drawElement(ctx, elem, opts) {
11
11
  var _a;
12
12
  if (((_a = elem === null || elem === void 0 ? void 0 : elem.operations) === null || _a === void 0 ? void 0 : _a.invisible) === true) {
13
13
  return;
14
14
  }
15
+ const { w, h } = elem;
16
+ const { scale } = opts.viewScaleInfo;
17
+ if ((scale < 1 && (w * scale < 1 || h * scale < 1)) || opts.parentOpacity === 0) {
18
+ return;
19
+ }
15
20
  try {
16
21
  switch (elem.type) {
17
22
  case 'rect': {
@@ -57,10 +62,11 @@ export function drawElement(ctx, elem, opts) {
57
62
  }
58
63
  }
59
64
  export function drawGroup(ctx, elem, opts) {
60
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
61
- const { x, y, w, h, angle } = calculator.elementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h, angle: elem.angle }, viewScaleInfo, viewSizeInfo);
65
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
66
+ const { x, y, w, h, angle } = calcViewElementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h, angle: elem.angle }, { viewScaleInfo, viewSizeInfo }) || elem;
62
67
  const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
63
68
  rotateElement(ctx, { x, y, w, h, angle }, () => {
69
+ ctx.globalAlpha = getOpacity(elem) * parentOpacity;
64
70
  drawBoxShadow(ctx, viewElem, {
65
71
  viewScaleInfo,
66
72
  viewSizeInfo,
@@ -70,6 +76,7 @@ export function drawGroup(ctx, elem, opts) {
70
76
  calcElemSize: { x, y, w, h, angle },
71
77
  viewScaleInfo,
72
78
  viewSizeInfo,
79
+ parentOpacity,
73
80
  renderContent: () => {
74
81
  const { x, y, w, h, radiusList } = calcViewBoxSize(viewElem, {
75
82
  viewScaleInfo,
@@ -104,11 +111,13 @@ export function drawGroup(ctx, elem, opts) {
104
111
  x: newParentSize.x + child.x,
105
112
  y: newParentSize.y + child.y
106
113
  });
107
- if (!calculator.isElementInView(child, opts.viewScaleInfo, opts.viewSizeInfo)) {
108
- continue;
114
+ if (opts.forceDrawAll !== true) {
115
+ if (!(calculator === null || calculator === void 0 ? void 0 : calculator.needRender(child))) {
116
+ continue;
117
+ }
109
118
  }
110
119
  try {
111
- drawElement(ctx, child, Object.assign({}, opts));
120
+ drawElement(ctx, child, Object.assign(Object.assign({}, opts), { parentOpacity: parentOpacity * getOpacity(elem) }));
112
121
  }
113
122
  catch (err) {
114
123
  console.error(err);
@@ -116,12 +125,12 @@ export function drawGroup(ctx, elem, opts) {
116
125
  }
117
126
  }
118
127
  if (elem.detail.overflow === 'hidden') {
119
- ctx.globalAlpha = 1;
120
128
  ctx.restore();
121
129
  }
122
130
  }
123
131
  });
124
132
  }
125
133
  });
134
+ ctx.globalAlpha = parentOpacity;
126
135
  });
127
136
  }
@@ -1,17 +1,17 @@
1
- import { rotateElement } from '@idraw/util';
1
+ import { rotateElement, calcViewElementSize } from '@idraw/util';
2
+ import { getOpacity } from './box';
2
3
  export function drawHTML(ctx, elem, opts) {
3
4
  const content = opts.loader.getContent(elem);
4
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
5
- const { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
5
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
6
+ const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo }) || elem;
6
7
  rotateElement(ctx, { x, y, w, h, angle }, () => {
7
- if (!content) {
8
+ if (!content && !opts.loader.isDestroyed()) {
8
9
  opts.loader.load(elem, opts.elementAssets || {});
9
10
  }
10
11
  if (elem.type === 'html' && content) {
11
- const { opacity } = elem.detail;
12
- ctx.globalAlpha = opacity ? opacity : 1;
12
+ ctx.globalAlpha = getOpacity(elem) * parentOpacity;
13
13
  ctx.drawImage(content, x, y, w, h);
14
- ctx.globalAlpha = 1;
14
+ ctx.globalAlpha = parentOpacity;
15
15
  }
16
16
  });
17
17
  }
@@ -1,9 +1,9 @@
1
- import { rotateElement, calcViewBoxSize } from '@idraw/util';
2
- import { drawBox, drawBoxShadow } from './box';
1
+ import { rotateElement, calcViewBoxSize, calcViewElementSize } from '@idraw/util';
2
+ import { drawBox, drawBoxShadow, getOpacity } from './box';
3
3
  export function drawImage(ctx, elem, opts) {
4
4
  const content = opts.loader.getContent(elem);
5
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
6
- const { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
5
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
6
+ const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo }) || elem;
7
7
  const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
8
8
  rotateElement(ctx, { x, y, w, h, angle }, () => {
9
9
  drawBoxShadow(ctx, viewElem, {
@@ -15,13 +15,13 @@ export function drawImage(ctx, elem, opts) {
15
15
  calcElemSize: { x, y, w, h, angle },
16
16
  viewScaleInfo,
17
17
  viewSizeInfo,
18
+ parentOpacity,
18
19
  renderContent: () => {
19
- if (!content) {
20
+ if (!content && !opts.loader.isDestroyed()) {
20
21
  opts.loader.load(elem, opts.elementAssets || {});
21
22
  }
22
23
  if (elem.type === 'image' && content) {
23
- const { opacity } = elem.detail;
24
- ctx.globalAlpha = opacity ? opacity : 1;
24
+ ctx.globalAlpha = getOpacity(elem) * parentOpacity;
25
25
  const { x, y, w, h, radiusList } = calcViewBoxSize(viewElem, {
26
26
  viewScaleInfo,
27
27
  viewSizeInfo
@@ -38,7 +38,7 @@ export function drawImage(ctx, elem, opts) {
38
38
  ctx.fill();
39
39
  ctx.clip();
40
40
  ctx.drawImage(content, x, y, w, h);
41
- ctx.globalAlpha = 1;
41
+ ctx.globalAlpha = parentOpacity;
42
42
  ctx.restore();
43
43
  }
44
44
  }
@@ -5,3 +5,4 @@ export { drawSVG } from './svg';
5
5
  export { drawHTML } from './html';
6
6
  export { drawText } from './text';
7
7
  export { drawElementList } from './elements';
8
+ export { drawLayout } from './layout';
@@ -5,3 +5,4 @@ export { drawSVG } from './svg';
5
5
  export { drawHTML } from './html';
6
6
  export { drawText } from './text';
7
7
  export { drawElementList } from './elements';
8
+ export { drawLayout } from './layout';
@@ -0,0 +1,2 @@
1
+ import type { RendererDrawElementOptions, ViewContext2D, DataLayout } from '@idraw/types';
2
+ export declare function drawLayout(ctx: ViewContext2D, layout: DataLayout, opts: RendererDrawElementOptions, renderContent: (ctx: ViewContext2D) => void): void;
@@ -0,0 +1,44 @@
1
+ import { calcViewElementSize, calcViewBoxSize } from '@idraw/util';
2
+ import { drawBoxShadow, drawBoxBackground, drawBoxBorder } from './box';
3
+ export function drawLayout(ctx, layout, opts, renderContent) {
4
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
5
+ const elem = Object.assign({ uuid: 'layout', type: 'group' }, layout);
6
+ const { x, y, w, h } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo }) || elem;
7
+ const angle = 0;
8
+ const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
9
+ ctx.globalAlpha = 1;
10
+ drawBoxShadow(ctx, viewElem, {
11
+ viewScaleInfo,
12
+ viewSizeInfo,
13
+ renderContent: () => {
14
+ drawBoxBackground(ctx, viewElem, { viewScaleInfo, viewSizeInfo });
15
+ }
16
+ });
17
+ if (layout.detail.overflow === 'hidden') {
18
+ const { viewScaleInfo, viewSizeInfo } = opts;
19
+ const elem = Object.assign({ uuid: 'layout', type: 'group' }, layout);
20
+ const viewElemSize = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo }) || elem;
21
+ const viewElem = Object.assign(Object.assign({}, elem), viewElemSize);
22
+ const { x, y, w, h, radiusList } = calcViewBoxSize(viewElem, {
23
+ viewScaleInfo,
24
+ viewSizeInfo
25
+ });
26
+ ctx.save();
27
+ ctx.fillStyle = 'transparent';
28
+ ctx.beginPath();
29
+ ctx.moveTo(x + radiusList[0], y);
30
+ ctx.arcTo(x + w, y, x + w, y + h, radiusList[1]);
31
+ ctx.arcTo(x + w, y + h, x, y + h, radiusList[2]);
32
+ ctx.arcTo(x, y + h, x, y, radiusList[3]);
33
+ ctx.arcTo(x, y, x + w, y, radiusList[0]);
34
+ ctx.closePath();
35
+ ctx.fill();
36
+ ctx.clip();
37
+ }
38
+ renderContent(ctx);
39
+ if (layout.detail.overflow === 'hidden') {
40
+ ctx.restore();
41
+ }
42
+ drawBoxBorder(ctx, viewElem, { viewScaleInfo, viewSizeInfo });
43
+ ctx.globalAlpha = parentOpacity;
44
+ }
@@ -1,10 +1,10 @@
1
- import { rotateElement, generateSVGPath } from '@idraw/util';
1
+ import { rotateElement, generateSVGPath, calcViewElementSize } from '@idraw/util';
2
2
  import { drawBox, drawBoxShadow } from './box';
3
3
  export function drawPath(ctx, elem, opts) {
4
4
  const { detail } = elem;
5
5
  const { originX, originY, originW, originH } = detail;
6
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
7
- const { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
6
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
7
+ const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo }) || elem;
8
8
  const scaleW = w / originW;
9
9
  const scaleH = h / originH;
10
10
  const viewOriginX = originX * scaleW;
@@ -19,6 +19,7 @@ export function drawPath(ctx, elem, opts) {
19
19
  calcElemSize: { x, y, w, h, angle },
20
20
  viewScaleInfo,
21
21
  viewSizeInfo,
22
+ parentOpacity,
22
23
  renderContent: () => {
23
24
  drawBoxShadow(ctx, viewElem, {
24
25
  viewScaleInfo,
@@ -1,8 +1,8 @@
1
- import { rotateElement } from '@idraw/util';
1
+ import { rotateElement, calcViewElementSize } from '@idraw/util';
2
2
  import { drawBox, drawBoxShadow } from './box';
3
3
  export function drawRect(ctx, elem, opts) {
4
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
5
- let { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
4
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
5
+ const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo }) || elem;
6
6
  const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
7
7
  rotateElement(ctx, { x, y, w, h, angle }, () => {
8
8
  drawBoxShadow(ctx, viewElem, {
@@ -14,6 +14,7 @@ export function drawRect(ctx, elem, opts) {
14
14
  calcElemSize: { x, y, w, h, angle },
15
15
  viewScaleInfo,
16
16
  viewSizeInfo,
17
+ parentOpacity,
17
18
  renderContent: () => {
18
19
  }
19
20
  });
@@ -1,17 +1,17 @@
1
- import { rotateElement } from '@idraw/util';
1
+ import { rotateElement, calcViewElementSize } from '@idraw/util';
2
+ import { getOpacity } from './box';
2
3
  export function drawSVG(ctx, elem, opts) {
3
4
  const content = opts.loader.getContent(elem);
4
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
5
- const { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
5
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
6
+ const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo }) || elem;
6
7
  rotateElement(ctx, { x, y, w, h, angle }, () => {
7
- if (!content) {
8
+ if (!content && !opts.loader.isDestroyed()) {
8
9
  opts.loader.load(elem, opts.elementAssets || {});
9
10
  }
10
11
  if (elem.type === 'svg' && content) {
11
- const { opacity } = elem.detail;
12
- ctx.globalAlpha = opacity ? opacity : 1;
12
+ ctx.globalAlpha = getOpacity(elem) * parentOpacity;
13
13
  ctx.drawImage(content, x, y, w, h);
14
- ctx.globalAlpha = 1;
14
+ ctx.globalAlpha = parentOpacity;
15
15
  }
16
16
  });
17
17
  }
@@ -1,10 +1,10 @@
1
- import { rotateElement } from '@idraw/util';
1
+ import { rotateElement, calcViewElementSize } from '@idraw/util';
2
2
  import { is, isColorStr, getDefaultElementDetailConfig } from '@idraw/util';
3
3
  import { drawBox } from './box';
4
4
  const detailConfig = getDefaultElementDetailConfig();
5
5
  export function drawText(ctx, elem, opts) {
6
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
7
- const { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
6
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
7
+ const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo }) || elem;
8
8
  const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
9
9
  rotateElement(ctx, { x, y, w, h, angle }, () => {
10
10
  drawBox(ctx, viewElem, {
@@ -12,10 +12,13 @@ export function drawText(ctx, elem, opts) {
12
12
  calcElemSize: { x, y, w, h, angle },
13
13
  viewScaleInfo,
14
14
  viewSizeInfo,
15
+ parentOpacity,
15
16
  renderContent: () => {
16
17
  const detail = Object.assign(Object.assign({}, detailConfig), elem.detail);
17
- const fontSize = (detail.fontSize || detailConfig.fontSize) * viewScaleInfo.scale;
18
- const lineHeight = detail.lineHeight ? detail.lineHeight * viewScaleInfo.scale : fontSize;
18
+ const originFontSize = detail.fontSize || detailConfig.fontSize;
19
+ const fontSize = originFontSize * viewScaleInfo.scale;
20
+ const originLineHeight = detail.lineHeight || originFontSize;
21
+ const lineHeight = originLineHeight * viewScaleInfo.scale;
19
22
  ctx.fillStyle = elem.detail.color || detailConfig.color;
20
23
  ctx.textBaseline = 'top';
21
24
  ctx.$setFont({
@@ -32,7 +35,7 @@ export function drawText(ctx, elem, opts) {
32
35
  let lineText = '';
33
36
  if (tempText.length > 0) {
34
37
  for (let i = 0; i < tempText.length; i++) {
35
- if (ctx.measureText(lineText + (tempText[i] || '')).width < ctx.$doPixelRatio(w)) {
38
+ if (ctx.measureText(lineText + (tempText[i] || '')).width <= ctx.$doPixelRatio(w)) {
36
39
  lineText += tempText[i] || '';
37
40
  }
38
41
  else {
@@ -47,7 +50,7 @@ export function drawText(ctx, elem, opts) {
47
50
  break;
48
51
  }
49
52
  if (tempText.length - 1 === i) {
50
- if ((lineNum + 1) * fontHeight < h) {
53
+ if ((lineNum + 1) * fontHeight <= h) {
51
54
  lines.push({
52
55
  text: lineText,
53
56
  width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
@@ -1,11 +1,17 @@
1
1
  import { EventEmitter } from '@idraw/util';
2
+ import type { LoadItemMap } from '@idraw/types';
3
+ import { Loader } from './loader';
2
4
  import type { Data, BoardRenderer, RendererOptions, RendererEventMap, RendererDrawOptions } from '@idraw/types';
3
5
  export declare class Renderer extends EventEmitter<RendererEventMap> implements BoardRenderer {
4
- private _opts;
5
- private _loader;
6
+ #private;
6
7
  constructor(opts: RendererOptions);
7
- private _init;
8
+ isDestroyed(): boolean;
9
+ destroy(): void;
8
10
  updateOptions(opts: RendererOptions): void;
9
11
  drawData(data: Data, opts: RendererDrawOptions): void;
10
12
  scale(num: number): void;
13
+ setLoadItemMap(itemMap: LoadItemMap): void;
14
+ getLoadItemMap(): LoadItemMap;
15
+ getLoader(): Loader;
11
16
  }
17
+ export { drawRect } from './draw';