@clypra/engine 1.1.2 → 1.2.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/dist/index.cjs +88 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +88 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -817,6 +817,17 @@ function restoreLetterSpacing(ctx, saved) {
|
|
|
817
817
|
function getCanvas2DContext2(canvas) {
|
|
818
818
|
return canvas.getContext("2d");
|
|
819
819
|
}
|
|
820
|
+
function ctxSupportsFilter(ctx) {
|
|
821
|
+
try {
|
|
822
|
+
const prev = ctx.filter;
|
|
823
|
+
ctx.filter = "blur(4px)";
|
|
824
|
+
const ok = typeof ctx.filter === "string" && ctx.filter.includes("blur");
|
|
825
|
+
ctx.filter = prev;
|
|
826
|
+
return ok;
|
|
827
|
+
} catch {
|
|
828
|
+
return false;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
820
831
|
function renderTextEffectCore(ctx, cfg) {
|
|
821
832
|
if (cfg.customRenderer === "InkBrushEngine") {
|
|
822
833
|
const engine = new InkBrushEngine(cfg);
|
|
@@ -1126,19 +1137,31 @@ function renderTextEffectCore(ctx, cfg) {
|
|
|
1126
1137
|
const vpy = cHeight / 2 + (bevelVanishingPointY !== void 0 ? bevelVanishingPointY : 80) / 100 * (cHeight / 2);
|
|
1127
1138
|
const fl = Math.max(100, bevelFocalLength !== void 0 ? bevelFocalLength : 400);
|
|
1128
1139
|
if (bevelBlur && bevelBlur > 0) {
|
|
1129
|
-
ctx.save();
|
|
1130
|
-
ctx.filter = `blur(${bevelBlur}px)`;
|
|
1131
1140
|
const blurColor = bevelBlurColor || bevelShadow || "#000000";
|
|
1132
|
-
|
|
1133
|
-
const scale = fl / (fl + i);
|
|
1141
|
+
if (ctxSupportsFilter(ctx)) {
|
|
1134
1142
|
ctx.save();
|
|
1135
|
-
ctx.
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1143
|
+
ctx.filter = `blur(${bevelBlur}px)`;
|
|
1144
|
+
for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
|
|
1145
|
+
const scale = fl / (fl + i);
|
|
1146
|
+
ctx.save();
|
|
1147
|
+
ctx.translate(vpx, vpy);
|
|
1148
|
+
ctx.scale(scale, scale);
|
|
1149
|
+
ctx.translate(-vpx, -vpy);
|
|
1150
|
+
renderLines("fill", blurColor);
|
|
1151
|
+
ctx.restore();
|
|
1152
|
+
}
|
|
1139
1153
|
ctx.restore();
|
|
1154
|
+
} else {
|
|
1155
|
+
for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
|
|
1156
|
+
const scale = fl / (fl + i);
|
|
1157
|
+
ctx.save();
|
|
1158
|
+
ctx.translate(vpx, vpy);
|
|
1159
|
+
ctx.scale(scale, scale);
|
|
1160
|
+
ctx.translate(-vpx, -vpy);
|
|
1161
|
+
renderWithShadowTrick("fill", blurColor, bevelBlur, 0, 0, 100);
|
|
1162
|
+
ctx.restore();
|
|
1163
|
+
}
|
|
1140
1164
|
}
|
|
1141
|
-
ctx.restore();
|
|
1142
1165
|
}
|
|
1143
1166
|
ctx.save();
|
|
1144
1167
|
for (let i = bevelDepth; i > 0; i--) {
|
|
@@ -1185,14 +1208,21 @@ function renderTextEffectCore(ctx, cfg) {
|
|
|
1185
1208
|
return { dx: i, dy: i };
|
|
1186
1209
|
};
|
|
1187
1210
|
if (bevelBlur && bevelBlur > 0) {
|
|
1188
|
-
ctx.save();
|
|
1189
|
-
ctx.filter = `blur(${bevelBlur}px)`;
|
|
1190
1211
|
const blurColor = bevelBlurColor || bevelShadow || "#000000";
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1212
|
+
if (ctxSupportsFilter(ctx)) {
|
|
1213
|
+
ctx.save();
|
|
1214
|
+
ctx.filter = `blur(${bevelBlur}px)`;
|
|
1215
|
+
for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
|
|
1216
|
+
const { dx, dy } = getDirOffset(i);
|
|
1217
|
+
renderLines("fill", blurColor, dx, dy);
|
|
1218
|
+
}
|
|
1219
|
+
ctx.restore();
|
|
1220
|
+
} else {
|
|
1221
|
+
for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
|
|
1222
|
+
const { dx, dy } = getDirOffset(i);
|
|
1223
|
+
renderWithShadowTrick("fill", blurColor, bevelBlur, dx, dy, 100);
|
|
1224
|
+
}
|
|
1194
1225
|
}
|
|
1195
|
-
ctx.restore();
|
|
1196
1226
|
}
|
|
1197
1227
|
ctx.save();
|
|
1198
1228
|
for (let i = bevelDepth; i > 0; i--) {
|
|
@@ -1246,24 +1276,51 @@ function renderTextEffectCore(ctx, cfg) {
|
|
|
1246
1276
|
customStrokeStyle = grad;
|
|
1247
1277
|
}
|
|
1248
1278
|
const drawStrokeLayer = (color, width, blurAmount, opacity, position) => {
|
|
1249
|
-
ctx
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1279
|
+
if (blurAmount > 0 && ctxSupportsFilter(ctx)) {
|
|
1280
|
+
ctx.save();
|
|
1281
|
+
ctx.globalAlpha = opacity / 100;
|
|
1282
|
+
ctx.strokeStyle = color;
|
|
1253
1283
|
ctx.filter = `blur(${blurAmount}px)`;
|
|
1284
|
+
if (position === "outside") {
|
|
1285
|
+
ctx.lineWidth = width * 2;
|
|
1286
|
+
renderLines("stroke");
|
|
1287
|
+
} else if (position === "center") {
|
|
1288
|
+
ctx.lineWidth = width;
|
|
1289
|
+
renderLines("stroke");
|
|
1290
|
+
} else if (position === "inside") {
|
|
1291
|
+
ctx.globalCompositeOperation = "source-atop";
|
|
1292
|
+
ctx.lineWidth = width * 2;
|
|
1293
|
+
renderLines("stroke");
|
|
1294
|
+
}
|
|
1295
|
+
ctx.restore();
|
|
1296
|
+
} else if (blurAmount > 0) {
|
|
1297
|
+
const colorStr = typeof color === "string" ? color : strokeColor;
|
|
1298
|
+
const spread = position === "center" ? width / 2 : width;
|
|
1299
|
+
if (position === "inside") {
|
|
1300
|
+
ctx.save();
|
|
1301
|
+
ctx.globalCompositeOperation = "source-atop";
|
|
1302
|
+
renderWithShadowTrick("stroke", colorStr, blurAmount, 0, 0, opacity, void 0, spread);
|
|
1303
|
+
ctx.restore();
|
|
1304
|
+
} else {
|
|
1305
|
+
renderWithShadowTrick("stroke", colorStr, blurAmount, 0, 0, opacity, void 0, spread);
|
|
1306
|
+
}
|
|
1307
|
+
} else {
|
|
1308
|
+
ctx.save();
|
|
1309
|
+
ctx.globalAlpha = opacity / 100;
|
|
1310
|
+
ctx.strokeStyle = color;
|
|
1311
|
+
if (position === "outside") {
|
|
1312
|
+
ctx.lineWidth = width * 2;
|
|
1313
|
+
renderLines("stroke");
|
|
1314
|
+
} else if (position === "center") {
|
|
1315
|
+
ctx.lineWidth = width;
|
|
1316
|
+
renderLines("stroke");
|
|
1317
|
+
} else if (position === "inside") {
|
|
1318
|
+
ctx.globalCompositeOperation = "source-atop";
|
|
1319
|
+
ctx.lineWidth = width * 2;
|
|
1320
|
+
renderLines("stroke");
|
|
1321
|
+
}
|
|
1322
|
+
ctx.restore();
|
|
1254
1323
|
}
|
|
1255
|
-
if (position === "outside") {
|
|
1256
|
-
ctx.lineWidth = width * 2;
|
|
1257
|
-
renderLines("stroke");
|
|
1258
|
-
} else if (position === "center") {
|
|
1259
|
-
ctx.lineWidth = width;
|
|
1260
|
-
renderLines("stroke");
|
|
1261
|
-
} else if (position === "inside") {
|
|
1262
|
-
ctx.globalCompositeOperation = "source-atop";
|
|
1263
|
-
ctx.lineWidth = width * 2;
|
|
1264
|
-
renderLines("stroke");
|
|
1265
|
-
}
|
|
1266
|
-
ctx.restore();
|
|
1267
1324
|
};
|
|
1268
1325
|
if (sType === "double") {
|
|
1269
1326
|
const outerWidth = strokeWidth + sWidthSecondary;
|