New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canvas Driver #157

Closed
bcoop713 opened this Issue Jul 17, 2015 · 21 comments

Comments

Projects
None yet
8 participants
@bcoop713

bcoop713 commented Jul 17, 2015

I would like to create a canvas driver. I don't have too much experience with the canvas API, so I've been doing some research.

I found a few javascript libraries for canvas interaction and creation, but I'm leaning towards going dependency free.

http://fabricjs.com/
http://www.createjs.com/easeljs

Any thoughts?

@staltz

This comment has been minimized.

Show comment
Hide comment
@staltz

staltz Jul 17, 2015

Member

You would need something comparable to virtual DOM. The way of building the view should be fully declarative, but canvas APIs and wrappers are normally imperative/mutable APIs.

You could try looking into how React Canvas libraries do it. And I think I remember hearing something about virtual-dom related to Canvas.

Member

staltz commented Jul 17, 2015

You would need something comparable to virtual DOM. The way of building the view should be fully declarative, but canvas APIs and wrappers are normally imperative/mutable APIs.

You could try looking into how React Canvas libraries do it. And I think I remember hearing something about virtual-dom related to Canvas.

@staltz staltz added the drivers label Jul 17, 2015

@cgeorg

This comment has been minimized.

Show comment
Hide comment
@cgeorg

cgeorg Jul 17, 2015

react-canvas might be a good thing to look at for inspiration.

cgeorg commented Jul 17, 2015

react-canvas might be a good thing to look at for inspiration.

@HighOnDrive

This comment has been minimized.

Show comment
Hide comment
@HighOnDrive

HighOnDrive Jul 21, 2015

There are two approaches, immediate or retained. I would prefer the immediate because I have all my parameters abstracted into models on Firebase already, ready to be streamed to views. My app makes use of the Canvas API primitives together with Opentype.js. The Canvas element alone is powerful and has new functionality like the Path object, etc.

The retained approach involves creating a host of objects if you do not have proper models in place. I wrestled with the whole scene graph issue and learnt to abstract flexible models instead that can be streamed. However, the retained one React folks like is https://github.com/reactjs/react-art but I do not need it :)

HighOnDrive commented Jul 21, 2015

There are two approaches, immediate or retained. I would prefer the immediate because I have all my parameters abstracted into models on Firebase already, ready to be streamed to views. My app makes use of the Canvas API primitives together with Opentype.js. The Canvas element alone is powerful and has new functionality like the Path object, etc.

The retained approach involves creating a host of objects if you do not have proper models in place. I wrestled with the whole scene graph issue and learnt to abstract flexible models instead that can be streamed. However, the retained one React folks like is https://github.com/reactjs/react-art but I do not need it :)

@staltz

This comment has been minimized.

Show comment
Hide comment
@staltz

staltz Jul 22, 2015

Member

If I would build this (and I might if time allows), I'd first make an unopinionated library similar to virtual-dom, but targeting canvas. Only then would I make the driver to wrap that library.

Member

staltz commented Jul 22, 2015

If I would build this (and I might if time allows), I'd first make an unopinionated library similar to virtual-dom, but targeting canvas. Only then would I make the driver to wrap that library.

@axefrog

This comment has been minimized.

Show comment
Hide comment
@axefrog

axefrog Sep 2, 2015

Yeah I think you could easily create a hybrid retained/immediate mode driver where you don't represent high-level objects so much as sets of instructions that can be replayed. I think I am very likely to start work on this later today because the website I am developing for my current client has heavy canvas-drawing requirements.

axefrog commented Sep 2, 2015

Yeah I think you could easily create a hybrid retained/immediate mode driver where you don't represent high-level objects so much as sets of instructions that can be replayed. I think I am very likely to start work on this later today because the website I am developing for my current client has heavy canvas-drawing requirements.

@HighOnDrive

This comment has been minimized.

Show comment
Hide comment
@HighOnDrive

HighOnDrive Sep 3, 2015

Sounds interesting, might have some ideas here. Certainly have a use for a canvas.

HighOnDrive commented Sep 3, 2015

Sounds interesting, might have some ideas here. Certainly have a use for a canvas.

@HighOnDrive

This comment has been minimized.

Show comment
Hide comment
@HighOnDrive

HighOnDrive Sep 26, 2015

There is an implementation of a canvas driver that wraps the pixi.js library here: https://github.com/eschwartz/cycle-pong

HighOnDrive commented Sep 26, 2015

