You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0782797
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: CHANGELOG.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,7 @@
7
7
Upgrading from 3.x? Upgrade to the latest 3.x release first, fix the deprecation hints, then switch: the [migration guide](https://imagescript.dev/documents/Migrating_to_4.0.html) lists every change and the nine behavior changes that don't show up as deprecations or compile errors.
8
8
9
9
-**Methods that take options refuse anything else than an object**: a stray number, string, boolean or `null` as the options of `cropCircle()`, `Image.renderText()`, the encoders (`encodeWebP()`, `encodeAVIF()`, `encodeJXL()`, ...), `quantize()`, `transform()`, `dropShadow()`, `outline()`, the gradients, `Image.decode()`, the animation encoders, and `new GainMap()` throws a `TypeError` that names the working form (e.g. `cropCircle({ size: 'cover' })`), so the 3.x calls that are gone like `cropCircle(true)` or `Image.renderText(font, 32, 'Hi')` fail instead of being ignored. Only the type of the argument is checked: a key that isn't an option is still ignored, so a typo like `{ maxWith: 300 }` isn't caught.
10
+
10
11
-**The mode constants are removed, modes are plain strings**: `Image.RESIZE_*`, `Image.SVG_MODE_*`, `Frame.DISPOSAL_*` and the `ResizeModes`, `SVGScaleModes` and `FrameDisposalModes` classes are gone. Resize modes are `'nearest-neighbor'`, `'bilinear'`, `'bicubic'` and `'area'` (the `ResizeMode` type), disposal modes `'any'`, `'keep'`, `'previous'` and `'background'` (`FrameDisposalModeName`), and the SVG modes became options of `renderSVG()` (below). `Image.RESIZE_AUTO`/`ResizeModes.AUTO` is `image.resize({ width: 256 })`. The old values are no longer accepted either: `'RESIZE_BILINEAR'`, the numbers 1-3 for SVG scale modes and the numeric disposal ids 0-3.
11
12
12
13
-**`absolute` is removed from `opacity()`, `red()`, `green()`, `blue()`, `lightness()` and `saturation()`**: they only scale now, `image.red(0.5)` (and `AdjustOptions`, the type of their options, is removed). For a fixed color, use `image.recolor()`. In JavaScript a leftover `image.red(0.5, true)` scales the channel instead of setting it.
@@ -83,7 +84,7 @@ Upgrading from 3.x? Upgrade to the latest 3.x release first, fix the deprecation
83
84
84
85
-**An animation has its own canvas size**: decoded animations keep the file's, `new Animation(frames, { width, height })` sets one, and `resize()` sets the new one. Without one it is the frames' extent, as before. Frames (or their parts) outside the canvas aren't encoded.
85
86
86
-
-**The encoders return `Promise<Uint8Array<ArrayBuffer>>`**, which`new Blob()`, `new Response()` and `crypto.subtle` take without a cast in TypeScript 5.9 and newer (needs TypeScript 5.7).
87
+
-**The encoders return `Promise<Uint8Array<ArrayBuffer>>`** instead of `Promise<Uint8Array>`, so`new Blob()`, `new Response()` and `crypto.subtle` take the output without a cast, also with the stricter DOM types of TypeScript 5.9 and newer. The type needs TypeScript 5.7 or newer.
87
88
88
89
### New
89
90
@@ -93,7 +94,7 @@ Upgrading from 3.x? Upgrade to the latest 3.x release first, fix the deprecation
93
94
-`Colors.gradient()` takes an array of evenly spaced colors, like the `stops` of the gradient functions.
94
95
-`Animation.scale()`, `Animation.trim()`, `Animation.rotate()`, `Animation.transform()`, `Animation.dropShadow()` and `Animation.outline()`. `scale()` and `trim()` keep the frames; the others work on the composited animation (full canvas frames) and resize the canvas.
95
96
-`Frame.contain()`, `Frame.cover()`, `Frame.rotate()`, `Frame.transform()`, `Frame.dropShadow()` and `Frame.outline()`, which move the offsets like `Frame.resize()` and `Frame.crop()`.
96
-
-`Image.encodeGIF()` for single images, with `colors`, `dither` and `ditherStrength` (also on the animation encoders).
97
+
-`Image.encodeGIF()` for single images, with `colors`, `dither` and `ditherStrength` (also on the animation encoders), and the `DitherMethod` type that `quantize()` and the GIF encoders share.
97
98
-`renderSVG({ fonts })` takes a single font without an array.
Copy file name to clipboardExpand all lines: guides/Migrating to 4.0.md
+16-12Lines changed: 16 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -97,9 +97,9 @@ new Animation(frames, { loopCount: Infinity });
97
97
animation.loopCount===Infinity;
98
98
```
99
99
100
-
The finite counts are the same: `0` plays once, `2` plays three times. The valid values are `Infinity` and integers from
101
-
0 ({@link AnimationOptions.loopCount}). `-1` throws a `RangeError`, like other negative numbers, `NaN` and fractions. Numeric strings, `null` and booleans
102
-
throw a `TypeError`. The check applies to the constructor, to the setter `animation.loopCount = ...` (which keeps the
100
+
The finite counts are the same: `0` plays once, `2` plays three times. The valid values are `Infinity` and integers
101
+
from 0 ({@link AnimationOptions.loopCount}). `-1` throws a `RangeError`, like other negative numbers, `NaN` and
102
+
fractions. Numeric strings, `null` and booleans throw a `TypeError`. The check applies to the constructor, to the setter `animation.loopCount = ...` (which keeps the
103
103
old count when it throws), and to the encoders `Animation.gifEncoder()`, `webpEncoder()` and `apngEncoder()`.
104
104
105
105
The formats store a finite count in fixed-size fields: a GIF up to `65535`, a WebP up to `65534` and an APNG up to
@@ -178,9 +178,10 @@ scaled them. Now:
178
178
-`frame.rotate(angle)` keeps the frame's middle in place.
179
179
-`frame.cover(w, h)` scales the offsets and then moves them by the cropped amount.
180
180
181
-
`transform()`, `dropShadow()` and `outline()` moved the offsets in 3.x too, but only as far as they allowed (a frame at
182
-
`xOffset: 0` grew to the right instead). Now the offsets can become negative: the frame grows evenly, and the part
183
-
outside the animation's canvas isn't encoded.
181
+
`transform()`, `dropShadow()` and `outline()` moved the offsets in 3.x too, but only as far as they allowed: a frame at
182
+
`xOffset: 0` couldn't grow to the left, so a shadow or outline was cut off on that side and a transform grew to the
183
+
right instead. Now the frame grows the same way an image does and the offsets can become negative; the part outside the
184
+
animation's canvas isn't encoded.
184
185
185
186
To keep a frame's offsets as they are, call the method on its image: `frame.image.crop(x, y, w, h)`. See
186
187
[frames hold an image](#frames-hold-an-image) for the other frame changes.
@@ -264,8 +265,8 @@ for (let i = 0; i < image.bitmap.length; i += 4) image.bitmap[i] = 0.5 * 255;
264
265
```
265
266
266
267
`bitmap` is RGBA, four bytes per pixel. Writing it directly skips the gain map of an HDR image, so do not use it on
267
-
images that have one. `absolute` on `lightness()` and `saturation()` sets the value of every pixel and keeps its hue. Do it per pixel:
268
-
read the color with `Colors.toHSLA()`, set the lightness or saturation, and write the pixel back with
268
+
images that have one. `absolute` on `lightness()` and `saturation()` sets the value of every pixel and keeps its hue.
269
+
Do it per pixel: read the color with `Colors.toHSLA()`, set the lightness or saturation, and write the pixel back with
269
270
`Colors.fromHSLA()`.
270
271
271
272
### Animations and GIF
@@ -333,7 +334,7 @@ object under the names of their options. The options of each method are on its o
0 commit comments