skia-canvas
Advanced tools
Changelog
🥚 ⟩ [v2.0.2] ⟩ Jan 28, 2025
fontHinting
attribute (off by default to better match font weights in browser rendering). Setting it to true
may result in crisper edges but adds some weight to the font.letterSpacing
no longer indents text at beginning of lineletterSpacing
now properly handles negative valuesmeasureText()
][measureText()]
ctx.font
string (NB: this is likely to cause vertical shifts for non-alphabetic
baselines)middle
& hanging
to better match browsersactualBoundingBox*
& lines[].x/y/width/height
rectangles returned by measureText() are now just the glyph-occupied area, not the whole line-height of the textblockactualBoundingBoxLeft
(positive values now mean left of the origin)lines[].baseline
now corresponds to the selected ctx.textBaseline
, previously it was always the alphabetic baselineChangelog
📦 ⟩ [v2.0.1] ⟩ Dec 8, 2024
Changelog
📦 ⟩ [v2.0.0] ⟩ Dec 2, 2024
drawImage()
][mdn_drawImage] (thanks to @mpaperno #180). Note that Images loaded from SVG files that don't have a width
and height
set on their root <svg>
element have some quirks as of this release:
height
will report being 150
and the width
will be set to accurately capture the image's aspect ratiodrawImage()
without size arguments, the SVG will be scaled to a size that fits within the Canvas's current bounds (using an approach akin to CSS's object-fit: contain
).drawImage()
, the ‘crop’ arguments (sx
, sy
, sWidth
, & sHeight
) will correspond to this scaled-to-fit size, not the Image's reported width
& height
.toBuffer()
and saveAs()
methods now support "raw"
as a format name and/or file extension, causing them to return non-encoded pixel data (by default in an "rgba"
layout like a standard [ImageData][ImageData] buffer)colorType
][colorType] argument to specify alternative pixel data layouts (e.g., "rgb"
or "bgra"
)new ImageData()
constructor, the optional settings arg now allows you to select the colorType
for the buffer's pixels.outlineText()
][outline_text] method now takes an optional width
argument and supports all the context's typographic settings (e.g., .font
, .fontVariant
, .textWrap
, .textTracking
, etc.).fontStretch
][fontStretch] property. Note that stretch values included in the .font
string will overwrite the current .fontStretch
setting (or will reset it to normal
if omitted).serif
, sans-serif
, monospace
, and system-ui
families are currently supported..textDecoration
property..letterSpacing
][letterSpacing] and [.wordSpacing
][wordSpacing] properties.resizable
][resizable] property which can be set to false
to prevent the window from being manually resized or maximized (contributed by @nornagon #124).input
][input] event now reports the composed character, not the individual keystrokes.engine
property which describes whether the CPU or GPU is being used, which graphics device was selected, and what (if any) error prevented it from being initialized..transform
and .setTransform
methods on Context, Path2D, and CanvasPattern objects can now take their arguments in additional formats. They can now be passed a [DOMMatrix][DOMMatrix] object or a string with a list of transformation operations compatible with the [CSS transform
][css_transform] property. The DOMMatrix constructor also supports these strings as well as plain, matrix-like objects with numeric attributes named a
, b
, c
, d
, e
, & f
(contributed by @mpaperno #178).SKIA_CANVAS_THREADS
][multithreading] environment variablesrc
property has been set to a local path. As a result, it's now necessary to await img.decode()
or set up an .on("load", …)
handler before drawing it—even when the src
is non-remote.keyup
/keydown
and input
event listeners now has fields and values consistent with browser behavior. In particular, code
is now a name (e.g., ShiftLeft
or KeyS
) rather than a numeric scancode, key
is a straightforward label for the key (e.g., Shift
or s
) and the new [location
][key_location] field provides a numeric description of which variant of a key was pressed..async
property has been removed. See the v0.9.28 release notes for details..textTracking
property has been removed in favor of the new [.letterSpacing
][letterSpacing] propertyvulkano
crate and makes better selections among devices present (previously it was just using the first result, which is not always optimal).this
to point to the new image (contributed by @mpaperno & @ForkKILLET).fullscreen
set to true
now takes effect immediately (previously it was failing silently).on("draw")
handlers no longer become unresponsive on macOS 14+ after being fully occluded by other windowsdrawCanvas()
method now clips to the specified crop size (contributed by @mpaperno #179)isPointInPath
][isPointInPath()] and [isPointInStroke
][isPointInStroke()] now works correctly when called with a Path2D object as the first argumentroundRect
method (contributed by @sandy85625 & @santilema)winit
and replaced the end-of-life’d skulpin-based Vulkan renderer with a new implementation using Vulkano for window-drawing on Windows and Linux.
It’s a fairly direct adaptation of Vulkano [sample code][vulkano_demo] for device setup with skia-specific rendering routines inspired by @pragmatrix’s renderer for [emergent][pragmatrix_emergent]. All of which is to say, if you understand this better than I do I'd love some suggestions for improving the rendering setup.
.gpu
][canvas_gpu] property to false
immediately after creation will prevent any GPU-related resource acquisition from occurring (though rendering speed will be predictably slower).msaa
][msaa] export argument. If omitted, defaults to 4x MSAA.import {Image} from "skia-canvas"
) when used as an ES Module.Changelog
📦 ⟩ [v1.0.2] ⟩ Aug 21, 2024
Changelog
📦 ⟩ [v1.0.1] ⟩ Oct 15, 2022
drawCanvas()
routine now works even when the destination canvas is later saved as an SVG (previously, the source canvas would be missing from the output). Caveat: this only works if the destination canvas is using the default source-over
blend mode, has its globalAlpha
set to 1, and is not using shadows or the effect
property. If any of those defaults have been changed, the drawn canvas will not appear in the saved SVG. Bitmap and PDF exports do not have this restriction.fullscreen
event to the Window
class to flag changes into and out of full-screen mode.Changelog
📦 ⟩ [v1.0.0] ⟩ Aug 5, 2022
.gpu
][canvas_gpu] property. If the platform supports hardware-accelerated rendering (using Metal on macOS and Vulkan on Linux & Windows), the property will be true
by default and can be set to false
to use the software renderer.reset()
][chrome_reset] context method which erases the canvas, resets the transformation state, and clears the current pathroundRect()
][chrome_rrect] method on contexts and Path2D objects which adds a rounded rectangle using 1–4 corner radii (provided as a single value or an array of numbers and/or DOMPoint objects)FontLibrary.reset()
method didn't actually remove previously installed fonts that had already been drawn with (and thus cached). It now clears those caches, which also means previously used fonts can now be replaced by calling .use()
again with the same family name..drawCanvas()
][drawCanvas] routine now applies filter effects and shadows consistent with the current resolution and transformation state..filter
][filter] property's "blur(…)"
and "drop-shadow(…)"
effects now match browser behavior much more closely and scale appropriately with the density
export option.clearRect()
with dimensions that fully enclose the canvas will now discard all the vector objects that have been drawn so far (rather than simply covering them up).Changelog
📦 ⟩ [v0.9.30] ⟩ Jun 7, 2022
reset()
][FontLibrary.reset] method to FontLibrary which uninstalls any fonts that had been dynamically installed via FontLibrary.use()
use()
][FontLibrary.use] method now checks for previously installed fonts with the same family name (or alias) and will replace them with the newly added fontclip
with an empty path (or one that does not intersect the current clipping mask) will now prevent drawing altogethertranslate
, rotate
, etc.) and line-drawing methods (moveTo
, lineTo
, ellipse
, etc.) are now silently ignored if called with NaN
, Infinity
, or non-Number values in the arguments rather than throwing an error
conicCurveTo()
][conicCurveTo] now correctly reflects the canvas's transform stateloadImage()
][loadImage()] now returns a Promise that correctly resolves to an Image object<rect/>
as their first elementnode:alpine
docker images and the version used when building the precompiled binariesChangelog
📦 ⟩ [v0.9.29] ⟩ Feb 7, 2022
matte
][matte] argument.drawImage()
][mdn_drawImage] function is passed a Canvas object as its image source it will now rasterize the canvas before drawing. The prior behavior (in which it is drawn as a vector graphic) can now be accessed through the new [drawCanvas()
][drawCanvas] method which supports the same numerical arguments as drawImage
but requires that its first argument be a Canvas.clearRect()
][mdn_clearRect] are now properly antialiasedclip()
][mdn_clip] method now interprets the current translate/scale/rotate state correctly when combining clipping masksChangelog
📦 ⟩ [v0.9.28] ⟩ Jan 12, 2022
.async
][async_depr] property has been deprecated and will be removed in a future release.
saveAs
, toBuffer
, and toDataURL
methods will now be async-only (likewise the [shorthand properties][shorthands]).saveAsSync
, toBufferSync
, and toDataURLSync
) if you want to block execution while exporting images.source-in
, source-out
, destination-atop
, and copy
composite operations now work correctly for paths rather than rendering shapes without color (contributed by @meihuanyu)rect()
now issues an initial moveTo
rather than extending the path, then leaves the ‘current’ point in its upper left cornerellipse()
extends the current path rather than implicitly closing it (contributed by @meihuanyu)arc()
also extends the current path rather than closing it