Moving objects on a canvas - javascript

I’m trying to build a game in canvas just to improve my skills set. The idea is there’s two objects on the screen that are player-controlled. I initialise the game with players, and then start a game loop that listens for player input.
At the moment, I can draw the players on the canvas (simply rectangles at this stage). However, I’m having trouble moving these objects on each “tick” of the game loop. At the moment, the rectangle is just drawn on top of the rectangle in the previous frame; I want to clear the canvas and re-draw the “players” in each tick.
How would I go about this? And is it the best way, or is there a better approach?
I’d post a code sample, but my JavaScript file is quite verbose and I’m hoping the description above is sufficient.

If the appearance of the players doesn't change from frame to frame, then I would use three separate canvas elements: one for the background and one for each player. Then you don't have to redraw anything, just change the CSS left and top values for each player canvas.
If the appearance of the players does change, then you'll need to redraw them. But you still might want to use a separate canvas for each one. That way you don't have to redraw the background. You can just draw and position each player.
Of course if the background changes or moves, you'll need to redraw it anyway. In that case you might just use a single canvas, or experiment with the separate canvases. With regard to the specific question of how to clear the background (or any canvas) before redrawing, here are a couple of ways to clear a canvas.
Either way, use requestAnimationFrame() in browsers that support it, instead of setTimeout() or setInterval(). If you search for requestAnimationFrame polyfill you will find many examples of how to do this and still support old browsers. Here's a good requestAnimationFrame polyfill.

Here is a good tutorial with a basic game loop. It renders a background, monsters and a player.
http://www.lostdecadegames.com/how-to-make-a-simple-html5-canvas-game/
// The main game loop
var main = function () {
var now = Date.now();
var delta = now - then;
update(delta / 1000);
render();
then = now;
};
You update your object positions in update and then call render.

I'm sorry, but having a separate canvas for each element in the scene, as another user sugested, is a terrible idea. And that won't improve your skills set in anyway.
Yes, you have to redraw everything on a single canvas, even the objects that don't transform from one frame to another. Clearing the canvas is simple, use the context.clearRect(0, 0, canvas.width, canvas.height) or do a fillRect to paint the background with some color, or draw an image on the entire canvas to have a static background, anything that covers the whole canvas will do.
So, you update the objects, clear the canvas, then, redraw everything. Since you just have 2 rects and the only thing that changes is their position this will be really easy to implement.
When you start making more complex things you might want to go for a more object-oriented aproach, by that I mean each object in your scene needs to "know how to draw themselves", like:
var player1 = new PlayerRect(position);
player1.draw(context);
This way you'd update it's position in the loop doing something like this:
player.position.x += 10;
In case you end up with hundreds of objects, all you have to do is a list where you could add/remove these objects and a loop calling their draw method.
I mean, that's the way I do it.

Related

Is it possible to make a viewport that follows the player using vanilla javascript?

I'm wondering how to make a viewport that follows the player such as in sidescrolling games. I have a semi-working version, but it requires me to move everything except the player.
ctx.translate(canvX,canvY);
drawBlocks();
ctx.restore()
This works for now, but I will have to draw enemies and other objects, and I don't want to constantly have to redo the process. I'm looking for a simple solution that basically involves a camera that follows the player. Is this possible?
Use something like three.js for games. Because you have to draw as many frames per second, and canvas just isn't great for that (if you don't believe me now, wait until you have to draw more things on the screen).
However, for your current code, one thing I notice is you're missing a save.
If that's not the problem, which I dont think it is, based on your question, you don't want to re-draw everything, only the background? You could actually use multiple layers, so that each enemy is an HTML element, and you only redraw the enemy when their animation frame changes. Then you just move their element ( a little cheaper than re-drawing in terms of performance ).
THREE.JS is what you should learn.. it will really help you out.

KineticJS clearRect equivalent

