@idraw/renderer 0.4.0-beta.4 → 0.4.0-beta.40

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.
@@ -1,17 +1,27 @@
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
+ const visiableMinSize = 0.4;
10
11
  export function drawElement(ctx, elem, opts) {
11
- var _a;
12
+ var _a, _b, _c;
12
13
  if (((_a = elem === null || elem === void 0 ? void 0 : elem.operations) === null || _a === void 0 ? void 0 : _a.invisible) === true) {
13
14
  return;
14
15
  }
16
+ const { w, h } = elem;
17
+ const { scale } = opts.viewScaleInfo;
18
+ if ((scale < 1 && (w * scale < visiableMinSize || h * scale < visiableMinSize)) || opts.parentOpacity === 0) {
19
+ return;
20
+ }
21
+ const { overrideElementMap } = opts;
22
+ if ((_c = (_b = overrideElementMap === null || overrideElementMap === void 0 ? void 0 : overrideElementMap[elem.uuid]) === null || _b === void 0 ? void 0 : _b.operations) === null || _c === void 0 ? void 0 : _c.invisible) {
23
+ return;
24
+ }
15
25
  try {
16
26
  switch (elem.type) {
17
27
  case 'rect': {
@@ -57,10 +67,11 @@ export function drawElement(ctx, elem, opts) {
57
67
  }
58
68
  }
59
69
  export function drawGroup(ctx, elem, opts) {
60
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
61
- const { x, y, w, h, angle } = (calculator === null || calculator === void 0 ? void 0 : calculator.elementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h, angle: elem.angle }, viewScaleInfo, viewSizeInfo)) || elem;
70
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
71
+ const { x, y, w, h, angle } = calcViewElementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h, angle: elem.angle }, { viewScaleInfo }) || elem;
62
72
  const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
63
73
  rotateElement(ctx, { x, y, w, h, angle }, () => {
74
+ ctx.globalAlpha = getOpacity(elem) * parentOpacity;
64
75
  drawBoxShadow(ctx, viewElem, {
65
76
  viewScaleInfo,
66
77
  viewSizeInfo,
@@ -70,6 +81,7 @@ export function drawGroup(ctx, elem, opts) {
70
81
  calcElemSize: { x, y, w, h, angle },
71
82
  viewScaleInfo,
72
83
  viewSizeInfo,
84
+ parentOpacity,
73
85
  renderContent: () => {
74
86
  const { x, y, w, h, radiusList } = calcViewBoxSize(viewElem, {
75
87
  viewScaleInfo,
@@ -105,12 +117,12 @@ export function drawGroup(ctx, elem, opts) {
105
117
  y: newParentSize.y + child.y
106
118
  });
107
119
  if (opts.forceDrawAll !== true) {
108
- if (!(calculator === null || calculator === void 0 ? void 0 : calculator.isElementInView(child, opts.viewScaleInfo, opts.viewSizeInfo))) {
120
+ if (!(calculator === null || calculator === void 0 ? void 0 : calculator.needRender(child))) {
109
121
  continue;
110
122
  }
111
123
  }
112
124
  try {
113
- drawElement(ctx, child, Object.assign({}, opts));
125
+ drawElement(ctx, child, Object.assign(Object.assign({}, opts), { parentOpacity: parentOpacity * getOpacity(elem) }));
114
126
  }
115
127
  catch (err) {
116
128
  console.error(err);
@@ -118,12 +130,12 @@ export function drawGroup(ctx, elem, opts) {
118
130
  }
119
131
  }
120
132
  if (elem.detail.overflow === 'hidden') {
121
- ctx.globalAlpha = 1;
122
133
  ctx.restore();
123
134
  }
124
135
  }
125
136
  });
126
137
  }
127
138
  });
139
+ ctx.globalAlpha = parentOpacity;
128
140
  });
129
141
  }
@@ -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 === null || calculator === void 0 ? void 0 : calculator.elementSize(elem, viewScaleInfo, viewSizeInfo)) || elem;
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 === null || calculator === void 0 ? void 0 : calculator.elementSize(elem, viewScaleInfo, viewSizeInfo)) || elem;
5
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
6
+ const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo }) || 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,17 +15,21 @@ 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
28
28
  });
