Reputation: 3160
I am starting a painting application with RaphaelJS. What's the best way of keeping track of all the elements that have been drawn on a paper (with a mouse)?
The first way I thought of was to append all drawn elements into an array, but this might not be as efficient if there was a 'out of the box' solution that RaphaelJS had.
I checked the API but didn't find anything like what I was looking for... am I out of luck?
Upvotes: 4
Views: 2564
Reputation: 3556
From my experience the approach which works the best is to create specialized object (lets call it DataManager) which will hold the model of each drawing in an array (not the actual Rapahel object)
here is the manager stub:
function DataManager (){
var self = this;
self.DrawingsArray = [];
}
and here is the model stub:
function DrawingModel (name,raphael){
var self = this;
self.ID = someObject.generateSomeID();
self.Name = name;
self.Rapahel = raphael;
}
With this in mind we can create model, after adding the drawing to workspace, add reference of the raphael object to it, give it some name or id, and then add it to the DataManager's DrawingArray. When it comes to id, you can also add it as new property to Raphael object so it is easy to access the model in the event handlers, and so on.
The main advantages are:
Upvotes: 1
Reputation: 1240
Well I've worked on Raphael.js a bit and the most efficient way I found was separating the drawing logic from the data structure. I can't fully write the code here ( too long =( ) but can give you some idea using code pieces which might be of some help.
// Create Data Structure to keep seperate track of Elements and its attribute (assuming a Drawing Panel and only Line Type here)
function DrawingPanelStructure(Type, Attributes){
this.Type = Type;
this.Attributes = Attributes;
}
function PanelLineAttribute(Color,CurveDataX, CurveDataY)
{
this.Color = Color;
this.CurveDataX = CurveDataX;
this.CurveDataY = CurveDataY;
}
// Make Global Variables
_drawingPanelStructure = new Object();
var ElementDrawnNumber = 0; // Keeping Track of Number of elements drawn
// Then when Drawing the element, populate the Data Structure inside a function as
_drawingPanelStructure[ElementDrawnNumber] = new DrawingPanelStructure("Line",new PanelLineAttribute("Red",[1,5,6,7,5], [5,1,8,6,8]));
ElementDrawnNumber = ElementDrawnNumber + 1;
// Then you can call a function to draw the Element at specific index as
var XData = [];
var YData =[];
XData.push(_drawingPanelStructure[index].Attributes.CurveDataX);
YData.push(_drawingPanelStructure[index].Attributes.CurveDataY);
var LineChart = Paper.linechart(0, 0, DrawinPanelWidth, DrawingPanelHeight, 0),
XData, YData, {}
);
// Since in this example there is only 1 line drawn on LineChart I'll use LineChart.lines[0]
LineChart.lines[0].attr({ "stroke": _drawingPanelStructure[index].Attributes.Color});
It's also helpful in a way that while drawing an element you can give it a unique id of
ElementDrawn.id = "Element_" + ElementDrawnNumber;
That way you would be certain that Element_3 means element at 3rd index of _drawingPanelStructure.
So separate the Drawing Logic from the Data Structure, i.e. populate the Data Structure, then pass the Data Structure to some function which will then do all the drawing on the panel.
Upvotes: 1
Reputation: 21708
I guess it depends what you mean when you say "keeping track."
You're able to loop all elements on a given paper using Paper.forEach
and you're able to pull out specific elements using Paper.getById
.
If you're drawing elements with Paper.path
, set an ID that you can store in a separate data structure using the method described in this SO thread.
Upvotes: 3