I am now entering Kinetic and it has made it far easier for me to draw on canvas. However, building a game app, I need to clear the rectangle on every animation request. They're controlled by an fps cap script, but still, there are about 50 updates per second.
Kinetic's .removeChildren() method not only clears the canvas, it deletes the canvas node from the DOM. Doing so not only makes DOM queries inconsistent by intervals of .02 second, but also drops my FPS rate by about 60% in comparison to stock HTML5 canvas handling on every machine I ran the game on.
Is there a KineticJS method for clearing the canvas in a manner such as clearRect()'s?
Edit:
I have also made sure it's not a problem on any other part of the program. Call stack doesn't overflow, the FPS drop is just due to DOM changing twice every .02 second.
Edit 2:
I have tried the following:
Ignore the layer before and create a blank rectangle to fill up the visible part of the canvas. It dropped my frame rate to about 14 FPS;
Use the .clear() method. It solved the DOM consistency problem but the frame rate got even lower than before.
It seems the only solution would be calling the default HTML5 clearRect() method, but that would mean creating the canvas element by hand (and possibly making Kinetic useless as a library for my app).
Edit 3:
As for the app, I've started using standard HTML5 canvas since I have a deadline. I'd still like to see a Kinetic solution though - it might be helpful in the future. It surprises me to see such a simple thing is so hard, if not impossible, in a popular library like KineticJS.
You can use layer.clear with a bounding area to clear just the "dirty" part of your layer.
// tell layer not to auto-clear on layer.draw
layer.setClearBeforeDraw(false);
// clear the "dirty" portion of the canvas
layer.clear(100, 100, 150, 150);
// adjust some animation values and
// just draw the element that has changed
myRect.draw();
You should try to create new Layer for example:
var newLayer = new Kinetic.Layer();
Or call this function:
Canvas.clear();
Kinetic makes it very easy to draw using layers, groups and shapes.
If your view is properly make of these items you can easily remove them and they will be removed from the stage.
Perhaps you need to rewrite you code to make it work better in kinetic.
if you think your code is properly written you can try (as a workaround) to create kinetic rectangle and fill it with whatever you want to simulate a clear.

