@effing/canvas 0.40.1 → 0.41.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 CHANGED
@@ -280,6 +280,8 @@ const png = canvas.encodeSync("png");
280
280
  | `transform` | `translate`, `scale`, `rotate`, `skewX`, `skewY` |
281
281
  | `transformOrigin` | CSS transform-origin string |
282
282
  | `filter` | CSS filter string |
283
+ | `backdropFilter` | CSS filter string applied to the backdrop |
284
+ | `clipPath` | Basic shapes, `shape()`, geometry boxes, `none` |
283
285
 
284
286
  ### Image
285
287
 
@@ -287,6 +289,69 @@ const png = canvas.encodeSync("png");
287
289
  | ----------- | ------------------------------------------------ |
288
290
  | `objectFit` | `contain`, `cover`, `fill`, `none`, `scale-down` |
289
291
 
292
+ ### Clip paths
293
+
294
+ `clipPath` clips the element's entire rendering — background, borders,
295
+ box-shadow and children — to a shape in the element's own coordinate space
296
+ (so it follows `transform`). Supported values:
297
+
298
+ - Basic shapes: `inset()` (with `round`), `circle()`, `ellipse()` (with
299
+ `at <position>`, `closest-side` / `farthest-side`), `polygon()`, `path()`,
300
+ `rect()` and `xywh()`.
301
+ - `shape()` with `from`, `move`, `line`, `hline`, `vline`, `curve`, `smooth`,
302
+ `arc` and `close` commands (`to` and `by` forms, `with` control points).
303
+ - A geometry box — `border-box` (default), `padding-box`, `content-box`,
304
+ `margin-box` — on its own or combined with a shape as its reference box.
305
+ - `none`.
306
+
307
+ Percentages resolve against the reference box; other lengths accept the usual
308
+ units. `url(#id)` references and `calc()` are not supported; an unrecognised
309
+ value leaves the element unclipped.
310
+
311
+ ```tsx
312
+ <div
313
+ style={{
314
+ width: 200,
315
+ height: 200,
316
+ background: "#3B82F6",
317
+ clipPath: "shape(from 50% 0, line to 100% 100%, line to 0 100%, close)",
318
+ }}
319
+ />
320
+ ```
321
+
322
+ ### Backdrop filters
323
+
324
+ `backdropFilter` filters whatever has already been painted behind the
325
+ element's border box (following `borderRadius`) and paints the result back
326
+ before the element's own background, so a translucent background on top gives
327
+ the usual frosted-glass look:
328
+
329
+ ```tsx
330
+ <div
331
+ style={{
332
+ padding: 24,
333
+ borderRadius: 16,
334
+ backdropFilter: "blur(12px) saturate(1.4)",
335
+ backgroundColor: "rgba(255, 255, 255, 0.25)",
336
+ }}
337
+ >
338
+ Frosted glass
339
+ </div>
340
+ ```
341
+
342
+ The backdrop is everything drawn on the canvas before the element — ancestors
343
+ and earlier siblings, but also anything you drew on the context before calling
344
+ `renderReactElement`. Elements painted later are not affected. Any filter
345
+ function the `filter` property accepts works here too. Filter lengths are CSS
346
+ pixels of the element and follow its `transform`, including non-uniform
347
+ scales and skews. At the canvas edge the backdrop is extended outward, like a
348
+ browser clamps it at the viewport edge, so a blur stays uniform there.
349
+
350
+ One difference from browsers: `opacity` is applied per drawing operation, not
351
+ to the element's subtree as a group. Under an ancestor with `opacity` below 1
352
+ the filtered backdrop is painted back with that opacity, so it blends with the
353
+ unfiltered backdrop instead of the ancestor forming its own backdrop root.
354
+
290
355
  ### Units
291
356
 
292
357
  `px`, `em`, `rem`, `%`, `vw`, `vh`, `vmin`, `vmax`, `pt`, `pc`, `in`, `cm`, `mm`
@@ -434,15 +499,25 @@ type FontData = {
434
499
  type ImageCache = Map<string, Promise<Image>>;
435
500
 
436
501
  type EmojiStyle =
437
- | "twemoji"
438
- | "openmoji"
439
- | "blobmoji"
440
- | "noto"
441
- | "fluent"
442
- | "fluentFlat";
502
+ "twemoji" | "openmoji" | "blobmoji" | "noto" | "fluent" | "fluentFlat";
443
503
  ```
444
504
 
445
- Also re-exports from `@napi-rs/canvas`: `Canvas`, `SKRSContext2D`, `GlobalFonts`, `Image`, `LottieAnimation`. (`loadImage` is wrapped — see above — not re-exported directly.)
505
+ ### Canvas Primitives
506
+
507
+ The building blocks you need alongside a context are re-exported from `@napi-rs/canvas`, so you never need to import (or declare a dependency on) `@napi-rs/canvas` directly: `Canvas`, `SKRSContext2D`, `GlobalFonts`, `Image`, `ImageData`, `Path2D`, `DOMMatrix`, `DOMPoint`, `DOMRect`, `PathOp`, `FillType`, `StrokeJoin`, `StrokeCap`, and `LottieAnimation`. (`loadImage` is wrapped — see above — not re-exported directly.)
508
+
509
+ ```typescript
510
+ import { createCanvas, Path2D } from "@effing/canvas";
511
+
512
+ const canvas = createCanvas(200, 200);
513
+ const ctx = canvas.getContext("2d");
514
+
515
+ const star = new Path2D(
516
+ "M100 10 L123 80 L195 80 L137 125 L160 195 L100 150 L40 195 L63 125 L5 80 L77 80 Z",
517
+ );
518
+ ctx.fillStyle = "gold";
519
+ ctx.fill(star);
520
+ ```
446
521
 
447
522
  ## Examples
448
523
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _napi_rs_canvas from '@napi-rs/canvas';
2
2
  import { Image, loadImage as loadImage$1, LottieAnimation, SKRSContext2D } from '@napi-rs/canvas';
3
- export { Canvas, GlobalFonts, Image, LottieAnimation, SKRSContext2D } from '@napi-rs/canvas';
3
+ export { Canvas, DOMMatrix, DOMPoint, DOMRect, FillType, GlobalFonts, Image, ImageData, LottieAnimation, Path2D, PathOp, SKRSContext2D, StrokeCap, StrokeJoin } from '@napi-rs/canvas';
4
4
  import { ReactNode } from 'react';
5
5
 
6
6
  /** Source types accepted by {@link loadImage}, mirroring @napi-rs/canvas. */
@@ -285,6 +285,8 @@ type ComputedStyle = {
285
285
  transformOrigin?: string;
286
286
  objectFit?: "contain" | "cover" | "fill" | "none" | "scale-down";
287
287
  filter?: string;
288
+ backdropFilter?: string;
289
+ clipPath?: string;
288
290
  textBoxTrim?: "none" | "trim-start" | "trim-end" | "trim-both";
289
291
  textBoxEdge?: string;
290
292
  WebkitTextStrokeWidth?: number | string;