29
+ const { detail } = elem;
30
+ const { scaleMode, originW = 0, originH = 0 } = detail;
31
+ const imageW = ctx.$undoPixelRatio(originW);
32
+ const imageH = ctx.$undoPixelRatio(originH);
29
33
  ctx.save();
30
34
  ctx.fillStyle = 'transparent';
31
35
  ctx.beginPath();
@@ -37,8 +41,45 @@ export function drawImage(ctx, elem, opts) {
37
41
  ctx.closePath();
38
42
  ctx.fill();
39
43
  ctx.clip();
40
- ctx.drawImage(content, x, y, w, h);
41
- ctx.globalAlpha = 1;
44
+ if (scaleMode && originH && originW) {
45
+ let sx = 0;
46
+ let sy = 0;
47
+ let sWidth = imageW;
48
+ let sHeight = imageH;
49
+ const dx = x;
50
+ const dy = y;
51
+ const dWidth = w;
52
+ const dHeight = h;
53
+ if (imageW > elem.w || imageH > elem.h) {
54
+ if (scaleMode === 'fill') {
55
+ const sourceScale = Math.max(elem.w / imageW, elem.h / imageH);
56
+ const newImageWidth = imageW * sourceScale;
57
+ const newImageHeight = imageH * sourceScale;
58
+ sx = (newImageWidth - elem.w) / 2 / sourceScale;
59
+ sy = (newImageHeight - elem.h) / 2 / sourceScale;
60
+ sWidth = elem.w / sourceScale;
61
+ sHeight = elem.h / sourceScale;
62
+ }
63
+ else if (scaleMode === 'tile') {
64
+ sx = 0;
65
+ sy = 0;
66
+ sWidth = elem.w;
67
+ sHeight = elem.h;
68
+ }
69
+ else if (scaleMode === 'fit') {
70
+ const sourceScale = Math.min(elem.w / imageW, elem.h / imageH);
71
+ sx = (imageW - elem.w / sourceScale) / 2;
72
+ sy = (imageH - elem.h / sourceScale) / 2;
73
+ sWidth = elem.w / sourceScale;
74
+ sHeight = elem.h / sourceScale;
75
+ }
76
+ }
77
+ ctx.drawImage(content, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
78
+ }
79
+ else {
80
+ ctx.drawImage(content, x, y, w, h);
81
+ }
82
+ ctx.globalAlpha = parentOpacity;
42
83
  ctx.restore();
43
84
  }
44
85
  }
@@ -4,4 +4,7 @@ export { drawImage } from './image';
4
4
  export { drawSVG } from './svg';
5
5
  export { drawHTML } from './html';
6
6
  export { drawText } from './text';
7
+ export { drawGroup, drawElement } from './group';
7
8
  export { drawElementList } from './elements';
9
+ export { drawLayout } from './layout';
10
+ export { drawGlobalBackground } from './global';
@@ -4,4 +4,7 @@ export { drawImage } from './image';
4
4
  export { drawSVG } from './svg';
5
5
  export { drawHTML } from './html';
6
6
  export { drawText } from './text';
7
+ export { drawGroup, drawElement } from './group';
7
8
  export { drawElementList } from './elements';
9
+ export { drawLayout } from './layout';
10
+ export { drawGlobalBackground } from './global';
@@ -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 }) || 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 }) || 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, { originElem: elem, viewScaleInfo, viewSizeInfo });
43
+ ctx.globalAlpha = parentOpacity;
44
+ }
@@ -1,24 +1,57 @@
1
- import { rotateElement, generateSVGPath } from '@idraw/util';
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { rotateElement, generateSVGPath, calcViewElementSize } from '@idraw/util';
2
13
  import { drawBox, drawBoxShadow } from './box';