HTML5 Canvas Performance and Optimization Tips, Tricks and Coding Best Practices [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Closed 9 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
DO YOU KNOW SOME MORE BEST PRACTICES FOR CANVAS??
Please add to this thread what you know, have learned, or have read online any and all Canvas best practices, tips/tricks for performance
With Canvas being still very new to internet, and no signs of it ever getting old that I can see in the future, there are not too many documented "best practices" or other really important tips that are a 'must know' for developing with it in any one particular place. Things like this are scattered around and many times on lesser known sites.
There's so many things that people need to know about, and still so much to learn about too.
I wanted to share some things to help people who are learning Canvas and maybe some who already know it quite well and am hoping to get some feedback from others about what they feel are some best practices or other tips and tricks for working with Canvas in HTML5.
I want to start off with one I personally found to be quite a useful yet surprisingly uncommon thing for developers to do.
1. Indent your code
Just as you would any other time, in any other language whatever the case may be. It has been a best practice for everything else, and I have come to find that in a complex canvas app, things can get a little confusing when dealing with several different contexts and saved/restore states. Not to mention the code is just more readable and overall cleaner looking too.
For example:
...
// Try to tell me this doesn't make sense to do
ctx.fillStyle = 'red';
ctx.fill();
ctx.save();
if (thing < 3) {
// indenting
ctx.beginPath();
ctx.arc(2, 6, 11, 0, Math.PI*2, true);
ctx.closePath();
ctx.beginPath();
ctx.moveTo(20, 40);
ctx.lineTo(10, 200);
ctx.moveTo(20, 40);
ctx.lineTo(100, 40);
ctx.closePath();
ctx.save();
ctx.fillStyle = 'blue'
ctx.fill();
ctx.restore();
} else {
// no indenting
ctx.drawImage(img, 0, 0, 200, 200);
ctx.save();
ctx.shadowBlur();
ctx.beginPath();
ctx.arc(2, 60, 10, 0, Math.PI*2, false);
ctx.closePath();
ctx.fillStyle 'green';
ctx.fill();
ctx.restore();
}
ctx.restore();
ctx.drawRect();
ctx.fill();
...
Is the IF statement not easier and cleaner to read and know what is what immediately going on than the ELSE statement in this? Can you see what I'm saying here? I think this should be a method that developers should continue to practice just as they would when writing plain 'ol javascript or any other language even.
Use requestAnimationFrame instead of setInterval / setTimeout
setInterval and setTimeout were never intended to be used as animation timers, they're just generic methods for calling functions after a time delay. If you set an interval for 20ms in the future, but your queue of functions takes longer than that to execute, your timer won't fire until after these functions have completed. That could be a while, which isn't ideal where animation is concerned. RequestAnimationFrame is a method which tells the browser that an animation is taking place, so it can optimize repaints accordingly. It also throttles the animation for inactive tabs, so it won't kill your mobile device's battery if you leave it open in the background.
Nicholas Zakas wrote a hugely detailed and informative article about requestAnimationFrame on his blog which is well worth reading. If you want some hard and fast implementation instructions, then Paul Irish has written a requestAnimationFrame shim – this is what I've used in every one of the Canvas apps I have made until recently.
ACTUALLY
Even better than using requestAnimationFrame in place of setTimeout and setInterval, Joe Lambert has written a NEW and improved shim called requestInterval and requestTimeout, which he explains what issues exist when using requestAnimFrame.
You can view the gist of the script.
ACTUALLY x2
Now that all the browsers have caught up on the spec for this, there has been an update to the requestAnimFrame() polyfill, one which will probably remain the one to use to cover all vendors.
Use more than one canvas
A technique for animation-heavy games which #nicolahibbert wrote about in a post of hers on optimizing Canvas games mentions that it may be better to use multiple canvasses layered on top of one another rather than do everything in a single canvas. Nicola explains that "drawing too many pixels to the same canvas at the same time will cause your frame rate to fall through the floor. Take Breakout for example. Trying to draw the bricks, the ball, the paddle, any power-ups or weapons, and then each star in the background – this simply won't work, it takes too long to execute each of these instructions in turn. By splitting the starfield and the rest of the game onto separate canvases, you are able to ensure a decent framerate."
Render Elements Off-screen
I have had to do this for a few apps I've made including Samsung's Olympic Genome Project facebook app. It's an extremely useful thing to know and to make use of whether it's needed or not. It decreases load time immensely, plus it can be a really useful technique to load images off screen since they can sometimes take a while.
var tmpCanvas = document.createElement('canvas'),
tmpCtx = tmpCanvas.getContext('2d'),
img = document.createElement('img');
img.onload = function() {
tmpCtx.drawImage(thumbImg, 0, 0, 200, 200);
};
img.src = '/some/image/source.png';
Notice that the src of the image is set after it is loaded. This is a key thing to remember to do too. Once the images are done loading and drawn into these temp canvases, you can then draw them to your main canvas by using the same ctx.drawImage(), but instead of putting the image as the first argument, you use 'tmpCtx.canvas' to reference the temp canvas.
Other tips, tricks and resources
Canvas test cases
Some more canvas and JS tests
HTML5Rocks performance Improving
**requestAnimFrame to Optimize Dragging Events
Canvas has a back-reference
The 2d context has a back reference to it's associated DOM element:
var ctx = doc.getElementById('canvas').getContext('2d');
console.log(ctx.canvas); // HTMLCanvasElement
I'd love to hear more from other people on this. I am working on making a list of things that we should standardize to add a new section to my company's Front-end Code Standards and Best Practices. I'd love to get as much feedback on this as I can.
Redraw Regions
The best canvas optimization technique for animations is to limit the amount of pixels that get cleared/painted on each frame. The easiest solution to implement is resetting the entire canvas element and drawing everything over again but that is an expensive operation for your browser to process.
Reuse as many pixels as possible between frames. What that means is the fewer pixels that need to be processed each frame, the faster your program will run. For example, when erasing pixels with the clearRect(x, y, w, h) method, it is very beneficial to clear and redraw only the pixels that have changed and not the full canvas.
Procedural Sprites
Generating graphics procedurally is often the way to go, but sometimes that's not the most efficient one. If you're drawing simple shapes with solid fills then drawing them procedurally is the best way do so. But if you're drawing more detailed entities with strokes, gradient fills and other performance sensitive make-up you'd be better off using image sprites.
It is possible to get away with a mix of both. Draw graphical entities procedurally on the canvas once as your application starts up. After that you can reuse the same sprites by painting copies of them instead of generating the same drop-shadow, gradient and strokes repeatedly.
State Stack & Transformation
The canvas can be manipulated via transformations such as rotation and scaling, resulting in a change to the canvas coordinate system. This is where it's important to know about the state stack for which two methods are available: context.save() (pushes the current state to the stack) and context.restore() (reverts to the previous state). This enables you to apply transformation to a drawing and then restore back to the previous state to make sure the next shape is not affected by any earlier transformation. The states also include properties such as the fill and stroke colors.
Compositing
A very powerful tool at hand when working with canvas is compositing modes which, amongst other things, allow for masking and layering. There's a wide array of available composite modes and they are all set through the canvas context's globalCompositeOperation property. The composite modes are also part of the state stack properties, so you can apply a composite operation, stack the state and apply a different one, and restore back to the state before where you made the first one. This can be especially useful.
Anti-Aliasing
To allow for sub-pixel drawings, all browser implementations of canvas employ anti-aliasing (although this does not seem to be a requirement in the HTML5 spec). Anti-aliasing can be important to keep in mind if you want to draw crisp lines and notice the result looks blurred. This occurs because the browser will interpolate the image as though it was actually between those pixels. It results in a much smoother animation (you can genuinely move at half a pixel per update) but it'll make your images appear fuzzy.
To work around this you will need to either round to whole integer values or offset by half a pixel depending on if you're drawing fills or strokes.
Using Whole Numbers for drawImage() x and y positions
If you call drawImage on the Canvas element, it's much faster if you round the x and y position to a whole number.
Here's a test case on jsperf showing how much faster using whole numbers is compared to using decimals.
So round your x and y position to whole numbers before rendering.
Faster than Math.round()
Another jsperf test shows that Math.round() is not necessarily the fastest method for rounding numbers. Using a bitwise hack actually turns out to be faster than the built in method.
Canvas Sprite Optimization
Clearing the Canvas
To clear the entire canvas of any existing pixels context.clearRect(x, y, w, h) is typically used – but there is another option available. Whenever the width/height of the canvas are set, even if they are set to the same value repeatedly, the canvas is reset. This is good to know when working with a dynamically sized canvas as you will notice drawings disappearing.
Computation Distribution
The Chrome Developer Tools profiler is very useful for finding out what your performance bottlenecks are. Depending on your application you may need to refactor some parts of your program to improve the performance and how browsers handle specific parts of your code.
Optimization techniques
Here are my tips
1) Use clearRect to clear the canvas instead of canvas.width=canvas.width, because later resets the canvas states
2) If you are using mouse events on the canvas use following function, its is reliable and works in most of the cases.
/** returns the xy point where the mouse event was occured.
#param ev The event object.
*/
function getXY(ev){
return getMousePosition(ev, ev.srcElement || ev.originalTarget);
}
/** returns the top-left point of the element
#param elem The element
*/
function getElementPos(elem){
var obj = elem;
var top = 0;
var left = 0;
while (obj && obj.tagName != "BODY") {
top += obj.offsetTop-obj.scrollTop;
left += obj.offsetLeft -obj.scrollLeft ;
obj = obj.offsetParent;
}
return {
top: top,
left: left
};
};
/** returns the xy point where the mouse event was occured inside an element.
#param ev The event object.
#param elem The element
*/
function getMousePosition(evt, elem){
var pageX, pageY;
if(typeof(window.pageYOffset)=='number') {
pageX=window.pageXOffset;
pageY=window.pageYOffset;
}else{
pageX=document.documentElement.scrollLeft;
pageY=document.documentElement.scrollTop;
}
var mouseX = evt.clientX - getElementPos(elem).left + pageX;
var mouseY = evt.clientY - getElementPos(elem).top + pageY;
return {
x: mouseX,
y: mouseY
};
};
3) Use ExplorerCanvas if you want to support IE7
4) Instead of clearing the whole canvas clear only the part which is needed to be cleaned. Its good for performance.
Here's some more tips and suggestions I put into a list last night worth sharing.
Don't include jQuery unless you need to do more than just selecting the <canvas>.
I've managed to get by without it for almost everything I've made in canvas
Create abstracted functions and decouple your code. Separate functionality from appearance or initial draw state.
Make common functions reusable as much as possible. Ideally, you should use a module pattern, which you can create a utils object that contains common functions.
Use single and double letter variable names when it makes sense (x, y, z).
The coordinate system in Canvas adds more single letters that are
commonly declared as variables. Which can lead to creating multiple
single/double variables (dX, dY, aX, aY, vX, vY) as part of an element.
I suggest you type out or abbr. the word (dirX, accelX, velX) or be descriptive, otherwise things could get pretty confusing for you later on, trust me.
Create constructor functions which can be invoked as needed for making game elements. You can add custom methods and properties within the constructor, and create any number of you may need and they all will have their own properties and methods.
Example of a Ball constructor function I made:
// Ball constructor
var Ball = function(x, y) {
this.x = x;
this.y = y;
this.radius = 10;
this.color = '#fff';
// Direction and min, max x,y
this.dX = 15;
this.dY = -15;
this.minX = this.minY = 20 + this.radius;
this.maxX = this.radius - (canvasWidth - 20);
this.maxY = this.radius + canvasHeight;
this.draw = function(ctx) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, twoPI, true);
ctx.closePath();
ctx.save();
ctx.fillStyle = this.color;
ctx.fill();
ctx.restore();
};
};
Creating the Ball
ball = new Ball(centerX, canvasHeight - paddle.height - 30);
ball.draw(ctx);
A good base to work with is to create 3 functions:
init() - do all the initial work, and setup the base vars and event handlers etc...
draw() - called once to begin the game and draws the first frame of the game, including the creation of elements that may be changing or need constructing.
update() - called at the end of draw() and within itself via requestAnimFrame. Updates properties of changing elements, only do what you need to do here.
Do the least amount of work within the loop, making updates to the changing parts or elements. Create the game elements do any other UI work outside the animation loop.
The animation loop is often a recursive function, meaning it calls itself rapidly and repeatedly during the animation to draw each frame.
If there are many elements being animated at once, you might want to first create the elements using a constructor function if your not already, and then within the constructor make a 'timer' method that has requestAnimFrame/setTimeout using it just how you would normally within any animation loop, but effects this element specifically only.
You could make each game element have it's own timer, draw, and animate methods in the constructor.
Doing this gives you full separation of control for each element and one big animation loop will not be necessary at all since the loop is broken up into each element and you start/stop at will.
Or another option:
Create a Timer() constructor function which you can use and give each animating element individually, thereby minimizing work load within animation loops
After having worked on a recently launched Facebook app that uses Canvas and users Facebook profile information (the amount of data it must accommodate is massive for some) to match you and friends of yours also using the app, to Olympic athletes like a 6 degrees of separation type of thing, there's quite a lot I have learned in my extensive efforts to do everything I could possibly try for increasing performance within the app.
I literally spent months, and days at a time just working to re-factor the code which I knew already so well, and believed it to be the most optimal way to do things.
Use DOM Elements Whenever Possible
The fact is, browsers are still just not ready to handle more intensive running applications in Canvas, especially if you're required to develop the app with support for IE 8. There are sometimes cases where the DOM is faster than the current implementation of the Canvas API at the time of writing this. At least I've found it to be while working on a massively complex single page animating html5 and canvas application for Samsung.
We were able to do quite well at improving the performance of things while still using Canvas to do some complex work to crop images into circles, which would've probably been ok to stick with how we were doing it.
Days before the launch, we decided to try a different technique, and rather than create temporary canvases off-screen which were placed on the visible canvas once cropped into circles etc.., we just appended Image DOM elements on the Canvas, using the x and y coordinates that we had been using for placing the temp canvases before.
For cropping the images into circles, well that was simple, we just used the CSS3 border-radius property to do it which was far less work than the complex series of state changes and while ingenious and creative yet over-use of the .clip() method.
Once they are placed in the DOM, the animation of images the occurs, and the DOM nodes for each image are animated as separate entities of the Canvas. Ones that we can have full control over the styling off easily through CSS.
This technique is similar to another method for doing this type of work that is quite good to know as well, which involves layering Canvases on top of each other, rather than draw them to one context.

