Git Product home page Git Product logo

canvas2d's Introduction

Update Canvas 2D API

This repo contains new, current and old proposals for the Canvas 2D API, following a set of rationales.

Explainer video

In active development

  • Layers. Support layers in canvas, that will be drawn in one, allowing effects only possible with auxiliary canvases.

  • Display list object. Format and data structure for retained mode drawings, making Canvas apps faster, more accessible and indexable.

  • Mesh2D. Draw a large number of texture-mapped triangles efficiently.

  • WebGPU Integration. Switch contexts between Canvas2D and WebGPU.

  • WebGPU Shaders. Allow for WebGPU shaders to be used as Canvas2D layers filters.

Launched

Those proposals have already been incorporated on the WhatWG spec and may be in different stages of implementation on browsers.

Parked / Future ideas

  • Perspective transforms. Allow for perspective transforms Canvas 2D rendering. Support 4x4 transform matrices.

  • Recorded pictures. Create a record object that receives all the commands from a Canvas2D and can be replayed multiple times.

  • Conic curves. Draw primitive.

  • Batch text rendering.

  • Text blob.

  • Path2D Inspection. Allow inspection of Path2D objects, that are currently opaque.

  • Element as a source for drawImage.

Dropped ideas

  • Color input. support for new color input on Canvas.

  • Batch drawImage. Support for multiple images being drawn within a single API call.

  • Modern filters. Support composited filters, create a filter object that can be updated, and support more SVG-like filters. Superseded by layers.

canvas2d's People

Contributors

andresrperez12 avatar fmalita avatar fserb avatar graveljp avatar johnstiles-google avatar jpmedley avatar juanmihd avatar junov avatar macrabil avatar mysterydate avatar nt1m avatar vsekhar avatar wcandillon avatar yiyix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

canvas2d's Issues

Use GLES fragment shader as filters

Use SVG filters is not flexible enough, i pref using custom GLES fragment shader for filter, which provides most flexibles while not need to switch to WebGL/WebGPU.

The background: I'm using canvas2d to build a web-based UI editor framework, which is not a build-from-scratch, but mitigation from an old legacy C++ codebase. For some reason, compiling to WebAssembly + WebGL is too heavy, & i prefer using canvas2d first...

Serialization of CanvasFilters

Since the primary use case seems to be to use the CanvasFilters with OffscreenCanvas it might be a good idea to offer a mean to postMessage these, so authors can "share" these filters across different realms, just like we can transfer ImageBitmap objects today.

Make CSS filters work with `CanvasFilter`

Right now, there are two ways to provide filters: one for "simple" CSS filters (example: offscreenCanvas.filter = 'brightness(1)') and one for more complex SVG filters (example: offscreenCanvas.filter = new CanvasFilter([…])). Ideally, simple CSS filters could be modeled as {filter: 'brightness', amount: 1} as well, so they can all be passed in one big filter array.

roundRect might be better as an extension to CanvasPath mixin

The current proposal makes CanvasRoundRect about the same interface as CanvasRect, but I don't see the rationale for this choice.

As a web author I would prefer to have a roundRect() extension to the CanvasPath mixin, allowing to store it in Path2D objects maybe along with other shapes, or use it with methods like clip, isPointIn..., scrollToPath etc. and also allowing to fill or stroke many such shapes in a single call (with non negligible performance improvements).

I don't really see the point of having it outside of the "current path" and having an other method to clear pixels doesn't seem really useful either (we can already use compositing + fill() to clear from any path).

Text Modifiers — Variable Fonts

I think it would be important to port over CSS support of variable fonts, as they are an important new feature gaining a lot of traction right now.

For example:

font-variation-settings: 'wght' 700;

So should support the font-variation-settings property as attribute DOMString fontVariationSettings.

At the moment, the current workaround is to apply it crudely on the canvas element to affect all text drawn, e.g. https://codepen.io/JuanFuentes/details/bGpGpzg

Web platform brianstorm meeting in California

@Kaiido I tweeted at you earlier but fserb also had the brilliant idea to try to contact you here. The canvas team at Google will be traveling to the bay area for a meeting with Apple folks on March 8th. We will be talking about new features for graphics on the web platform. You are cordially invited to attend! Virtually or in person. We would love to hear your ideas!
My email is [email protected] if you want to talk with me directly.

Proposals