3
14
  export function drawPath(ctx, elem, opts) {
15
+ var _a, _b;
4
16
  const { detail } = elem;
5
- const { originX, originY, originW, originH } = detail;
6
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
7
- const { x, y, w, h, angle } = (calculator === null || calculator === void 0 ? void 0 : calculator.elementSize(elem, viewScaleInfo, viewSizeInfo)) || elem;
17
+ const { originX, originY, originW, originH, fillRule } = detail;
18
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
19
+ const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo }) || elem;
8
20
  const scaleW = w / originW;
9
21
  const scaleH = h / originH;
10
22
  const viewOriginX = originX * scaleW;
11
23
  const viewOriginY = originY * scaleH;
12
24
  const internalX = x - viewOriginX;
13
25
  const internalY = y - viewOriginY;
26
+ const _c = elem.detail, { clipPath, clipPathStrokeColor, clipPathStrokeWidth } = _c, restDetail = __rest(_c, ["clipPath", "clipPathStrokeColor", "clipPathStrokeWidth"]);
14
27
  const scaleNum = viewScaleInfo.scale * viewSizeInfo.devicePixelRatio;
15
28
  const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
29
+ let boxViewElem = Object.assign({}, viewElem);
30
+ boxViewElem.detail = restDetail;
31
+ let boxOriginElem = Object.assign({}, elem);
32
+ boxOriginElem.detail = restDetail;
33
+ if (detail.fill && detail.fill !== 'string' && ((_b = (_a = detail.fill) === null || _a === void 0 ? void 0 : _a.type) === null || _b === void 0 ? void 0 : _b.includes('gradient'))) {
34
+ boxViewElem = Object.assign(Object.assign({}, viewElem), {
35
+ detail: Object.assign(Object.assign({}, viewElem.detail), {
36
+ background: detail.fill,
37
+ clipPath: {
38
+ commands: detail.commands,
39
+ originX,
40
+ originY,
41
+ originW,
42
+ originH
43
+ }
44
+ })
45
+ });
46
+ boxOriginElem.detail = Object.assign({}, boxViewElem.detail);
47
+ }
16
48
  rotateElement(ctx, { x, y, w, h, angle }, () => {
17
- drawBox(ctx, viewElem, {
18
- originElem: elem,
49
+ drawBox(ctx, boxViewElem, {
50
+ originElem: boxOriginElem,
19
51
  calcElemSize: { x, y, w, h, angle },
20
52
  viewScaleInfo,
21
53
  viewSizeInfo,
54
+ parentOpacity,
22
55
  renderContent: () => {
23
56
  drawBoxShadow(ctx, viewElem, {
24
57
  viewScaleInfo,
@@ -30,8 +63,15 @@ export function drawPath(ctx, elem, opts) {
30
63
  const pathStr = generateSVGPath(detail.commands || []);
31
64
  const path2d = new Path2D(pathStr);
32
65
  if (detail.fill) {
33
- ctx.fillStyle = detail.fill;
34
- ctx.fill(path2d);
66
+ if (typeof detail.fill === 'string') {
67
+ ctx.fillStyle = detail.fill;
68
+ }
69
+ else {
70
+ ctx.fillStyle = 'transparent';
71
+ }
72
+ }
73
+ if (detail.fill) {
74
+ ctx.fill(path2d, fillRule);
35
75
  }
36
76
  if (detail.stroke && detail.strokeWidth !== 0) {
37
77
  ctx.strokeStyle = detail.stroke;
@@ -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
- const { x, y, w, h, angle } = (calculator === null || calculator === void 0 ? void 0 : calculator.elementSize(elem, viewScaleInfo, viewSizeInfo)) || elem;
4
+ const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
5
+ const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo }) || 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 === null || calculator === void 0 ? void 0 : calculator.elementSize(elem, viewScaleInfo, viewSizeInfo)) || elem;
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,86 +1,43 @@
1
- import { rotateElement } from '@idraw/util';
1
+ import { rotateElement, calcViewElementSize, enhanceFontFamliy } from '@idraw/util';
2
2
  import { is, isColorStr, getDefaultElementDetailConfig } from '@idraw/util';
3
- import { drawBox } from './box';
3
+ import { drawBox, drawBoxShadow } 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 === null || calculator === void 0 ? void 0 : calculator.elementSize(elem, viewScaleInfo, viewSizeInfo)) || elem;
6
+ const { viewScaleInfo, viewSizeInfo, parentOpacity, calculator } = 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
- drawBox(ctx, viewElem, {
11
- originElem: elem,
12
- calcElemSize: { x, y, w, h, angle },
10
+ var _a, _b;
11
+ drawBoxShadow(ctx, viewElem, {
13
12
  viewScaleInfo,
14
13
  viewSizeInfo,
15
14
  renderContent: () => {
16
- 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;
19
- ctx.fillStyle = elem.detail.color || detailConfig.color;
20
- ctx.textBaseline = 'top';
21
- ctx.$setFont({
22
- fontWeight: detail.fontWeight,
23
- fontSize: fontSize,
24
- fontFamily: detail.fontFamily
15
+ drawBox(ctx, viewElem, {
16
+ originElem: elem,
17
+ calcElemSize: { x, y, w, h, angle },
18
+ viewScaleInfo,
19
+ viewSizeInfo,
20
+ parentOpacity
25
21
  });
26
- const detailText = detail.text.replace(/\r\n/gi, '\n');
27
- const fontHeight = lineHeight;
28
- const detailTextList = detailText.split('\n');
29
- const lines = [];
30
- let lineNum = 0;
31
- detailTextList.forEach((tempText, idx) => {
32
- let lineText = '';
33
- if (tempText.length > 0) {
34
- for (let i = 0; i < tempText.length; i++) {
35
- if (ctx.measureText(lineText + (tempText[i] || '')).width < ctx.$doPixelRatio(w)) {
36
- lineText += tempText[i] || '';
37
- }
38
- else {
39
- lines.push({
40
- text: lineText,
41
- width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
42
- });
43
- lineText = tempText[i] || '';
44
- lineNum++;
45
- }
46
- if ((lineNum + 1) * fontHeight > h) {
47
- break;
48
- }
49
- if (tempText.length - 1 === i) {
50
- if ((lineNum + 1) * fontHeight < h) {
51
- lines.push({
52
- text: lineText,
53
- width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
54
- });
55
- if (idx < detailTextList.length - 1) {
56
- lineNum++;
57
- }
58
- break;
59
- }
60
- }
61
- }
62
- }
63
- else {
64
- lines.push({
65
- text: '',
66
- width: 0
67
- });
68
- }
69
- });
70
- let startY = 0;
71
- if (lines.length * fontHeight < h) {
72
- if (elem.detail.verticalAlign === 'top') {
73
- startY = 0;
74
- }
75
- else if (elem.detail.verticalAlign === 'bottom') {
76
- startY += h - lines.length * fontHeight;
77
- }
78
- else {
79
- startY += (h - lines.length * fontHeight) / 2;
80
- }
81
- }
82
- {
83
- const _y = y + startY;
22
+ }
23
+ });
24
+ {
25
+ const detail = Object.assign(Object.assign({}, detailConfig), elem.detail);
26
+ const originFontSize = detail.fontSize || detailConfig.fontSize;
27
+ const fontSize = originFontSize * viewScaleInfo.scale;
28
+ if (fontSize < 2) {
29
+ return;
30
+ }
31
+ ctx.fillStyle = elem.detail.color || detailConfig.color;
32
+ ctx.textBaseline = 'top';
33
+ ctx.$setFont({
34
+ fontWeight: detail.fontWeight,
35
+ fontSize: fontSize,
36
+ fontFamily: enhanceFontFamliy(detail.fontFamily)
37
+ });
38
+ {
39
+ const virtualTextDetail = calculator.getVirtualFlatItem(elem.uuid);
40
+ if (Array.isArray(virtualTextDetail === null || virtualTextDetail === void 0 ? void 0 : virtualTextDetail.textLines) && ((_a = virtualTextDetail === null || virtualTextDetail === void 0 ? void 0 : virtualTextDetail.textLines) === null || _a === void 0 ? void 0 : _a.length) > 0) {
84
41
  if (detail.textShadowColor !== undefined && isColorStr(detail.textShadowColor)) {
85
42
  ctx.shadowColor = detail.textShadowColor;
86
43
  }
@@ -93,18 +50,11 @@ export function drawText(ctx, elem, opts) {
93
50
  if (detail.textShadowBlur !== undefined && is.number(detail.textShadowBlur)) {
94
51
  ctx.shadowBlur = detail.textShadowBlur;
95
52
  }
96
- lines.forEach((line, i) => {
97
- let _x = x;
98
- if (detail.textAlign === 'center') {
99
- _x = x + (w - line.width) / 2;
100
- }
101
- else if (detail.textAlign === 'right') {
102
- _x = x + (w - line.width);
103
- }
104
- ctx.fillText(line.text, _x, _y + fontHeight * i);
53
+ (_b = virtualTextDetail === null || virtualTextDetail === void 0 ? void 0 : virtualTextDetail.textLines) === null || _b === void 0 ? void 0 : _b.forEach((line) => {
54
+ ctx.fillText(line.text, x + line.x * viewScaleInfo.scale, y + line.y * viewScaleInfo.scale);
105
55
  });
106
56
  }
107
57
  }
108
- });
58
+ }
109
59
  });
110
60
  }
@@ -1,12 +1,20 @@
1
1
  import { EventEmitter } from '@idraw/util';
2
2
  import type { LoadItemMap } from '@idraw/types';
3
+ import { Loader } from './loader';
3
4
  import type { Data, BoardRenderer, RendererOptions, RendererEventMap, RendererDrawOptions } from '@idraw/types';
5
+ import { Calculator } from './calculator';
6
+ export { Calculator };
4
7
  export declare class Renderer extends EventEmitter<RendererEventMap> implements BoardRenderer {
5
8
  #private;
6
9
  constructor(opts: RendererOptions);
10
+ isDestroyed(): boolean;
11
+ destroy(): void;
7
12
  updateOptions(opts: RendererOptions): void;
8
13
  drawData(data: Data, opts: RendererDrawOptions): void;
9
14
  scale(num: number): void;
10
15
  setLoadItemMap(itemMap: LoadItemMap): void;
11
16
  getLoadItemMap(): LoadItemMap;
17
+ getLoader(): Loader;
18
+ getCalculator(): Calculator;
12
19
  }
20
+ export { drawCircle, drawRect, drawImage, drawSVG, drawHTML, drawText, drawGroup, drawElement, drawElementList, drawLayout, drawGlobalBackground } from './draw';
package/dist/esm/index.js CHANGED
@@ -9,25 +9,43 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _Renderer_instances, _Renderer_opts, _Renderer_loader, _Renderer_init;
12
+ var _Renderer_instances, _Renderer_opts, _Renderer_loader, _Renderer_calculator, _Renderer_hasDestroyed, _Renderer_init;
13
13
  import { EventEmitter } from '@idraw/util';
14
- import { drawElementList } from './draw/index';
14
+ import { drawElementList, drawLayout, drawGlobalBackground } from './draw/index';
15
15
  import { Loader } from './loader';
16
+ import { Calculator } from './calculator';
17
+ export { Calculator };
16
18
  export class Renderer extends EventEmitter {
17
19
  constructor(opts) {
18
20
  super();
19
21
  _Renderer_instances.add(this);
20
22
  _Renderer_opts.set(this, void 0);
21
23
  _Renderer_loader.set(this, new Loader());
24
+ _Renderer_calculator.set(this, void 0);
25
+ _Renderer_hasDestroyed.set(this, false);
22
26
  __classPrivateFieldSet(this, _Renderer_opts, opts, "f");
27
+ __classPrivateFieldSet(this, _Renderer_calculator, new Calculator({
28
+ tempContext: opts.tempContext
29
+ }), "f");
23
30
  __classPrivateFieldGet(this, _Renderer_instances, "m", _Renderer_init).call(this);
24
31
  }
32
+ isDestroyed() {
33
+ return __classPrivateFieldGet(this, _Renderer_hasDestroyed, "f");
34
+ }
35
+ destroy() {
36
+ this.clear();
37
+ __classPrivateFieldSet(this, _Renderer_opts, null, "f");
38
+ __classPrivateFieldGet(this, _Renderer_loader, "f").destroy();
39
+ __classPrivateFieldSet(this, _Renderer_loader, null, "f");
40
+ __classPrivateFieldSet(this, _Renderer_hasDestroyed, true, "f");
41
+ }
25
42
  updateOptions(opts) {
26
43
  __classPrivateFieldSet(this, _Renderer_opts, opts, "f");
27
44
  }
28
45
  drawData(data, opts) {
29
46
  const loader = __classPrivateFieldGet(this, _Renderer_loader, "f");
30
- const { calculator } = __classPrivateFieldGet(this, _Renderer_opts, "f");
47
+ const calculator = __classPrivateFieldGet(this, _Renderer_calculator, "f");
48
+ const { sharer } = __classPrivateFieldGet(this, _Renderer_opts, "f");
31
49
  const viewContext = __classPrivateFieldGet(this, _Renderer_opts, "f").viewContext;
32
50
  viewContext.clearRect(0, 0, viewContext.canvas.width, viewContext.canvas.height);
33
51
  const parentElementSize = {
@@ -36,9 +54,18 @@ export class Renderer extends EventEmitter {
36
54
  w: opts.viewSizeInfo.width,
37
55
  h: opts.viewSizeInfo.height
38
56
  };
39
- drawElementList(viewContext, data, Object.assign({ loader,
57
+ const drawOpts = Object.assign({ loader,
40
58
  calculator,
41
- parentElementSize, elementAssets: data.assets }, opts));
59
+ parentElementSize, elementAssets: data.assets, parentOpacity: 1, overrideElementMap: sharer === null || sharer === void 0 ? void 0 : sharer.getActiveOverrideElemenentMap() }, opts);
60
+ drawGlobalBackground(viewContext, data.global, drawOpts);
61
+ if (data.layout) {
62
+ drawLayout(viewContext, data.layout, drawOpts, () => {
63
+ drawElementList(viewContext, data, drawOpts);
64
+ });
65
+ }
66
+ else {
67
+ drawElementList(viewContext, data, drawOpts);
68
+ }
42
69
  }
43
70
  scale(num) {
44
71
  const { sharer } = __classPrivateFieldGet(this, _Renderer_opts, "f");
@@ -71,12 +98,20 @@ export class Renderer extends EventEmitter {
71
98
  getLoadItemMap() {
72
99
  return __classPrivateFieldGet(this, _Renderer_loader, "f").getLoadItemMap();
73
100
  }
101
+ getLoader() {
102
+ return __classPrivateFieldGet(this, _Renderer_loader, "f");
103
+ }
104
+ getCalculator() {
105
+ return __classPrivateFieldGet(this, _Renderer_calculator, "f");
106
+ }
74
107
  }
75
- _Renderer_opts = new WeakMap(), _Renderer_loader = new WeakMap(), _Renderer_instances = new WeakSet(), _Renderer_init = function _Renderer_init() {
108
+ _Renderer_opts = new WeakMap(), _Renderer_loader = new WeakMap(), _Renderer_calculator = new WeakMap(), _Renderer_hasDestroyed = new WeakMap(), _Renderer_instances = new WeakSet(), _Renderer_init = function _Renderer_init() {
76
109
  const loader = __classPrivateFieldGet(this, _Renderer_loader, "f");
77
110
  loader.on('load', (e) => {
78
111
  this.trigger('load', e);
79
112
  });
80
- loader.on('error', () => {
113
+ loader.on('error', (e) => {
114
+ console.error(e);
81
115
  });
82
116
  };
117
+ export { drawCircle, drawRect, drawImage, drawSVG, drawHTML, drawText, drawGroup, drawElement, drawElementList, drawLayout, drawGlobalBackground } from './draw';