@idraw/renderer 0.4.0-alpha.3 → 0.4.0-alpha.4

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,12 +1,7 @@
1
- import { istype, isColorStr, generateSVGPath, rotateElement, is } from '@idraw/util';
1
+ import { istype, isColorStr, generateSVGPath, rotateElement, is, getDefaultElementDetailConfig, calcViewBoxSize } from '@idraw/util';
2
+ import { createColorStyle } from './color';
3
+ const defaultElemConfig = getDefaultElementDetailConfig();
2
4
  export function drawBox(ctx, viewElem, opts) {
3
- var _a, _b;
4
- 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) {
5
- ctx.globalAlpha = viewElem.detail.opacity;
6
- }
7
- else {
8
- ctx.globalAlpha = 1;
9
- }
10
5
  const { pattern, renderContent, originElem, calcElemSize, viewScaleInfo, viewSizeInfo } = opts || {};
11
6
  drawClipPath(ctx, viewElem, {
12
7
  originElem,
@@ -14,12 +9,19 @@ export function drawBox(ctx, viewElem, opts) {
14
9
  viewScaleInfo,
15
10
  viewSizeInfo,
16
11
  renderContent: () => {
17
- drawBoxBorder(ctx, viewElem, { viewScaleInfo, viewSizeInfo });
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
+ }
18
19
  drawBoxBackground(ctx, viewElem, { pattern, viewScaleInfo, viewSizeInfo });
19
20
  renderContent === null || renderContent === void 0 ? void 0 : renderContent();
21
+ drawBoxBorder(ctx, viewElem, { viewScaleInfo, viewSizeInfo });
22
+ ctx.globalAlpha = 1;
20
23
  }
21
24
  });
22
- ctx.globalAlpha = 1;
23
25
  }
