@codehz/draw-call 0.5.2 → 0.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/README.md +7 -7
- package/{browser → dist/browser}/index.cjs +103 -148
- package/{node → dist/browser}/index.d.cts +16 -4
- package/dist/browser/index.d.ts +466 -0
- package/{browser → dist/browser}/index.js +102 -146
- package/{node → dist/node}/index.cjs +103 -148
- package/dist/node/index.d.cts +466 -0
- package/{node → dist/node}/index.d.mts +16 -4
- package/{node → dist/node}/index.mjs +102 -147
- package/examples/card.ts +1 -1
- package/examples/customdraw-basic.ts +39 -35
- package/examples/customdraw.ts +63 -59
- package/examples/demo.html +114 -0
- package/examples/demo.ts +1 -1
- package/examples/image-smoothing.ts +1 -1
- package/examples/richtext.ts +1 -1
- package/examples/transform.ts +1 -1
- package/package.json +55 -32
- package/browser/index.d.cts +0 -998
- package/browser/index.d.ts +0 -998
package/README.md
CHANGED
|
@@ -244,7 +244,7 @@ Transform({
|
|
|
244
244
|
|
|
245
245
|
### CustomDraw
|
|
246
246
|
|
|
247
|
-
|
|
247
|
+
自定义绘制组件,提供受控的绘制上下文。原生 Canvas API 可通过 `ctx.canvas` 访问,`save`/`restore`/transform 由 `CustomDrawContext` 管理。
|
|
248
248
|
|
|
249
249
|
```typescript
|
|
250
250
|
CustomDraw({
|
|
@@ -252,12 +252,12 @@ CustomDraw({
|
|
|
252
252
|
height: 100,
|
|
253
253
|
draw: (ctx, options) => {
|
|
254
254
|
// 使用原生 Canvas API 进行绘制
|
|
255
|
-
ctx.fillStyle = "#667eea";
|
|
256
|
-
ctx.fillRect(10, 10, 180, 80);
|
|
257
|
-
ctx.fillStyle = "#ffffff";
|
|
258
|
-
ctx.font = "bold 16px sans-serif";
|
|
259
|
-
ctx.textAlign = "center";
|
|
260
|
-
ctx.fillText("Custom Draw", 100, 60);
|
|
255
|
+
ctx.canvas.fillStyle = "#667eea";
|
|
256
|
+
ctx.canvas.fillRect(10, 10, 180, 80);
|
|
257
|
+
ctx.canvas.fillStyle = "#ffffff";
|
|
258
|
+
ctx.canvas.font = "bold 16px sans-serif";
|
|
259
|
+
ctx.canvas.textAlign = "center";
|
|
260
|
+
ctx.canvas.fillText("Custom Draw", 100, 60);
|
|
261
261
|
},
|
|
262
262
|
});
|
|
263
263
|
```
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value:
|
|
2
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
2
|
//#region src/compat/index.ts
|
|
4
3
|
const DOMMatrix = typeof window !== "undefined" ? window.DOMMatrix : void 0;
|
|
5
4
|
const Path2D = typeof window !== "undefined" ? window.Path2D : void 0;
|
|
@@ -9,7 +8,6 @@ function createRawCanvas(width, height) {
|
|
|
9
8
|
canvas.height = height;
|
|
10
9
|
return canvas;
|
|
11
10
|
}
|
|
12
|
-
|
|
13
11
|
//#endregion
|
|
14
12
|
//#region src/types/base.ts
|
|
15
13
|
function linearGradient(angle, ...stops) {
|
|
@@ -80,7 +78,6 @@ function normalizeBorderRadius(value) {
|
|
|
80
78
|
];
|
|
81
79
|
return value;
|
|
82
80
|
}
|
|
83
|
-
|
|
84
81
|
//#endregion
|
|
85
82
|
//#region src/layout/components/box.ts
|
|
86
83
|
/**
|
|
@@ -193,7 +190,6 @@ function measureBoxSize(element, ctx, availableWidth, measureChild) {
|
|
|
193
190
|
height: typeof element.height === "number" ? element.height : intrinsicHeight
|
|
194
191
|
};
|
|
195
192
|
}
|
|
196
|
-
|
|
197
193
|
//#endregion
|
|
198
194
|
//#region src/layout/components/customDraw.ts
|
|
199
195
|
/**
|
|
@@ -210,7 +206,6 @@ function measureCustomDrawSize(element, ctx, availableWidth, measureChild) {
|
|
|
210
206
|
height: 0
|
|
211
207
|
};
|
|
212
208
|
}
|
|
213
|
-
|
|
214
209
|
//#endregion
|
|
215
210
|
//#region src/layout/components/image.ts
|
|
216
211
|
/**
|
|
@@ -236,7 +231,6 @@ function measureImageSize(element, _ctx, _availableWidth) {
|
|
|
236
231
|
height: 0
|
|
237
232
|
};
|
|
238
233
|
}
|
|
239
|
-
|
|
240
234
|
//#endregion
|
|
241
235
|
//#region src/layout/components/richtext.ts
|
|
242
236
|
/**
|
|
@@ -404,7 +398,6 @@ function wrapRichText(ctx, spans, maxWidth, lineHeightScale = 1.2, elementStyle
|
|
|
404
398
|
}];
|
|
405
399
|
return lines;
|
|
406
400
|
}
|
|
407
|
-
|
|
408
401
|
//#endregion
|
|
409
402
|
//#region src/layout/components/stack.ts
|
|
410
403
|
/**
|
|
@@ -441,7 +434,6 @@ function measureStackSize(element, ctx, availableWidth, measureChild) {
|
|
|
441
434
|
height: typeof element.height === "number" ? element.height : intrinsicHeight
|
|
442
435
|
};
|
|
443
436
|
}
|
|
444
|
-
|
|
445
437
|
//#endregion
|
|
446
438
|
//#region src/layout/components/svg.ts
|
|
447
439
|
/**
|
|
@@ -475,7 +467,6 @@ function measureSvgSize(element, _ctx, _availableWidth) {
|
|
|
475
467
|
height: 0
|
|
476
468
|
};
|
|
477
469
|
}
|
|
478
|
-
|
|
479
470
|
//#endregion
|
|
480
471
|
//#region src/render/utils/font.ts
|
|
481
472
|
/**
|
|
@@ -486,23 +477,42 @@ function measureSvgSize(element, _ctx, _availableWidth) {
|
|
|
486
477
|
function buildFontString(font) {
|
|
487
478
|
return `${font.style ?? "normal"} ${font.weight ?? "normal"} ${font.size ?? 16}px ${font.family ?? "sans-serif"}`;
|
|
488
479
|
}
|
|
489
|
-
|
|
490
480
|
//#endregion
|
|
491
481
|
//#region src/layout/utils/measure.ts
|
|
482
|
+
const MEASURE_CACHE_LIMIT = 256;
|
|
492
483
|
function createCanvasMeasureContext(ctx) {
|
|
484
|
+
const cache = /* @__PURE__ */ new Map();
|
|
485
|
+
let lastFontString = null;
|
|
493
486
|
return { measureText(text, font) {
|
|
494
|
-
|
|
495
|
-
|
|
487
|
+
const fontString = buildFontString(font);
|
|
488
|
+
const key = fontString + "\0" + text;
|
|
489
|
+
const hit = cache.get(key);
|
|
490
|
+
if (hit !== void 0) {
|
|
491
|
+
cache.delete(key);
|
|
492
|
+
cache.set(key, hit);
|
|
493
|
+
return hit;
|
|
494
|
+
}
|
|
495
|
+
if (fontString !== lastFontString) {
|
|
496
|
+
ctx.font = fontString;
|
|
497
|
+
ctx.textBaseline = "middle";
|
|
498
|
+
lastFontString = fontString;
|
|
499
|
+
}
|
|
496
500
|
const metrics = ctx.measureText(text);
|
|
497
501
|
const height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;
|
|
498
502
|
const fontSize = font.size || 16;
|
|
499
|
-
|
|
503
|
+
const result = {
|
|
500
504
|
width: metrics.width,
|
|
501
505
|
height: height || fontSize,
|
|
502
506
|
offset: (metrics.actualBoundingBoxAscent - metrics.actualBoundingBoxDescent) / 2,
|
|
503
507
|
ascent: metrics.actualBoundingBoxAscent,
|
|
504
508
|
descent: metrics.actualBoundingBoxDescent
|
|
505
509
|
};
|
|
510
|
+
if (cache.size >= MEASURE_CACHE_LIMIT) {
|
|
511
|
+
const oldest = cache.keys().next().value;
|
|
512
|
+
if (oldest !== void 0) cache.delete(oldest);
|
|
513
|
+
}
|
|
514
|
+
cache.set(key, result);
|
|
515
|
+
return result;
|
|
506
516
|
} };
|
|
507
517
|
}
|
|
508
518
|
function wrapText(ctx, text, maxWidth, font) {
|
|
@@ -578,7 +588,6 @@ function truncateText(ctx, text, maxWidth, font, ellipsis = "...") {
|
|
|
578
588
|
offset
|
|
579
589
|
};
|
|
580
590
|
}
|
|
581
|
-
|
|
582
591
|
//#endregion
|
|
583
592
|
//#region src/layout/components/text.ts
|
|
584
593
|
/**
|
|
@@ -604,7 +613,6 @@ function measureTextSize(element, ctx, availableWidth) {
|
|
|
604
613
|
height: Math.max(height, lineHeightPx)
|
|
605
614
|
};
|
|
606
615
|
}
|
|
607
|
-
|
|
608
616
|
//#endregion
|
|
609
617
|
//#region src/layout/components/transform.ts
|
|
610
618
|
/**
|
|
@@ -615,7 +623,6 @@ function measureTextSize(element, ctx, availableWidth) {
|
|
|
615
623
|
function measureTransformSize(element, ctx, availableWidth, measureIntrinsicSize) {
|
|
616
624
|
return measureIntrinsicSize(element.children, ctx, availableWidth);
|
|
617
625
|
}
|
|
618
|
-
|
|
619
626
|
//#endregion
|
|
620
627
|
//#region src/layout/components/index.ts
|
|
621
628
|
/**
|
|
@@ -637,7 +644,6 @@ function measureIntrinsicSize(element, ctx, availableWidth) {
|
|
|
637
644
|
};
|
|
638
645
|
}
|
|
639
646
|
}
|
|
640
|
-
|
|
641
647
|
//#endregion
|
|
642
648
|
//#region src/layout/utils/offset.ts
|
|
643
649
|
/**
|
|
@@ -650,7 +656,6 @@ function applyOffset(node, dx, dy) {
|
|
|
650
656
|
node.layout.contentY += dy;
|
|
651
657
|
for (const child of node.children) applyOffset(child, dx, dy);
|
|
652
658
|
}
|
|
653
|
-
|
|
654
659
|
//#endregion
|
|
655
660
|
//#region src/types/layout.ts
|
|
656
661
|
function resolveSize(size, available, auto) {
|
|
@@ -665,7 +670,6 @@ function sizeNeedsParent(size) {
|
|
|
665
670
|
if (typeof size === "string" && size.endsWith("%")) return true;
|
|
666
671
|
return false;
|
|
667
672
|
}
|
|
668
|
-
|
|
669
673
|
//#endregion
|
|
670
674
|
//#region src/layout/engine.ts
|
|
671
675
|
/**
|
|
@@ -785,7 +789,14 @@ function computeLayoutImpl(element, ctx, constraints, x = 0, y = 0) {
|
|
|
785
789
|
}
|
|
786
790
|
if (layoutElement.type === "richtext") {
|
|
787
791
|
const lineHeight = layoutElement.lineHeight ?? 1.2;
|
|
788
|
-
|
|
792
|
+
const elementStyle = {
|
|
793
|
+
font: layoutElement.font,
|
|
794
|
+
color: layoutElement.color,
|
|
795
|
+
background: layoutElement.background,
|
|
796
|
+
underline: layoutElement.underline,
|
|
797
|
+
strikethrough: layoutElement.strikethrough
|
|
798
|
+
};
|
|
799
|
+
let lines = wrapRichText(ctx, layoutElement.spans, contentWidth, lineHeight, elementStyle);
|
|
789
800
|
if (layoutElement.maxLines && lines.length > layoutElement.maxLines) {
|
|
790
801
|
lines = lines.slice(0, layoutElement.maxLines);
|
|
791
802
|
if (layoutElement.ellipsis && lines.length > 0) {
|
|
@@ -1083,7 +1094,6 @@ function computeLayoutImpl(element, ctx, constraints, x = 0, y = 0) {
|
|
|
1083
1094
|
}
|
|
1084
1095
|
return node;
|
|
1085
1096
|
}
|
|
1086
|
-
|
|
1087
1097
|
//#endregion
|
|
1088
1098
|
//#region src/render/utils/colors.ts
|
|
1089
1099
|
function isGradientDescriptor$1(color) {
|
|
@@ -1119,7 +1129,6 @@ function resolveColor$1(ctx, color, x, y, width, height) {
|
|
|
1119
1129
|
if (isGradientDescriptor$1(color)) return resolveGradient$1(ctx, color, x, y, width, height);
|
|
1120
1130
|
return color;
|
|
1121
1131
|
}
|
|
1122
|
-
|
|
1123
1132
|
//#endregion
|
|
1124
1133
|
//#region src/render/utils/shadows.ts
|
|
1125
1134
|
function applyShadow$1(ctx, shadow) {
|
|
@@ -1141,7 +1150,6 @@ function clearShadow$1(ctx) {
|
|
|
1141
1150
|
ctx.shadowBlur = 0;
|
|
1142
1151
|
ctx.shadowColor = "transparent";
|
|
1143
1152
|
}
|
|
1144
|
-
|
|
1145
1153
|
//#endregion
|
|
1146
1154
|
//#region src/render/utils/shapes.ts
|
|
1147
1155
|
function roundRectPath(ctx, x, y, width, height, radius) {
|
|
@@ -1158,7 +1166,6 @@ function roundRectPath(ctx, x, y, width, height, radius) {
|
|
|
1158
1166
|
ctx.quadraticCurveTo(x, y, x + tl, y);
|
|
1159
1167
|
ctx.closePath();
|
|
1160
1168
|
}
|
|
1161
|
-
|
|
1162
1169
|
//#endregion
|
|
1163
1170
|
//#region src/render/components/box.ts
|
|
1164
1171
|
function renderBox(ctx, node) {
|
|
@@ -1187,125 +1194,90 @@ function renderBox(ctx, node) {
|
|
|
1187
1194
|
}
|
|
1188
1195
|
if (element.opacity !== void 0 && element.opacity < 1) ctx.globalAlpha = 1;
|
|
1189
1196
|
}
|
|
1190
|
-
|
|
1191
1197
|
//#endregion
|
|
1192
|
-
//#region src/render/components/
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1198
|
+
//#region src/render/components/CustomDrawContext.ts
|
|
1199
|
+
function cloneMatrix(matrix) {
|
|
1200
|
+
return new DOMMatrix([
|
|
1201
|
+
matrix.a,
|
|
1202
|
+
matrix.b,
|
|
1203
|
+
matrix.c,
|
|
1204
|
+
matrix.d,
|
|
1205
|
+
matrix.e,
|
|
1206
|
+
matrix.f
|
|
1207
|
+
]);
|
|
1208
|
+
}
|
|
1209
|
+
function toRelativeMatrix(transform) {
|
|
1210
|
+
if (transform === void 0) return new DOMMatrix();
|
|
1211
|
+
if (transform instanceof DOMMatrix) return cloneMatrix(transform);
|
|
1212
|
+
return new DOMMatrix(transform);
|
|
1213
|
+
}
|
|
1214
|
+
var ManagedCustomDrawContext = class {
|
|
1215
|
+
canvas;
|
|
1210
1216
|
baseTransform;
|
|
1211
|
-
/**
|
|
1212
|
-
* 相对变换矩阵(用户通过 setTransform 设置)
|
|
1213
|
-
*/
|
|
1214
1217
|
relativeTransform;
|
|
1215
|
-
|
|
1216
|
-
* save/restore 计数器
|
|
1217
|
-
*/
|
|
1218
|
+
transformStack = [];
|
|
1218
1219
|
saveCount = 0;
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
* @param baseTransform 初始的基础变换矩阵
|
|
1223
|
-
*/
|
|
1224
|
-
constructor(ctx, baseTransform) {
|
|
1225
|
-
this.ctx = ctx;
|
|
1226
|
-
this.baseTransform = baseTransform;
|
|
1220
|
+
constructor(canvas, baseTransform) {
|
|
1221
|
+
this.canvas = canvas;
|
|
1222
|
+
this.baseTransform = cloneMatrix(baseTransform);
|
|
1227
1223
|
this.relativeTransform = new DOMMatrix();
|
|
1228
1224
|
}
|
|
1229
|
-
/**
|
|
1230
|
-
* save() - 保存当前状态并增加计数
|
|
1231
|
-
*/
|
|
1232
1225
|
save() {
|
|
1233
1226
|
this.saveCount++;
|
|
1234
|
-
this.
|
|
1227
|
+
this.transformStack.push(cloneMatrix(this.relativeTransform));
|
|
1228
|
+
this.canvas.save();
|
|
1235
1229
|
}
|
|
1236
|
-
/**
|
|
1237
|
-
* restore() - 恢复上一个状态并减少计数
|
|
1238
|
-
*/
|
|
1239
1230
|
restore() {
|
|
1240
|
-
if (this.saveCount
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1231
|
+
if (this.saveCount === 0) return;
|
|
1232
|
+
this.saveCount--;
|
|
1233
|
+
this.relativeTransform = this.transformStack.pop() ?? new DOMMatrix();
|
|
1234
|
+
this.canvas.restore();
|
|
1235
|
+
this.applyRelativeTransform();
|
|
1244
1236
|
}
|
|
1245
|
-
/**
|
|
1246
|
-
* setTransform() - 设置相对变换
|
|
1247
|
-
*/
|
|
1248
|
-
setTransform(...args) {
|
|
1249
|
-
let matrix;
|
|
1250
|
-
if (args.length === 1 && args[0] instanceof DOMMatrix) matrix = args[0];
|
|
1251
|
-
else if (args.length === 6) matrix = new DOMMatrix([
|
|
1252
|
-
args[0],
|
|
1253
|
-
args[1],
|
|
1254
|
-
args[2],
|
|
1255
|
-
args[3],
|
|
1256
|
-
args[4],
|
|
1257
|
-
args[5]
|
|
1258
|
-
]);
|
|
1259
|
-
else return;
|
|
1260
|
-
this.relativeTransform = matrix;
|
|
1261
|
-
const actualTransform = this.baseTransform.multiply(matrix);
|
|
1262
|
-
this.ctx.setTransform(actualTransform);
|
|
1263
|
-
}
|
|
1264
|
-
/**
|
|
1265
|
-
* getTransform() - 返回相对变换(而不是绝对变换)
|
|
1266
|
-
*/
|
|
1267
1237
|
getTransform() {
|
|
1268
|
-
return this.relativeTransform;
|
|
1238
|
+
return cloneMatrix(this.relativeTransform);
|
|
1239
|
+
}
|
|
1240
|
+
setTransform(transform) {
|
|
1241
|
+
this.relativeTransform = toRelativeMatrix(transform);
|
|
1242
|
+
this.applyRelativeTransform();
|
|
1243
|
+
}
|
|
1244
|
+
resetTransform() {
|
|
1245
|
+
this.relativeTransform = new DOMMatrix();
|
|
1246
|
+
this.applyRelativeTransform();
|
|
1247
|
+
}
|
|
1248
|
+
translate(x, y) {
|
|
1249
|
+
this.relativeTransform = this.relativeTransform.translate(x, y);
|
|
1250
|
+
this.applyRelativeTransform();
|
|
1251
|
+
}
|
|
1252
|
+
rotate(angle) {
|
|
1253
|
+
this.relativeTransform = this.relativeTransform.rotate(angle * 180 / Math.PI);
|
|
1254
|
+
this.applyRelativeTransform();
|
|
1255
|
+
}
|
|
1256
|
+
scale(x, y) {
|
|
1257
|
+
this.relativeTransform = this.relativeTransform.scale(x, y ?? x);
|
|
1258
|
+
this.applyRelativeTransform();
|
|
1259
|
+
}
|
|
1260
|
+
transform(a, b, c, d, e, f) {
|
|
1261
|
+
this.relativeTransform = this.relativeTransform.multiply(new DOMMatrix([
|
|
1262
|
+
a,
|
|
1263
|
+
b,
|
|
1264
|
+
c,
|
|
1265
|
+
d,
|
|
1266
|
+
e,
|
|
1267
|
+
f
|
|
1268
|
+
]));
|
|
1269
|
+
this.applyRelativeTransform();
|
|
1269
1270
|
}
|
|
1270
|
-
/**
|
|
1271
|
-
* 析构函数级的清理 - 自动恢复所有未恢复的 save
|
|
1272
|
-
*/
|
|
1273
1271
|
destroy() {
|
|
1274
|
-
while (this.saveCount > 0)
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
}
|
|
1272
|
+
while (this.saveCount > 0) this.restore();
|
|
1273
|
+
}
|
|
1274
|
+
applyRelativeTransform() {
|
|
1275
|
+
this.canvas.setTransform(this.baseTransform.multiply(this.relativeTransform));
|
|
1279
1276
|
}
|
|
1280
1277
|
};
|
|
1281
|
-
function
|
|
1282
|
-
|
|
1283
|
-
return new Proxy(proxy, {
|
|
1284
|
-
get(target, prop, receiver) {
|
|
1285
|
-
if (prop === "save" || prop === "restore" || prop === "setTransform" || prop === "getTransform" || prop === "destroy") return Reflect.get(target, prop, receiver).bind(proxy);
|
|
1286
|
-
const ownValue = Reflect.get(target, prop, receiver);
|
|
1287
|
-
if (ownValue !== void 0) return ownValue;
|
|
1288
|
-
const contextValue = target.ctx[prop];
|
|
1289
|
-
if (typeof contextValue === "function") return contextValue.bind(target.ctx);
|
|
1290
|
-
return contextValue;
|
|
1291
|
-
},
|
|
1292
|
-
set(target, prop, value, _receiver) {
|
|
1293
|
-
target.ctx[prop] = value;
|
|
1294
|
-
return true;
|
|
1295
|
-
},
|
|
1296
|
-
has(target, prop) {
|
|
1297
|
-
if (prop === "save" || prop === "restore" || prop === "setTransform" || prop === "getTransform" || prop === "destroy") return true;
|
|
1298
|
-
return prop in target.ctx;
|
|
1299
|
-
},
|
|
1300
|
-
ownKeys(target) {
|
|
1301
|
-
return Reflect.ownKeys(target.ctx);
|
|
1302
|
-
},
|
|
1303
|
-
getOwnPropertyDescriptor(target, prop) {
|
|
1304
|
-
return Reflect.getOwnPropertyDescriptor(target.ctx, prop);
|
|
1305
|
-
}
|
|
1306
|
-
});
|
|
1278
|
+
function createCustomDrawContext(canvas, baseTransform) {
|
|
1279
|
+
return new ManagedCustomDrawContext(canvas, baseTransform);
|
|
1307
1280
|
}
|
|
1308
|
-
|
|
1309
1281
|
//#endregion
|
|
1310
1282
|
//#region src/render/components/customDraw.ts
|
|
1311
1283
|
/**
|
|
@@ -1316,7 +1288,7 @@ function renderCustomDraw(ctx, node) {
|
|
|
1316
1288
|
const element = node.element;
|
|
1317
1289
|
ctx.save();
|
|
1318
1290
|
ctx.translate(node.layout.x, node.layout.y);
|
|
1319
|
-
const
|
|
1291
|
+
const customCtx = createCustomDrawContext(ctx, ctx.getTransform());
|
|
1320
1292
|
const inner = () => {
|
|
1321
1293
|
if (node.children && node.children.length > 0) {
|
|
1322
1294
|
ctx.save();
|
|
@@ -1325,15 +1297,14 @@ function renderCustomDraw(ctx, node) {
|
|
|
1325
1297
|
ctx.restore();
|
|
1326
1298
|
}
|
|
1327
1299
|
};
|
|
1328
|
-
element.draw(
|
|
1300
|
+
element.draw(customCtx, {
|
|
1329
1301
|
inner,
|
|
1330
1302
|
width: node.layout.contentWidth,
|
|
1331
1303
|
height: node.layout.contentHeight
|
|
1332
1304
|
});
|
|
1333
|
-
|
|
1305
|
+
customCtx.destroy();
|
|
1334
1306
|
ctx.restore();
|
|
1335
1307
|
}
|
|
1336
|
-
|
|
1337
1308
|
//#endregion
|
|
1338
1309
|
//#region src/render/components/image.ts
|
|
1339
1310
|
function renderImage(ctx, node) {
|
|
@@ -1419,7 +1390,6 @@ function renderImage(ctx, node) {
|
|
|
1419
1390
|
}
|
|
1420
1391
|
if (element.opacity !== void 0 && element.opacity < 1) ctx.globalAlpha = 1;
|
|
1421
1392
|
}
|
|
1422
|
-
|
|
1423
1393
|
//#endregion
|
|
1424
1394
|
//#region src/render/components/richtext.ts
|
|
1425
1395
|
function renderRichText(ctx, node) {
|
|
@@ -1470,7 +1440,6 @@ function renderRichText(ctx, node) {
|
|
|
1470
1440
|
currentY += line.height;
|
|
1471
1441
|
}
|
|
1472
1442
|
}
|
|
1473
|
-
|
|
1474
1443
|
//#endregion
|
|
1475
1444
|
//#region src/render/components/svg.ts
|
|
1476
1445
|
function isGradientDescriptor(color) {
|
|
@@ -1742,7 +1711,6 @@ function renderSvg(ctx, node) {
|
|
|
1742
1711
|
for (const child of element.children) renderSvgChild(ctx, child, transform, bounds, baseTransform);
|
|
1743
1712
|
ctx.restore();
|
|
1744
1713
|
}
|
|
1745
|
-
|
|
1746
1714
|
//#endregion
|
|
1747
1715
|
//#region src/render/components/text.ts
|
|
1748
1716
|
function renderText(ctx, node) {
|
|
@@ -1777,7 +1745,6 @@ function renderText(ctx, node) {
|
|
|
1777
1745
|
}
|
|
1778
1746
|
if (element.shadow) clearShadow$1(ctx);
|
|
1779
1747
|
}
|
|
1780
|
-
|
|
1781
1748
|
//#endregion
|
|
1782
1749
|
//#region src/render/components/transform.ts
|
|
1783
1750
|
/**
|
|
@@ -1853,7 +1820,6 @@ function renderTransform(ctx, node) {
|
|
|
1853
1820
|
renderNode(ctx, childNode);
|
|
1854
1821
|
ctx.restore();
|
|
1855
1822
|
}
|
|
1856
|
-
|
|
1857
1823
|
//#endregion
|
|
1858
1824
|
//#region src/render/index.ts
|
|
1859
1825
|
function renderNode(ctx, node) {
|
|
@@ -1893,7 +1859,6 @@ function renderNode(ctx, node) {
|
|
|
1893
1859
|
break;
|
|
1894
1860
|
}
|
|
1895
1861
|
}
|
|
1896
|
-
|
|
1897
1862
|
//#endregion
|
|
1898
1863
|
//#region src/canvas.ts
|
|
1899
1864
|
/**
|
|
@@ -1963,7 +1928,6 @@ function createCanvas(options) {
|
|
|
1963
1928
|
}
|
|
1964
1929
|
};
|
|
1965
1930
|
}
|
|
1966
|
-
|
|
1967
1931
|
//#endregion
|
|
1968
1932
|
//#region src/components/Box.ts
|
|
1969
1933
|
function Box(props) {
|
|
@@ -1972,7 +1936,6 @@ function Box(props) {
|
|
|
1972
1936
|
...props
|
|
1973
1937
|
};
|
|
1974
1938
|
}
|
|
1975
|
-
|
|
1976
1939
|
//#endregion
|
|
1977
1940
|
//#region src/components/CustomDraw.ts
|
|
1978
1941
|
function CustomDraw(props) {
|
|
@@ -1981,7 +1944,6 @@ function CustomDraw(props) {
|
|
|
1981
1944
|
...props
|
|
1982
1945
|
};
|
|
1983
1946
|
}
|
|
1984
|
-
|
|
1985
1947
|
//#endregion
|
|
1986
1948
|
//#region src/components/Image.ts
|
|
1987
1949
|
function Image(props) {
|
|
@@ -1990,7 +1952,6 @@ function Image(props) {
|
|
|
1990
1952
|
...props
|
|
1991
1953
|
};
|
|
1992
1954
|
}
|
|
1993
|
-
|
|
1994
1955
|
//#endregion
|
|
1995
1956
|
//#region src/components/RichText.ts
|
|
1996
1957
|
function RichText(props) {
|
|
@@ -1999,7 +1960,6 @@ function RichText(props) {
|
|
|
1999
1960
|
...props
|
|
2000
1961
|
};
|
|
2001
1962
|
}
|
|
2002
|
-
|
|
2003
1963
|
//#endregion
|
|
2004
1964
|
//#region src/components/Stack.ts
|
|
2005
1965
|
function Stack(props) {
|
|
@@ -2008,7 +1968,6 @@ function Stack(props) {
|
|
|
2008
1968
|
...props
|
|
2009
1969
|
};
|
|
2010
1970
|
}
|
|
2011
|
-
|
|
2012
1971
|
//#endregion
|
|
2013
1972
|
//#region src/components/Svg.ts
|
|
2014
1973
|
function Svg(props) {
|
|
@@ -2055,7 +2014,6 @@ const svg = {
|
|
|
2055
2014
|
...props
|
|
2056
2015
|
})
|
|
2057
2016
|
};
|
|
2058
|
-
|
|
2059
2017
|
//#endregion
|
|
2060
2018
|
//#region src/components/Text.ts
|
|
2061
2019
|
function Text(props) {
|
|
@@ -2064,7 +2022,6 @@ function Text(props) {
|
|
|
2064
2022
|
...props
|
|
2065
2023
|
};
|
|
2066
2024
|
}
|
|
2067
|
-
|
|
2068
2025
|
//#endregion
|
|
2069
2026
|
//#region src/components/Transform.ts
|
|
2070
2027
|
function Transform(props) {
|
|
@@ -2073,7 +2030,6 @@ function Transform(props) {
|
|
|
2073
2030
|
...props
|
|
2074
2031
|
};
|
|
2075
2032
|
}
|
|
2076
|
-
|
|
2077
2033
|
//#endregion
|
|
2078
2034
|
//#region src/layout/utils/print.ts
|
|
2079
2035
|
/**
|
|
@@ -2133,7 +2089,6 @@ function printLayout(node) {
|
|
|
2133
2089
|
function layoutToString(node, _indent = " ") {
|
|
2134
2090
|
return printLayoutToString(node, "", true).join("\n");
|
|
2135
2091
|
}
|
|
2136
|
-
|
|
2137
2092
|
//#endregion
|
|
2138
2093
|
exports.Box = Box;
|
|
2139
2094
|
exports.CustomDraw = CustomDraw;
|
|
@@ -2150,4 +2105,4 @@ exports.layoutToString = layoutToString;
|
|
|
2150
2105
|
exports.linearGradient = linearGradient;
|
|
2151
2106
|
exports.printLayout = printLayout;
|
|
2152
2107
|
exports.radialGradient = radialGradient;
|
|
2153
|
-
exports.svg = svg;
|
|
2108
|
+
exports.svg = svg;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Canvas } from "@napi-rs/canvas";
|
|
1
|
+
import { Canvas, DOMMatrix } from "@napi-rs/canvas";
|
|
2
2
|
|
|
3
3
|
//#region src/types/base.d.ts
|
|
4
4
|
type Size = number | `${number}%` | "auto" | "fill";
|
|
@@ -152,7 +152,19 @@ interface LayoutConstraints {
|
|
|
152
152
|
//#endregion
|
|
153
153
|
//#region src/types/components.d.ts
|
|
154
154
|
type ElementType = "box" | "text" | "richtext" | "image" | "svg" | "stack" | "transform" | "customdraw";
|
|
155
|
-
interface
|
|
155
|
+
interface CustomDrawContext {
|
|
156
|
+
readonly canvas: CanvasRenderingContext2D;
|
|
157
|
+
save(): void;
|
|
158
|
+
restore(): void;
|
|
159
|
+
getTransform(): DOMMatrix;
|
|
160
|
+
setTransform(transform?: DOMMatrix | [number, number, number, number, number, number]): void;
|
|
161
|
+
resetTransform(): void;
|
|
162
|
+
translate(x: number, y: number): void;
|
|
163
|
+
rotate(angle: number): void;
|
|
164
|
+
scale(x: number, y?: number): void;
|
|
165
|
+
transform(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
|
166
|
+
}
|
|
167
|
+
interface CustomDrawOptions {
|
|
156
168
|
inner?: () => void;
|
|
157
169
|
width: number;
|
|
158
170
|
height: number;
|
|
@@ -357,7 +369,7 @@ interface TransformElement extends ElementBase, TransformProps {
|
|
|
357
369
|
type: "transform";
|
|
358
370
|
}
|
|
359
371
|
interface CustomDrawProps extends LayoutProps {
|
|
360
|
-
draw: (ctx:
|
|
372
|
+
draw: (ctx: CustomDrawContext, options: CustomDrawOptions) => void;
|
|
361
373
|
children?: Element;
|
|
362
374
|
}
|
|
363
375
|
interface CustomDrawElement extends ElementBase, CustomDrawProps {
|
|
@@ -451,4 +463,4 @@ declare function printLayout(node: LayoutNode): void;
|
|
|
451
463
|
*/
|
|
452
464
|
declare function layoutToString(node: LayoutNode, _indent?: string): string;
|
|
453
465
|
//#endregion
|
|
454
|
-
export { type AlignItems, type AlignSelf, type Border, type Bounds, Box, type BoxElement, type BoxProps, type CanvasOptions, type Color, type ColorStop, type ContainerLayoutProps, CustomDraw, type CustomDrawElement, type CustomDrawProps, type DrawCallCanvas, type Element, type FlexDirection, type FontProps, type GradientDescriptor, Image, type JustifyContent, type LayoutElement, type LayoutNode, type LayoutProps, type LinearGradientDescriptor, type MeasureContext, type
|
|
466
|
+
export { type AlignItems, type AlignSelf, type Border, type Bounds, Box, type BoxElement, type BoxProps, type CanvasOptions, type Color, type ColorStop, type ContainerLayoutProps, CustomDraw, type CustomDrawContext, type CustomDrawElement, type CustomDrawOptions, type CustomDrawProps, type DrawCallCanvas, type Element, type FlexDirection, type FontProps, type GradientDescriptor, Image, type JustifyContent, type LayoutElement, type LayoutNode, type LayoutProps, type LinearGradientDescriptor, type MeasureContext, type RadialGradientDescriptor, RichText, type RichTextElement, type RichTextProps, type RichTextSpan, type Shadow, type Size, type Spacing, Stack, type StackAlign, type StackElement, type StackProps, type StrokeProps, Svg, type SvgAlign, type SvgChild, type SvgCircleChild, type SvgElement, type SvgEllipseChild, type SvgGroupChild, type SvgLineChild, type SvgPathChild, type SvgPolygonChild, type SvgPolylineChild, type SvgProps, type SvgRectChild, type SvgStyleProps, type SvgTextChild, type SvgTransformProps, Text, type TextElement, type TextProps, Transform, type TransformElement, type TransformProps, computeLayout, createCanvas, createCanvasMeasureContext, layoutToString, linearGradient, printLayout, radialGradient, svg };
|