Optimizing html5 canvas game

Right now I've got two game loops in a game I'm making. A draw loop that loops through an array of objects on screen and a logic loop that does game logic. I have the logic loop running about 10 more frames than the draw loop. I have this set up like this because doing game logic may take longer and I don't want it to interfere with the draw loop.
I have the logic loop set up like this:
vs.logicloop = function(){
vs.Gameloop();
//do the updating of object scripts
if(vs.windowActive){
var l = vs.scenegraph.length;
var i = 0;
while(i < l){
vs.scenegraph[i].logicScript();
i++;
}
}
//restart loop
setTimeout(vs.logicloop, 1000/(vs.fps+10));
};
and the draw loop like this:
vs.drawloop = function(){
//clear the screen
vsd.clr();
//goes through everything in the scene
//graph and draws it and runs each object's
//personal draw code
if(vs.windowActive){
var l = vs.scenegraph.length;
var i = 0;
while(i < l){
vs.ctx.save();
vs.scenegraph[i].update();
vs.scenegraph[i].draw();
vs.scenegraph[i].drawScript();
vs.ctx.restore();
i++;
}
}
//restart loop
setTimeout(vs.drawloop, 1000/vs.fps);
};
I'm using setTimeout because I heard that setInterval will cause loops to overlap if one isn't finished yet. Are there any optimizations I can do to really get some speed? Especially optimizing the game loops.
I've heard of some javascript engines getting thousands of objects on screen at once. I can't imagine how they do that, at most mine can get up to 100 objects on screen on a very old computer and about 700 on a reasonably stocked computer. And that's without a lot of game code running in the background and before I've worked out how to do pixel perfect collision detection and physics.
My process is to draw a background color fillRect over the canvas every draw loop, then looping through all the objects and drawing their draw code. Also it doesn't try to draw objects out of view.
This is my first paying job, and I really want to impress. Plus I can keep ownership of the engine once I'm done with the game.
Thanks A Lot
if you use floating values for sprite coordinates, try converting them to integers. that will cost you losing subpixel rendering but you will gain a lot of speed.
don't use images with odd widths. always use widths as powers of 2.
this one is hard to implement in some cases but if your game is suitable, don't clear screen and redraw everything each frame. instead, draw changed parts.
if you have to clear the canvas, don't draw a blank rectangle. try setting the canvas width/height again with the same size. that should reset the pixels faster than rectangle drawing.
rest of the methods i can suggest are not HTML5 canvas dependent but general subjects like using bit shiftings, inverse loops, and operator instead of modulo when possible, precalculations etc.
Oh geez, I could probably write you a full sonnet here if you posted all your code. Here's a quick rundown:
Read Emir's answer. All of those are good except the last one which is very dependent on the situation. Setting canvas.width = canvas.width to clear the canvas can be faster on some browsers but it also clobbers all canvas state (ie the last set fill and font) which can slow things down because setting those properties is actually painfully slow.
Read my articles on Canvas performance: http://simonsarris.com/blog/tag/performance
I have a lot of other tips saved up in a private document that I'm writing a small ebook out of. If you want early access to it I can probably allow that.
Pick up High performance JavaScript by Zakas and read it.
Don't use save() and restore() like you are in the quoted code unless you must. They are just slowing things down.
For the timer see http://paulirish.com/2011/requestanimationframe-for-smart-animating/
Multiple canvases for foreground-background-middleground can definitely help. Caching things on in-memory canvases can definitely help. It all depends on what you're drawing.
A lot of performance problems are due to death by a thousand tiny cuts. For instance:
vs.scenegraph[i].update();
vs.scenegraph[i].draw();
vs.scenegraph[i].drawScript();
To
var scene = vs.scenegraph[i];
scene.update();
scene.draw();
scene.drawScript();
Will help a minute amount. How many opportunities for minute-amount stuff you have I don't know - we'd need to see a lot more code.
I heard that setInterval will cause loops to overlap if one isn't finished yet.
This is false, JavaScript is single threaded. This means that if your first interval is still running when it hits the next step, the next step will be delayed until the first step has finished computing. This also means that you can't rely on setInterval to be accurate if you start doing a lot of computations.
I'd echo much of all has been said by other people. Integer values, use request animation frame, etc. If drawing text be careful how often you set fonts. Also you might find using an object pool can help if you are creating lots of temporary objects per frame.
As a general read on game loops I'd recommend this: http://www.koonsolo.com/news/dewitters-gameloop/