There is an implementation of a canvas driver that wraps the pixi.js library here: https://github.com/eschwartz/cycle-pong

@eschwartz

This comment has been minimized.

Show comment
Hide comment
@eschwartz

eschwartz Oct 3, 2015

Thanks, @HighOnDrive. Here's the (very simple) driver you were referring to

If I would build this (and I might if time allows), I'd first make an unopinionated library similar to virtual-dom, but targeting canvas.

Take a look at jsondiffpatch -- I think that will get you a good way torwards where you're going. If you can put together a structural representation of your view models, it should be pretty straightforward to map diffs in those view models to canvas operations (especially if you make use of a decent Canvas/Game library).

I started messing around with something like that for my pong game, but I decided my time was better spent wrapping my head around RxJS...

eschwartz commented Oct 3, 2015

Thanks, @HighOnDrive. Here's the (very simple) driver you were referring to

If I would build this (and I might if time allows), I'd first make an unopinionated library similar to virtual-dom, but targeting canvas.

Take a look at jsondiffpatch -- I think that will get you a good way torwards where you're going. If you can put together a structural representation of your view models, it should be pretty straightforward to map diffs in those view models to canvas operations (especially if you make use of a decent Canvas/Game library).

I started messing around with something like that for my pong game, but I decided my time was better spent wrapping my head around RxJS...

@staltz

This comment has been minimized.

Show comment
Hide comment
@staltz

staltz Oct 3, 2015

Member

Thanks for pointing to jsondiffpatch!

Member

staltz commented Oct 3, 2015

Thanks for pointing to jsondiffpatch!

@HighOnDrive

This comment has been minimized.

Show comment
Hide comment
@HighOnDrive

HighOnDrive Oct 3, 2015

@eschwartz jsondiffpatch looks great!

I have the view models but am not really needing a full blown graphic scenegraph library at this time. The view models serve this purpose for me so I just want to draw to the standard canvas element, which is just a image.

Would a driver be required when rendering to a standard canvas? The virtual-DOM would not diff the drawing but maybe if I track and set a dirty state on the canvas node it might?

HighOnDrive commented Oct 3, 2015

@eschwartz jsondiffpatch looks great!

I have the view models but am not really needing a full blown graphic scenegraph library at this time. The view models serve this purpose for me so I just want to draw to the standard canvas element, which is just a image.

Would a driver be required when rendering to a standard canvas? The virtual-DOM would not diff the drawing but maybe if I track and set a dirty state on the canvas node it might?

@HighOnDrive

This comment has been minimized.

Show comment
Hide comment
@HighOnDrive

HighOnDrive Oct 4, 2015

I’ve been able to think things through further and agree that I will need a canvas driver no matter if I use a retained or immediate approach to rendering. I generally need a bit more to go on than just adopting drivers as a Cycle pattern because it is the in thing to do, lol

Turns out it is a combo of how Cycle loops it’s driver processes, keeps main pure, interacts with the virtual-DOM and so on. I just wanted to know why whenever I do things in Cycle an extra driver step is often required. As long as it is purposeful then I’m good to go :-)

So the verdict is that a canvas driver is required for both immediate and retained rendering scenarios. In this case it would make sense to create a universal canvas driver for Cycle, that can interface with the standard HTML5 canvas element by default and then also any other retained/scenegraph related graphic API out there if desired?

Then a developer could have a base to work with and not have to figure out how to interface with graphics within Cycle over and over. They could then just customize a stock cycle-canvas-driver further, depending on their use case and any optional 2D/3D API they might choose.

HighOnDrive commented Oct 4, 2015

I’ve been able to think things through further and agree that I will need a canvas driver no matter if I use a retained or immediate approach to rendering. I generally need a bit more to go on than just adopting drivers as a Cycle pattern because it is the in thing to do, lol

Turns out it is a combo of how Cycle loops it’s driver processes, keeps main pure, interacts with the virtual-DOM and so on. I just wanted to know why whenever I do things in Cycle an extra driver step is often required. As long as it is purposeful then I’m good to go :-)

So the verdict is that a canvas driver is required for both immediate and retained rendering scenarios. In this case it would make sense to create a universal canvas driver for Cycle, that can interface with the standard HTML5 canvas element by default and then also any other retained/scenegraph related graphic API out there if desired?

Then a developer could have a base to work with and not have to figure out how to interface with graphics within Cycle over and over. They could then just customize a stock cycle-canvas-driver further, depending on their use case and any optional 2D/3D API they might choose.

