Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassing CanvasRenderingContext2D

Is it possible to create a subclass of the CanvasRenderingContext2D and assign an instance of it as the context for a Canvas element?

I'd like to be able do something like:

class ContextSub extends CanvasRenderingContext2D
    shape : (pointList, solid = true, closed=true) =>
        @beginPath()
        @lineTo p[0], p[1] for p in pointList
        if closed
             @closePath()
             if solid then @fill() else @stroke()
        else
            if solid then @fill() else @stroke()
            @closePath()

And then:

canvas = document.getElementById "canvas"
canvas.setContext new ContextSub()

Currently, I'm approaching the problem like this:

class MyContext 
    constructor : (ctx) ->
        for key of ctx
            @[key] = ctx[key]

canvas = document.getElementById "canvas"
myContext = new MyContext(canvas.getContext('2d'))

This gets me pretty close, but it seems like a hack. Are there any major unforeseen drawbacks to this approach?

Update

In response to @kangax: I'm working on a graphics framework and I'd like to keep the syntax as terse as possible. I want to avoid using @ctx.arc(), @ctx.lineStyle() and instead just subclass the context and then be able to use @arc(), @shape(), ect.

Update 2

I've done a bit more digging and this does not seem possible. I noticed that the context object has a property called canvas, so I attempted to extend context and then set that property to a canvas defined in the html. That seemed to work, in that no errors were thrown, but calling any methods of the super class resulted in an Illegal Invocation error. Similarly, using the hack approach above also resulted in the same error. Apparently, this is not an intended use case for the CanvasRenderingContext2D!

like image 240
JeremyFromEarth Avatar asked Aug 04 '26 03:08

JeremyFromEarth


1 Answers

Do not try to subclass or modify prototypes of native objects, as you most likely end up conflicts with web security.

Instead, if you want to build your own framework which handles CanvasRenderingContext2D transparently, use something like proxy objects:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

(Warning: ECMAScript6 feature, but can be emulated with hand-written JavaScript)

like image 183
Mikko Ohtamaa Avatar answered Aug 06 '26 18:08

Mikko Ohtamaa



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!