Drag and drop in mozilla canvas

I want to implement a drawing pane (similar but smaller version to what visio gives for flow charts) in mozilla canvas.
Is there any support for this?
I have used jQuery till now to create the rectangles and move them around. While this is easy here..creating lines (connections between objects) is a real pain. I am using some crude way to color pixel by pixel in javascript and it is neither looking good nor scalable and also I need to build a lot of functions to make the connections stick to a set of objects etc.
Does anyone know if the canvas and the functions available there will make my life easier.
Any pointers to what is a better solution in this case. (I am hoping it is not applet)
Thanks in advance.
Yes you can use canvas for that. Drawing simple shapes and scaling them is pretty simple.
But if you need to edit the shapes after you have drawn them, you will have to invest some more work. Canvas draws in a so called "immediate mode", which means, that it does not know what you have painted right after you have painted it. It does not keep track of painted shapes. If you need that you will have to implement that on your own.
I have done this using the isPointInPath() function which can be used to test if a user clicks on a particular point. I keep track of my painted objects using the MVC-Pattern (Model-View-Controller), so that I can find out which Shape has been clicked on.
Another alternative might be fabrics.js which should be very close to what you need.
Please follow this link :
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial
LMK if it helps!
Following steps may help:
1. Create and add a canvas to the DOM :
var myCanvas = document.createElement('canvas'); document.body.appendChild(myCanvas);
2. Set the width-height of canvas :
myCanvas.width=200;
myCanvas.height=200;
3. Get the context of the canvas and start drawing on it :
var gc = myCanvas.getContext('2d');
4. Code to draw rectangle :
gc.strokeRect(50,50,50,50);
5. After this, add mousehandlers(mousedown,mousemove,mouseup)/touchhandlers(touchdown,touchmove,touchup) on the canvas and handle the movement accordingly.
Either of these jQuery plugins are great for drawing panes:
jCanvas For drawing any simple and even complex shapes
sketch.js for drawing in general.
They are both responsive and compatible.

Categories