@Frikki

This comment has been minimized.

Show comment
Hide comment
@Frikki

Frikki Oct 5, 2015

Member

@HighOnDrive What do you mean, "keeps main pure"? main(), because it takes in the world as sources, produces side effects, and is, thus, not pure at all, i.e., there is no guarantee that main() produces the same result every time.

Member

Frikki commented Oct 5, 2015

@HighOnDrive What do you mean, "keeps main pure"? main(), because it takes in the world as sources, produces side effects, and is, thus, not pure at all, i.e., there is no guarantee that main() produces the same result every time.

@staltz

This comment has been minimized.

Show comment
Hide comment
@staltz

staltz Oct 5, 2015

Member

@Frikki if you provide the same inputs, it should help put the same results.

Member

staltz commented Oct 5, 2015

@Frikki if you provide the same inputs, it should help put the same results.

@Frikki

This comment has been minimized.

Show comment
Hide comment
@Frikki

Frikki Oct 5, 2015

Member

@staltz Surely, but there is no guarantee; thus, not pure.

Member

Frikki commented Oct 5, 2015

@staltz Surely, but there is no guarantee; thus, not pure.

@staltz

This comment has been minimized.

Show comment
Hide comment
@staltz

staltz Oct 5, 2015

Member

Does anything in JavaScript have a guarantee?

Member

staltz commented Oct 5, 2015

Does anything in JavaScript have a guarantee?

@Frikki

This comment has been minimized.

Show comment
Hide comment
@Frikki

Frikki Oct 5, 2015

Member

@staltz Good question. In a perfect environment, yes. But since JavaScript relies on other software, and ultimately, on hardware, then no. What I was referring to was the idea of pure functions.

Member

Frikki commented Oct 5, 2015

@staltz Good question. In a perfect environment, yes. But since JavaScript relies on other software, and ultimately, on hardware, then no. What I was referring to was the idea of pure functions.

@staltz

This comment has been minimized.

Show comment
Hide comment
@staltz

staltz Oct 5, 2015

Member

Then neither is x => x * 2 a pure function?

Member

staltz commented Oct 5, 2015

Then neither is x => x * 2 a pure function?

@Frikki

This comment has been minimized.

Show comment
Hide comment
@Frikki

Frikki Oct 5, 2015

Member

Yes, in the sense of pure functions, it is, because the function always evaluates the same result given the same argument.

Member

Frikki commented Oct 5, 2015

Yes, in the sense of pure functions, it is, because the function always evaluates the same result given the same argument.

@staltz

This comment has been minimized.

Show comment
Hide comment
@staltz

staltz Oct 5, 2015

Member

And why can't a main() ever do the same?

Member

staltz commented Oct 5, 2015

And why can't a main() ever do the same?

@Frikki

This comment has been minimized.

Show comment
Hide comment
@Frikki

Frikki Oct 5, 2015

Member

It can, if you don’t feed it the world, i.e., drivers. The drivers can cause all kinds of unpredictable side effects; thus, the main result may not evaluate the same on the same argument(s) given.

Member

Frikki commented Oct 5, 2015

It can, if you don’t feed it the world, i.e., drivers. The drivers can cause all kinds of unpredictable side effects; thus, the main result may not evaluate the same on the same argument(s) given.

@HighOnDrive

This comment has been minimized.

Show comment
Hide comment
@HighOnDrive

HighOnDrive Oct 5, 2015

Hey dudes, just seeing all this talk of purity after watching RxJS vids all day and recovering with a late night deep trance jam out on the guitar, whats up! LOL

By keeping main() pure I only meant that it has it's specific task and then run() handles the actual looping, which might not be looping in a sense at all, because observables don't do squat unless they are subscribed to and there are events to react to, so they are not just orbiting. At least that is my current understanding.

I'm just thinking further on that universal cycle-canvas driver now 😄

HighOnDrive commented Oct 5, 2015

Hey dudes, just seeing all this talk of purity after watching RxJS vids all day and recovering with a late night deep trance jam out on the guitar, whats up! LOL

By keeping main() pure I only meant that it has it's specific task and then run() handles the actual looping, which might not be looping in a sense at all, because observables don't do squat unless they are subscribed to and there are events to react to, so they are not just orbiting. At least that is my current understanding.

I'm just thinking further on that universal cycle-canvas driver now 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment