@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 CHANGED
@@ -1007,6 +1007,17 @@ function restoreLetterSpacing(ctx, saved) {
1007
1007
  function getCanvas2DContext2(canvas) {
1008
1008
  return canvas.getContext("2d");
1009
1009
  }
1010
+ function ctxSupportsFilter(ctx) {
1011
+ try {
1012
+ const prev = ctx.filter;
1013
+ ctx.filter = "blur(4px)";
1014
+ const ok = typeof ctx.filter === "string" && ctx.filter.includes("blur");
1015
+ ctx.filter = prev;
1016
+ return ok;
1017
+ } catch {
1018
+ return false;
1019
+ }
1020
+ }
1010
1021
  function renderTextEffectCore(ctx, cfg) {
1011
1022
  if (cfg.customRenderer === "InkBrushEngine") {
1012
1023
  const engine = new InkBrushEngine(cfg);
@@ -1316,19 +1327,31 @@ function renderTextEffectCore(ctx, cfg) {
1316
1327
  const vpy = cHeight / 2 + (bevelVanishingPointY !== void 0 ? bevelVanishingPointY : 80) / 100 * (cHeight / 2);
1317
1328
  const fl = Math.max(100, bevelFocalLength !== void 0 ? bevelFocalLength : 400);
1318
1329
  if (bevelBlur && bevelBlur > 0) {
1319
- ctx.save();
1320
- ctx.filter = `blur(${bevelBlur}px)`;
1321
1330
  const blurColor = bevelBlurColor || bevelShadow || "#000000";
1322
- for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
1323
- const scale = fl / (fl + i);
1331
+ if (ctxSupportsFilter(ctx)) {
1324
1332
  ctx.save();
1325
- ctx.translate(vpx, vpy);
1326
- ctx.scale(scale, scale);
1327
- ctx.translate(-vpx, -vpy);
1328
- renderLines("fill", blurColor);
1333
+ ctx.filter = `blur(${bevelBlur}px)`;
1334
+ for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
1335
+ const scale = fl / (fl + i);
1336
+ ctx.save();
1337
+ ctx.translate(vpx, vpy);
1338
+ ctx.scale(scale, scale);
1339
+ ctx.translate(-vpx, -vpy);
1340
+ renderLines("fill", blurColor);
1341
+ ctx.restore();
1342
+ }
1329
1343
  ctx.restore();
1344
+ } else {
1345
+ for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
1346
+ const scale = fl / (fl + i);
1347
+ ctx.save();
1348
+ ctx.translate(vpx, vpy);
1349
+ ctx.scale(scale, scale);
1350
+ ctx.translate(-vpx, -vpy);
1351
+ renderWithShadowTrick("fill", blurColor, bevelBlur, 0, 0, 100);
1352
+ ctx.restore();
1353
+ }
1330
1354
  }
1331
- ctx.restore();
1332
1355
  }
1333
1356
  ctx.save();
1334
1357
  for (let i = bevelDepth; i > 0; i--) {
@@ -1375,14 +1398,21 @@ function renderTextEffectCore(ctx, cfg) {
1375
1398
  return { dx: i, dy: i };
1376
1399
  };
1377
1400
  if (bevelBlur && bevelBlur > 0) {
1378
- ctx.save();
1379
- ctx.filter = `blur(${bevelBlur}px)`;
1380
1401
  const blurColor = bevelBlurColor || bevelShadow || "#000000";
1381
- for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
1382
- const { dx, dy } = getDirOffset(i);
1383
- renderLines("fill", blurColor, dx, dy);
1402
+ if (ctxSupportsFilter(ctx)) {
1403
+ ctx.save();
1404
+ ctx.filter = `blur(${bevelBlur}px)`;
1405
+ for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
1406
+ const { dx, dy } = getDirOffset(i);
1407
+ renderLines("fill", blurColor, dx, dy);
1408
+ }
1409
+ ctx.restore();
1410
+ } else {
1411
+ for (let i = bevelDepth; i > 0; i -= Math.max(1, Math.floor(bevelDepth / 4))) {
1412
+ const { dx, dy } = getDirOffset(i);
1413
+ renderWithShadowTrick("fill", blurColor, bevelBlur, dx, dy, 100);
1414
+ }
1384
1415
  }
1385
- ctx.restore();
1386
1416
  }
1387
1417
  ctx.save();
1388
1418
  for (let i = bevelDepth; i > 0; i--) {
@@ -1436,24 +1466,51 @@ function renderTextEffectCore(ctx, cfg) {
1436
1466
  customStrokeStyle = grad;
1437
1467
  }
1438
1468
  const drawStrokeLayer = (color, width, blurAmount, opacity, position) => {
1439
- ctx.save();
1440
- ctx.globalAlpha = opacity / 100;
1441
- ctx.strokeStyle = color;
1442
- if (blurAmount > 0) {
1469
+ if (blurAmount > 0 && ctxSupportsFilter(ctx)) {
1470
+ ctx.save();
1471
+ ctx.globalAlpha = opacity / 100;
1472
+ ctx.strokeStyle = color;
1443
1473
  ctx.filter = `blur(${blurAmount}px)`;
1474
+ if (position === "outside") {
1475
+ ctx.lineWidth = width * 2;
1476
+ renderLines("stroke");
1477
+ } else if (position === "center") {
1478
+ ctx.lineWidth = width;
1479
+ renderLines("stroke");
1480
+ } else if (position === "inside") {
1481
+ ctx.globalCompositeOperation = "source-atop";
1482
+ ctx.lineWidth = width * 2;
1483
+ renderLines("stroke");
1484
+ }
1485
+ ctx.restore();
1486
+ } else if (blurAmount > 0) {
1487
+ const colorStr = typeof color === "string" ? color : strokeColor;
1488
+ const spread = position === "center" ? width / 2 : width;
1489
+ if (position === "inside") {
1490
+ ctx.save();
1491
+ ctx.globalCompositeOperation = "source-atop";
1492
+ renderWithShadowTrick("stroke", colorStr, blurAmount, 0, 0, opacity, void 0, spread);
1493
+ ctx.restore();
1494
+ } else {
1495
+ renderWithShadowTrick("stroke", colorStr, blurAmount, 0, 0, opacity, void 0, spread);
1496
+ }
1497
+ } else {
1498
+ ctx.save();
1499
+ ctx.globalAlpha = opacity / 100;
1500
+ ctx.strokeStyle = color;
1501
+ if (position === "outside") {
1502
+ ctx.lineWidth = width * 2;
1503
+ renderLines("stroke");
1504
+ } else if (position === "center") {
1505
+ ctx.lineWidth = width;
1506
+ renderLines("stroke");
1507
+ } else if (position === "inside") {
1508
+ ctx.globalCompositeOperation = "source-atop";
1509
+ ctx.lineWidth = width * 2;
1510
+ renderLines("stroke");
1511
+ }
1512
+ ctx.restore();
1444
1513
  }
1445
- if (position === "outside") {
1446
- ctx.lineWidth = width * 2;
1447
- renderLines("stroke");
1448
- } else if (position === "center") {
1449
- ctx.lineWidth = width;
1450
- renderLines("stroke");
1451
- } else if (position === "inside") {
1452
- ctx.globalCompositeOperation = "source-atop";
1453
- ctx.lineWidth = width * 2;
1454
- renderLines("stroke");
1455
- }
1456
- ctx.restore();
1457
1514
  };
1458
1515
  if (sType === "double") {
1459
1516
  const outerWidth = strokeWidth + sWidthSecondary;