24
26
  function drawClipPath(ctx, viewElem, opts) {
25
27
  const { renderContent, originElem, calcElemSize, viewScaleInfo, viewSizeInfo } = opts;
@@ -53,21 +55,23 @@ function drawClipPath(ctx, viewElem, opts) {
53
55
  }
54
56
  function drawBoxBackground(ctx, viewElem, opts) {
55
57
  var _a, _b;
56
- const { pattern, viewScaleInfo } = opts;
58
+ const { pattern, viewScaleInfo, viewSizeInfo } = opts;
57
59
  let transform = [];
60
+ let { borderRadius, borderWidth } = viewElem.detail;
61
+ if (typeof borderWidth !== 'number') {
62
+ borderRadius = 0;
63
+ }
58
64
  if (viewElem.detail.background || pattern) {
59
- const { x, y, w, h } = viewElem;
60
- let r = (viewElem.detail.borderRadius || 0) * viewScaleInfo.scale;
61
- r = Math.min(r, w / 2, h / 2);
62
- if (w < r * 2 || h < r * 2) {
63
- r = 0;
64
- }
65
+ const { x, y, w, h, radiusList } = calcViewBoxSize(viewElem, {
66
+ viewScaleInfo,
67
+ viewSizeInfo
68
+ });
65
69
  ctx.beginPath();
66
- ctx.moveTo(x + r, y);
67
- ctx.arcTo(x + w, y, x + w, y + h, r);
68
- ctx.arcTo(x + w, y + h, x, y + h, r);
69
- ctx.arcTo(x, y + h, x, y, r);
70
- ctx.arcTo(x, y, x + w, y, r);
70
+ ctx.moveTo(x + radiusList[0], y);
71
+ ctx.arcTo(x + w, y, x + w, y + h, radiusList[1]);
72
+ ctx.arcTo(x + w, y + h, x, y + h, radiusList[2]);
73
+ ctx.arcTo(x, y + h, x, y, radiusList[3]);
74
+ ctx.arcTo(x, y, x + w, y, radiusList[0]);
71
75
  ctx.closePath();
72
76
  if (typeof pattern === 'string') {
73
77
  ctx.fillStyle = pattern;
@@ -78,40 +82,21 @@ function drawBoxBackground(ctx, viewElem, opts) {
78
82
  else if (typeof viewElem.detail.background === 'string') {
79
83
  ctx.fillStyle = viewElem.detail.background;
80
84
  }
81
- else if (((_a = viewElem.detail.background) === null || _a === void 0 ? void 0 : _a.type) === 'linearGradient') {
82
- const { start, end, stops } = viewElem.detail.background;
83
- const viewStart = {
84
- x: start.x + x,
85
- y: start.y + y
86
- };
87
- const viewEnd = {
88
- x: end.x + x,
89
- y: end.y + y
90
- };
91
- const linearGradient = ctx.createLinearGradient(viewStart.x, viewStart.y, viewEnd.x, viewEnd.y);
92
- stops.forEach((stop) => {
93
- linearGradient.addColorStop(stop.offset, stop.color);
85
+ else if (((_a = viewElem.detail.background) === null || _a === void 0 ? void 0 : _a.type) === 'linear-gradient') {
86
+ const colorStyle = createColorStyle(ctx, viewElem.detail.background, {
87
+ viewElementSize: { x, y, w, h },
88
+ viewScaleInfo,
89
+ opacity: ctx.globalAlpha
94
90
  });
95
- ctx.fillStyle = linearGradient;
96
- }
97
- else if (((_b = viewElem.detail.background) === null || _b === void 0 ? void 0 : _b.type) === 'radialGradient') {
98
- const { inner, outer, stops } = viewElem.detail.background;
99
- transform = viewElem.detail.background.transform || [];
100
- const viewInner = {
101
- x: inner.x,
102
- y: inner.y,
103
- radius: inner.radius * viewScaleInfo.scale
104
- };
105
- const viewOuter = {
106
- x: outer.x,
107
- y: outer.y,
108
- radius: outer.radius * viewScaleInfo.scale
109
- };
110
- const radialGradient = ctx.createRadialGradient(viewInner.x, viewInner.y, viewInner.radius, viewOuter.x, viewOuter.y, viewOuter.radius);
111
- stops.forEach((stop) => {
112
- radialGradient.addColorStop(stop.offset, stop.color);
91
+ ctx.fillStyle = colorStyle;
92
+ }
93
+ else if (((_b = viewElem.detail.background) === null || _b === void 0 ? void 0 : _b.type) === 'radial-gradient') {
94
+ const colorStyle = createColorStyle(ctx, viewElem.detail.background, {
95
+ viewElementSize: { x, y, w, h },
96
+ viewScaleInfo,
97
+ opacity: ctx.globalAlpha
113
98
  });
114
- ctx.fillStyle = radialGradient;
99
+ ctx.fillStyle = colorStyle;
115
100
  if (transform && transform.length > 0) {
116
101
  for (let i = 0; i < (transform === null || transform === void 0 ? void 0 : transform.length); i++) {
117
102
  const action = transform[i];
@@ -134,97 +119,147 @@ function drawBoxBackground(ctx, viewElem, opts) {
134
119
  }
135
120
  }
136
121
  function drawBoxBorder(ctx, viewElem, opts) {
122
+ var _a, _b;
123
+ if (viewElem.detail.borderWidth === 0) {
124
+ return;
125
+ }
137
126
  if (!isColorStr(viewElem.detail.borderColor)) {
138
127
  return;
139
128
  }
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
+ }
140
135
  const { viewScaleInfo } = opts;
141
- let borderColor = '#000000';
136
+ const { scale } = viewScaleInfo;
137
+ let borderColor = defaultElemConfig.borderColor;
142
138
  if (isColorStr(viewElem.detail.borderColor) === true) {
143
139
  borderColor = viewElem.detail.borderColor;
144
140
  }
145
- const { borderWidth, borderRadius, borderDash } = viewElem.detail;
141
+ const { borderWidth, borderRadius, borderDash, boxSizing = defaultElemConfig.boxSizing } = viewElem.detail;
146
142
  let bw = 0;
147
143
  if (typeof borderWidth === 'number') {
148
144
  bw = borderWidth || 1;
149
145
  }
150
- bw = bw * viewScaleInfo.scale;
151
- let r = borderRadius || 0;
146
+ bw = bw * scale;
147
+ let radiusList = [0, 0, 0, 0];
148
+ if (typeof borderRadius === 'number') {
149
+ const br = borderRadius * scale;
150
+ radiusList = [br, br, br, br];
151
+ }
152
+ else if (Array.isArray(borderRadius) && (borderRadius === null || borderRadius === void 0 ? void 0 : borderRadius.length) === 4) {
153
+ radiusList = [borderRadius[0] * scale, borderRadius[1] * scale, borderRadius[2] * scale, borderRadius[3] * scale];
154
+ }
152
155
  ctx.strokeStyle = borderColor;
153
- ctx.setLineDash(borderDash || []);
156
+ let viewBorderDash = [];
157
+ if (Array.isArray(borderDash) && borderDash.length > 0) {
158
+ viewBorderDash = borderDash.map((num) => Math.ceil(num * scale));
159
+ }
154
160
  let borderTop = 0;
155
161
  let borderRight = 0;
156
162
  let borderBottom = 0;
157
163
  let borderLeft = 0;
158
164
  if (Array.isArray(borderWidth)) {
159
- borderTop = borderWidth[0] || 0;
160
- borderRight = borderWidth[1] || 0;
161
- borderBottom = borderWidth[2] || 0;
162
- borderLeft = borderWidth[3] || 0;
165
+ borderTop = (borderWidth[0] || 0) * scale;
166
+ borderRight = (borderWidth[1] || 0) * scale;
167
+ borderBottom = (borderWidth[2] || 0) * scale;
168
+ borderLeft = (borderWidth[3] || 0) * scale;
163
169
  }
164
170
  if (borderLeft || borderRight || borderTop || borderBottom) {
165
- const { x, y, w, h } = viewElem;
166
- if (borderLeft) {
171
+ ctx.lineCap = 'butt';
172
+ let { x, y, w, h } = viewElem;
173
+ if (boxSizing === 'border-box') {
174
+ x = x + borderLeft / 2;
175
+ y = y + borderTop / 2;
176
+ w = w - borderLeft / 2 - borderRight / 2;
177
+ h = h - borderTop / 2 - borderBottom / 2;
178
+ }
179
+ else if (boxSizing === 'content-box') {
180
+ x = x - borderLeft / 2;
181
+ y = y - borderTop / 2;
182
+ w = w + borderLeft / 2 + borderRight / 2;
183
+ h = h + borderTop / 2 + borderBottom / 2;
184
+ }
185
+ else {
186
+ x = viewElem.x;
187
+ y = viewElem.y;
188
+ w = viewElem.w;
189
+ h = viewElem.h;
190
+ }
191
+ if (borderTop) {
167
192
  ctx.beginPath();
168
- ctx.lineWidth = borderLeft * viewScaleInfo.scale;
169
- ctx.moveTo(x, y);
170
- ctx.lineTo(x, y + h);
193
+ ctx.lineWidth = borderTop;
194
+ ctx.moveTo(x - borderLeft / 2, y);
195
+ ctx.lineTo(x + w + borderRight / 2, y);
171
196
  ctx.closePath();
172
197
  ctx.stroke();
173
198
  }
174
199
  if (borderRight) {
175
200
  ctx.beginPath();
176
- ctx.lineWidth = borderRight * viewScaleInfo.scale;
177
- ctx.moveTo(x + w, y);
178
- ctx.lineTo(x + w, y + h);
201
+ ctx.lineWidth = borderRight;
202
+ ctx.moveTo(x + w, y - borderTop / 2);
203
+ ctx.lineTo(x + w, y + h + borderBottom / 2);
179
204
  ctx.closePath();
180
205
  ctx.stroke();
181
206
  }
182
- if (borderTop) {
207
+ if (borderBottom) {
183
208
  ctx.beginPath();
184
- ctx.lineWidth = borderTop * viewScaleInfo.scale;
185
- ctx.moveTo(x, y);
186
- ctx.lineTo(x + w, y);
209
+ ctx.lineWidth = borderBottom;
210
+ ctx.moveTo(x - borderLeft / 2, y + h);
211
+ ctx.lineTo(x + w + borderRight / 2, y + h);
187
212
  ctx.closePath();
188
213
  ctx.stroke();
189
214
  }
190
- if (borderBottom) {
215
+ if (borderLeft) {
191
216
  ctx.beginPath();
192
- ctx.lineWidth = borderBottom * viewScaleInfo.scale;
193
- ctx.moveTo(x, y + h);
194
- ctx.lineTo(x + w, y + h);
217
+ ctx.lineWidth = borderLeft;
218
+ ctx.moveTo(x, y - borderTop / 2);
219
+ ctx.lineTo(x, y + h + borderBottom / 2);
195
220
  ctx.closePath();
196
221
  ctx.stroke();
197
222
  }
198
223
  }
199
224
  else {
200
225
  let { x, y, w, h } = viewElem;
201
- const { boxSizing } = viewElem.detail;
202
226
  if (boxSizing === 'border-box') {
227
+ x = viewElem.x + bw / 2;
228
+ y = viewElem.y + bw / 2;
229
+ w = viewElem.w - bw;
230
+ h = viewElem.h - bw;
231
+ }
232
+ else if (boxSizing === 'content-box') {
233
+ x = viewElem.x - bw / 2;
234
+ y = viewElem.y - bw / 2;
235
+ w = viewElem.w + bw;
236
+ h = viewElem.h + bw;
237
+ }
238
+ else {
203
239
  x = viewElem.x;
204
240
  y = viewElem.y;
205
241
  w = viewElem.w;
206
242
  h = viewElem.h;
207
243
  }
208
- else {
209
- x = viewElem.x - bw;
210
- y = viewElem.y - bw;
211
- w = viewElem.w + bw * 2;
212
- h = viewElem.h + bw * 2;
244
+ if (viewBorderDash.length > 0) {
245
+ ctx.lineCap = 'butt';
213
246
  }
214
- r = Math.min(r, w / 2, h / 2);
215
- if (r < w / 2 && r < h / 2) {
216
- r = r + bw / 2;
247
+ else {
248
+ ctx.lineCap = 'square';
217
249
  }
218
- ctx.beginPath();
250
+ ctx.setLineDash(viewBorderDash);
219
251
  ctx.lineWidth = bw;
220
- ctx.moveTo(x + r, y);
221
- ctx.arcTo(x + w, y, x + w, y + h, r);
222
- ctx.arcTo(x + w, y + h, x, y + h, r);
223
- ctx.arcTo(x, y + h, x, y, r);
224
- ctx.arcTo(x, y, x + w, y, r);
252
+ ctx.beginPath();
253
+ ctx.moveTo(x + radiusList[0], y);
254
+ ctx.arcTo(x + w, y, x + w, y + h, radiusList[1]);
255
+ ctx.arcTo(x + w, y + h, x, y + h, radiusList[2]);
256
+ ctx.arcTo(x, y + h, x, y, radiusList[3]);
257
+ ctx.arcTo(x, y, x + w, y, radiusList[0]);
225
258
  ctx.closePath();
226
259
  ctx.stroke();
260
+ ctx.globalAlpha = 1;
227
261
  }
262
+ ctx.setLineDash([]);
228
263
  }
229
264
  export function drawBoxShadow(ctx, viewElem, opts) {
230
265
  const { detail } = viewElem;
@@ -232,7 +267,7 @@ export function drawBoxShadow(ctx, viewElem, opts) {
232
267
  const { shadowColor, shadowOffsetX, shadowOffsetY, shadowBlur } = detail;
233
268
  if (is.number(shadowBlur)) {
234
269
  ctx.save();
235
- ctx.shadowColor = shadowColor || '#000000';
270
+ ctx.shadowColor = shadowColor || defaultElemConfig.shadowColor;
236
271
  ctx.shadowOffsetX = (shadowOffsetX || 0) * viewScaleInfo.scale;
237
272
  ctx.shadowOffsetY = (shadowOffsetY || 0) * viewScaleInfo.scale;
238
273
  ctx.shadowBlur = (shadowBlur || 0) * viewScaleInfo.scale;
@@ -1,28 +1,50 @@
1
1
  import { rotateElement } from '@idraw/util';
2
+ import { createColorStyle } from './color';
3
+ import { drawBoxShadow } from './box';
2
4
  export function drawCircle(ctx, elem, opts) {
3
5
  const { detail, angle } = elem;
4
6
  const { background = '#000000', borderColor = '#000000', borderWidth = 0 } = detail;
5
7
  const { calculator, viewScaleInfo, viewSizeInfo } = opts;
6
8
  const { x, y, w, h } = calculator.elementSize({ x: elem.x, y: elem.y, w: elem.w, h: elem.h }, viewScaleInfo, viewSizeInfo);
9
+ const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
7
10
  rotateElement(ctx, { x, y, w, h, angle }, () => {
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.strokeStyle = borderColor;
17
- ctx.lineWidth = borderWidth;
18
- ctx.circle(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI);
19
- ctx.closePath();
20
- ctx.stroke();
21
- }
22
- ctx.beginPath();
23
- ctx.fillStyle = background;
24
- ctx.circle(centerX, centerY, a, b, 0, 0, 2 * Math.PI);
25
- ctx.closePath();
26
- ctx.fill();
11
+ drawBoxShadow(ctx, viewElem, {
12
+ viewScaleInfo,
13
+ viewSizeInfo,
14
+ renderContent: () => {
15
+ var _a, _b;
16
+ const a = w / 2;
17
+ const b = h / 2;
18
+ const centerX = x + a;
19
+ 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;
22
+ }
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;
29
+ ctx.beginPath();
30
+ ctx.strokeStyle = borderColor;
31
+ ctx.lineWidth = borderWidth;
32
+ ctx.circle(centerX, centerY, ba, bb, 0, 0, 2 * Math.PI);
33
+ ctx.closePath();
34
+ ctx.stroke();
35
+ }
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
+ }
48
+ });
27
49
  });
28
50
  }
@@ -0,0 +1,6 @@
1
+ import type { ViewContext2D, ViewScaleInfo, ElementSize, LinearGradientColor, RadialGradientColor } from '@idraw/types';
2
+ export declare function createColorStyle(ctx: ViewContext2D, color: string | LinearGradientColor | RadialGradientColor | undefined, opts: {
3
+ viewElementSize: ElementSize;
4
+ viewScaleInfo: ViewScaleInfo;
5
+ opacity: number;
6
+ }): string | CanvasPattern | CanvasGradient;
@@ -0,0 +1,44 @@
1
+ import { mergeHexColorAlpha } from '@idraw/util';
2
+ export function createColorStyle(ctx, color, opts) {
3
+ if (typeof color === 'string') {
4
+ return color;
5
+ }
6
+ const { viewElementSize, viewScaleInfo, opacity = 1 } = opts;
7
+ const { x, y } = viewElementSize;
8
+ const { scale } = viewScaleInfo;
9
+ if ((color === null || color === void 0 ? void 0 : color.type) === 'linear-gradient') {
10
+ const { start, end, stops } = color;
11
+ const viewStart = {
12
+ x: x + start.x * scale,
13
+ y: y + start.y * scale
14
+ };
15
+ const viewEnd = {
16
+ x: x + end.x * scale,
17
+ y: y + end.y * scale
18
+ };
19
+ const linearGradient = ctx.createLinearGradient(viewStart.x, viewStart.y, viewEnd.x, viewEnd.y);
20
+ stops.forEach((stop) => {
21
+ linearGradient.addColorStop(stop.offset, mergeHexColorAlpha(stop.color, opacity));
22
+ });
23
+ return linearGradient;
24
+ }
25
+ if ((color === null || color === void 0 ? void 0 : color.type) === 'radial-gradient') {
26
+ const { inner, outer, stops } = color;
27
+ const viewInner = {
28
+ x: x + inner.x * scale,
29
+ y: y + inner.y * scale,
30
+ radius: inner.radius * scale
31
+ };
32
+ const viewOuter = {
33
+ x: x + outer.x * scale,
34
+ y: y + outer.y * scale,
35
+ radius: outer.radius * scale
36
+ };
37
+ const radialGradient = ctx.createRadialGradient(viewInner.x, viewInner.y, viewInner.radius, viewOuter.x, viewOuter.y, viewOuter.radius);
38
+ stops.forEach((stop) => {
39
+ radialGradient.addColorStop(stop.offset, mergeHexColorAlpha(stop.color, opacity));
40
+ });
41
+ return radialGradient;
42
+ }
43
+ return '#000000';
44
+ }
@@ -1,8 +1,13 @@
1
+ import { getDefaultElementDetailConfig } from '@idraw/util';
1
2
  import { drawElement } from './group';
3
+ const defaultDetail = getDefaultElementDetailConfig();
2
4
  export function drawElementList(ctx, data, opts) {
3
5
  const { elements = [] } = data;
4
6
  for (let i = 0; i < elements.length; i++) {
5
- const elem = elements[i];
7
+ const element = elements[i];
8
+ const elem = Object.assign(Object.assign({}, element), {
9
+ detail: Object.assign(Object.assign({}, defaultDetail), element === null || element === void 0 ? void 0 : element.detail)
10
+ });
6
11
  if (!opts.calculator.isElementInView(elem, opts.viewScaleInfo, opts.viewSizeInfo)) {
7
12
  continue;
8
13
  }
@@ -5,7 +5,7 @@ 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 } from './base';
8
+ import { drawBox } from './box';
9
9
  import { drawPath } from './path';
10
10
  export function drawElement(ctx, elem, opts) {
11
11
  var _a;
@@ -1,14 +1,17 @@
1
1
  import { rotateElement } from '@idraw/util';
2
2
  export function drawHTML(ctx, elem, opts) {
3
- const content = opts.loader.getContent(elem.uuid);
3
+ const content = opts.loader.getContent(elem);
4
4
  const { calculator, viewScaleInfo, viewSizeInfo } = opts;
5
5
  const { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
6
6
  rotateElement(ctx, { x, y, w, h, angle }, () => {
7
7
  if (!content) {
8
- opts.loader.load(elem);
8
+ opts.loader.load(elem, opts.elementAssets || {});
9
9
  }
10
10
  if (elem.type === 'html' && content) {
11
+ const { opacity } = elem.detail;
12
+ ctx.globalAlpha = opacity ? opacity : 1;
11
13
  ctx.drawImage(content, x, y, w, h);
14
+ ctx.globalAlpha = 1;
12
15
  }
13
16
  });
14
17
  }
@@ -1,14 +1,48 @@
1
- import { rotateElement } from '@idraw/util';
1
+ import { rotateElement, calcViewBoxSize } from '@idraw/util';
2
+ import { drawBox, drawBoxShadow } from './box';
2
3
  export function drawImage(ctx, elem, opts) {
3
- const content = opts.loader.getContent(elem.uuid);
4
+ const content = opts.loader.getContent(elem);
4
5
  const { calculator, viewScaleInfo, viewSizeInfo } = opts;
5
6
  const { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
7
+ const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
6
8
  rotateElement(ctx, { x, y, w, h, angle }, () => {
7
- if (!content) {
8
- opts.loader.load(elem, opts.elementAssets || {});
9
- }
10
- if (elem.type === 'image' && content) {
11
- ctx.drawImage(content, x, y, w, h);
12
- }
9
+ drawBoxShadow(ctx, viewElem, {
10
+ viewScaleInfo,
11
+ viewSizeInfo,
12
+ renderContent: () => {
13
+ drawBox(ctx, viewElem, {
14
+ originElem: elem,
15
+ calcElemSize: { x, y, w, h, angle },
16
+ viewScaleInfo,
17
+ viewSizeInfo,
18
+ renderContent: () => {
19
+ if (!content) {
20
+ opts.loader.load(elem, opts.elementAssets || {});
21
+ }
22
+ if (elem.type === 'image' && content) {
23
+ const { opacity } = elem.detail;
24
+ ctx.globalAlpha = opacity ? opacity : 1;
25
+ const { x, y, w, h, radiusList } = calcViewBoxSize(viewElem, {
26
+ viewScaleInfo,
27
+ viewSizeInfo
28
+ });
29
+ ctx.save();
30
+ ctx.beginPath();
31
+ ctx.moveTo(x + radiusList[0], y);
32
+ ctx.arcTo(x + w, y, x + w, y + h, radiusList[1]);
33
+ ctx.arcTo(x + w, y + h, x, y + h, radiusList[2]);
34
+ ctx.arcTo(x, y + h, x, y, radiusList[3]);
35
+ ctx.arcTo(x, y, x + w, y, radiusList[0]);
36
+ ctx.closePath();
37
+ ctx.fill();
38
+ ctx.clip();
39
+ ctx.drawImage(content, x, y, w, h);
40
+ ctx.globalAlpha = 1;
41
+ ctx.restore();
42
+ }
43
+ }
44
+ });
45
+ }
46
+ });
13
47
  });
14
48
  }
@@ -1,5 +1,5 @@
1
1
  import { rotateElement, generateSVGPath } from '@idraw/util';
2
- import { drawBox, drawBoxShadow } from './base';
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;
@@ -1,5 +1,5 @@
1
1
  import { rotateElement } from '@idraw/util';
2
- import { drawBox, drawBoxShadow } from './base';
2
+ import { drawBox, drawBoxShadow } from './box';
3
3
  export function drawRect(ctx, elem, opts) {
4
4
  const { calculator, viewScaleInfo, viewSizeInfo } = opts;
5
5
  let { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
@@ -1,6 +1,6 @@
1
1
  import { rotateElement } from '@idraw/util';
2
2
  export function drawSVG(ctx, elem, opts) {
3
- const content = opts.loader.getContent(elem.uuid);
3
+ const content = opts.loader.getContent(elem);
4
4
  const { calculator, viewScaleInfo, viewSizeInfo } = opts;
5
5
  const { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
6
6
  rotateElement(ctx, { x, y, w, h, angle }, () => {
@@ -8,7 +8,10 @@ export function drawSVG(ctx, elem, opts) {
8
8
  opts.loader.load(elem, opts.elementAssets || {});
9
9
  }
10
10
  if (elem.type === 'svg' && content) {
11
+ const { opacity } = elem.detail;
12
+ ctx.globalAlpha = opacity ? opacity : 1;
11
13
  ctx.drawImage(content, x, y, w, h);
14
+ ctx.globalAlpha = 1;
12
15
  }
13
16
  });
14
17
  }
@@ -1,6 +1,7 @@
1
1
  import { rotateElement } from '@idraw/util';
2
- import { is, isColorStr } from '@idraw/util';
3
- import { drawBox } from './base';
2
+ import { is, isColorStr, getDefaultElementDetailConfig } from '@idraw/util';
3
+ import { drawBox } from './box';
4
+ const detailConfig = getDefaultElementDetailConfig();
4
5
  export function drawText(ctx, elem, opts) {
5
6
  const { calculator, viewScaleInfo, viewSizeInfo } = opts;
6
7
  const { x, y, w, h, angle } = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
@@ -12,14 +13,10 @@ export function drawText(ctx, elem, opts) {
12
13
  viewScaleInfo,
13
14
  viewSizeInfo,
14
15
  renderContent: () => {
15
- const detail = Object.assign({
16
- fontSize: 12,
17
- fontFamily: 'sans-serif',
18
- textAlign: 'center'
19
- }, elem.detail);
20
- const fontSize = detail.fontSize * viewScaleInfo.scale;
16
+ const detail = Object.assign(Object.assign({}, detailConfig), elem.detail);
17
+ const fontSize = (detail.fontSize || detailConfig.fontSize) * viewScaleInfo.scale;
21
18
  const lineHeight = detail.lineHeight ? detail.lineHeight * viewScaleInfo.scale : fontSize;
22
- ctx.fillStyle = elem.detail.color;
19
+ ctx.fillStyle = elem.detail.color || detailConfig.color;
23
20
  ctx.textBaseline = 'top';
24
21
  ctx.$setFont({
25
22
  fontWeight: detail.fontWeight,
@@ -13,5 +13,5 @@ export declare class Loader extends EventEmitter<LoaderEventMap> implements Rend
13
13
  private _loadResource;
14
14
  private _isExistingErrorStorage;
15
15
  load(element: Element<LoadElementType>, assets: ElementAssets): void;
16
- getContent(uuid: string): LoadContent | null;
16
+ getContent(element: Element<LoadElementType>): LoadContent | null;
17
17
  }