Here are some proposals with features I felt missing in the past:

  • ctx.shapeSmoothEnabled = false; Allow to disable Antialiasing for primitives:
  • ctx.shape( vertices_array ); Specify shape by passing a list of vertices instead of one by one.
  • ctx.fillTriangle(v1,v2,v3, c1,c2,c3 ); Draw a triangle specifying 3 vertex and 3 colors, or even 3 uvs. Ideal for continuous surfaces.
  • ctx.colorizeImages = true; Colorizing images by fillColor (currently I have to do hacks with globalOperation
  • ctx.drawImage( webgl_texture_handler, x, y ); Being able to use a WebGLTexture Handler with drawImage (it already supports using a WebGL Canvas and most backends render canvas2D using OpenGL).

Nice to have

  • ctx.transformCoordinate(x,y); a function that given a 2D coordinate it transforms it using current transform

Integer only coordinate space mode.

I’m migrating a Windows GDI application to HTML using Canvas and I stumbled across the fact that canvas uses a fractional coordinate space which requires “moving” to the mid of a pixel in order to draw vertical and horizontal lines of width 1.

https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors

Unfortunately, I couldn’t find any article explaining the motivation behind the use of fractional units in the canvas but after reviewing numerous canvas code examples on the web I noticed that’s its pretty common to see people adding 0.5 when drawing lines, so while I assume there are probably good reasons and uses cases for using fractional pixels (I’m far from an expert on this), perhaps it is equally applicable to have an integer only pixel mode (like in GDI) for simple cases where it is possible to establish a one-to-one mapping between whole number points on the Cartesian system and 1x1 squares on the canvas grid.

Arbitrary gradient transforms

It'd be nice if CanvasGradient could have an arbitrary transform. For example, this would allow for elliptical radial gradients or skewed gradients.

This is possible with the current canvas API in some situations by 1) tracing the path with lineTo etc., 2) calling context.transform(..), and 3) calling context.fill(), which transforms the gradient while not transforming the path. But this feels both roundabout and doesn't play nicely if you want to use Path2D.

Ideally there would be a CanvasGradient.transform method that accepts a DomMatrix similar to CanvasRenderingContext2d.transform. This would be analogous to SVG gradientTransform.

Another possibility would be to allow context.createPattern to accept a CanvasGradient, as CanvasPattern.setTransform already exists.

Make canvas2d faster than Webgl

currrent Path2D just contain the point infomation about shap. when call draw(path2D), the borwser must generate new geometry data according lineWidth and other attribuite in context.
if the path2D includs all the infomation about generate geometry, the geometry data can cache, give the chance to browser optimization the drawcall.

CanvasFilters - Even <feImage>?

The <feImage> SVG filter primitive allows to load external resources and graphic elements accessible in the document.

This filter seems to create a few issues with how the canvas API works.

Fetching resources should be an async operation, this means that by the time we pass the resulting CanvasFilter to the canvas, the resource may still not be ready to be rendered. SVG doesn't have this problem, it can just rerender when the resource is loaded. Canvas can't do that.

Currently the best I can think of would be to make it take ImageBitmaps instead of URIs.

`beginLayer` vs `beginFilter`

I'm curious about why the naming uses "layers" as a concept with beginLayer/endLayer, instead of calling them simply beginFilter/endFilter if their sole purpose is to be able to apply filters to groups of commands. Because I excepted "layers" to be something else, more analogous to layers in a graphics editor that can be shown/hidden/reordered/etc.

add clipRect() function

Clipping to integer pixel axis aligned rects has a very different implementation than arbitrary geometry. It would be nice to be able to expose ctx.clipRect() instead ofctx.rect(); ctx.clip();

Skia and CoreGraphics both expose a clipRect() type function so there's definitely precedence for this kind of thing.

Gradient spread methods

It would be useful if CanvasGradient allowed specifying a spread method, which determines how the gradient is rendered outside the [0.0, 1.0] stop range:

  • Pad (current default, gradient stop is clamped to [0.0, 1.0])
  • Repeat (gradient repeats in the same order past the edges, i.e. colors at [1.0, 2.0] would be the same as [0.0, 1.0]
  • Reflect (gradient colors repeat in reverse past the edges, i.e. colors at [1.0, 2.0] would be the reverse of [0.0, 1.0]

This would give canvas parity with spreadMethod in SVG and SpreadMethod going back to Flash.

[Mesh2D] Triangle order

In the case of overlapping triangles what order are they drawn in for blending purposes? Can this be controlled?

Reset / Clear

I use .save() and .restore() as the first and last calls during drawing to reset my canvas state. Since I call save at the beginning to store the initial state basically. Outside the two calls I can cleanly clearRect just before first .save() when drawing again.

Would .reset() be like resetting to initial state in the same way as these state related methods? Wouldn't it surprise developers if it does extra things like clearing the canvas?

Perhaps separately a simple .clear() that is like .clearRect() but implies the whole canvas instead of having to define the coordinates awkwardly?

There is already a separation between what is canvas state and clearing canvas content and I think it would be a mistake to mix the two.

So my suggestion is:

  • .reset() — restores the state of the canvas to the initial state, clearing the entire state stack
  • .clear() — erases the pixels in the entire canvas area by setting them to transparent black

roundRect requiring an array

I can see that the new roundRect requires an array to specify the radius, even when the radius is constant among all corners.

Knowing that most of us are fighting the garbage collector constantly, I do not see it smart to force to pass an array with every call of roundRect.

More when other functions in canvas take advantage of the variable number of arguments, like drawImage.

I suggest to allow the radius parameter to be a number.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.