I am just getting started with Backbone.js, but it looks really interesting...
Right now, I am redoing a previous project that draws various objects (2-3 different model types) into a single HTML5 canvas.
Each object is clickable. There is a event handler for the canvas that gets the location of the click (local to the canvas object) and then searches the objects for one that could produce a hit.
I开发者_StackOverflow中文版s there a particular way or best practice that I should use when doing this for a click event on a Backbone.js view?
Thanks!
Update: found fabric.js which seems to handle the idea of objects within a canvas element, but doesn't provide the MVC style framework as backbone.js.
Also, I took a look at knockout.js. It seems even more tied to HTML elements (not canvas) than backbone.js.
I came across this question because I'm working on a Backbone-based framework for working with canvas, so I grappled with this myself. The answer I eventually came to was: Forget about using Backbone.View with canvas. If it can't be represented by a DOM element, then it doesn't make sense to use Backbone.View for it; its properties just don't map to canvas "elements."
You could use Backbone.View to represent a single canvas
DOM element just fine, mind you, but that's not the scenario you're describing. What you need is a custom view class that can represent your in-canvas objects and handle their events.
I am also working on a card game using Backbone.js
on Canvas and came across this question. What I am currently doing is have a CardView
that has el
as a canvas tag so that a canvas will be created on initialization. All the drawing of the card is done on this view's render
method. However, this canvas will not be added to the DOM
.
I then have a Hand
, which is a Backbone.Collection
to hold a collection of cards. This collection has a Backbone.View
attached to the game canvas (the only and big one in the DOM
). This view also holds an array of Backbone.View
's. Then I have:
render: function() {
var that = this;
this.ctx.save();
_(this._views).each(function(view) {
that.ctx.drawImage(view.render().el, 0, 0);
that.ctx.translate(view.el.width, 0);
});
this.ctx.restore();
},
Basically, I draw each view's canvas into the game canvas using drawImage
of the context.
I addEventListener
to HandView
's canvas (which is its el
) to handle click. In this handler, I check the mouse positions against which CardView
, then manipulate that view.
Mind you, this is just something I'm experimenting since I'm new to Backbone.js
too. This maybe the worst way to do, but I just hope that you can see one of the ways to do it.
I do wish that we could check mouse against a canvas that does not exists in the DOM. If it's possible, we could just addEventListener
to CardView
's canvas and let it translate and re-render. No need for HandView
's canvas to loop through its views.
I'm late to this party, but IMO neither views nor models/collections are not the place to house this kind of logic.
If you're using fabric or some other library (I have an application using raphael.js), you should be creating a bespoke module that handles the drawing/manipulation and responds to canvas events using local events handling (ie. https://github.com/kangax/fabric.js/wiki/Working-with-events).
If you need to communicate those events out you should expose them programatically and use backbone events to publish them to other backbone components.
You shouldn't tightly couple your models and views in the ways suggested above.
Just getting started with backbone.js myself, but I would probably make a backbone view (say canvasView) that renders and listens to the events on the canvas. The click event can be dispatched to a method on the view objects and in that method you do your object-matching algorithm and other logic.
精彩评论