Instializing this as an object with the new keyword is necesarry, but saving the object to a variable is not, since all functions will be applied to the DomElement directly.
var DomElement = document.getElementById('myCanvas'),
ConfigObject = {};
new Canvas(DomElement, ConfigObject);
If no element is given a canvas will be created and appended to the body. If the element is not a canvas it will be taken as a container, and any canvases within it will be used as layers. All functions will be applied to the container element given, not the canvases within.
To set the draw loop function, simply define a draw, beforeDraw, or afterDraw function.
var canvas = document.getElementById('myCanvas');
new Canvas(canvas);
canvas.draw = function () {
canvas.beginPath();
canvas.rect(0,0,50,40);
canvas.fill('#0f0');
}
Because the draw function is in the same scope as the context functions they can be called using this
canvas.draw = function () {
this.fillRect(0,0,50,40,'#0f0');
this.fillCircle(100,120,30,'#00f');
}
Name | Default | Values | Description |
---|---|---|---|
zoom | 1 | Number between 0 and... infinity zoom > 0 | Zoom level, or scale factor of the canvas drawing. |
center | {x:0,y:0} | x, y coordinate object | The offset, or translation of the canvas drawing. This should only be gotten after initialization, and should be set using canvas.setCenter({x:0,y:0}) after that. |
inverseY | false | Boolean: true/false | Inverts the Y axis, as the pre-flipping of it can be an annoyance |
inverseZ | false | Boolean: true/false | Inverts the scrolling direction, for those who prefer OSx style scrolling. This does not effect touch-screen pinch zooming. |
zoomMin | 1/34000 | Number between 0 and 1 0 < zoomMin <= 1 | The minimum magnification (zoom out) of the canvas. |
zoomMax | 34000 | Number between 1 and infinity zoomMax >= 1 | The maximum magnification (zoom in) of the canvas. At values greater than 34000 lines begin to disappear, text acts funny and the zoom algorithm may jitter. |
scrollSpeed | 1/1000 | Number between 0 and 1 0 < scrollSpeed < 1 | The magnification factor of scrolling |
shapeOrigin | false |
"top", "bottom", "left", "right", "center"
or any pair of horizontal and vertical positions |
The position of the point given to a shape function relative to the shape drawn. Normal value for rectangles and text would be "top left".
If only one position is defined, e.g. "left" then the other position will be the shape's default: center for arcs; and the top for rectangles and text. |
clearBeforeDraw | true | Boolean: true/false | Clearing the canvas before the draw loop can be disabled if you require a difference-based render method. |
panning | true | Boolean: true/false | The ability to pan the canvas can be disabled by this switch |
zooming | true | Boolean: true/false | The ability to zoom the canvas can be disabled by this switch |
zoomPanning | true | Boolean: true/false | The ability to change the center of origin while zooming can be disabled by this switch. If this is off while panning is on, then you will always zoom into the center of the current view, regardless of mouse position, while still being able to change the center by panning. |
minShapeZoom | 0 | Number between 0 and 1 0 <= minShapeZoom < 1 | The zoom (out) level that objects will begin to retain their size at, instead of continuing to get smaller. |
Slight lag is due to repeated text rendering
var canv = new Canvas(),
C = document.getElementsByTagName('canvas')[0];
C.draw = function () {
for (var x=-400;x<400;x+=30) {
for (var y=-400;y<400;y+=30) {
var r = (x*y)/8000,
c = '#f00';
if (r < 0) {
r = -r;
c = '#00f';
}
this.fillSquare(x,y,r*2,'#0f0');
this.paintCircle(x,y,r,c);
this.setCtx('font',"5px sans-serif")
this.fillText(x+":"+y,x,y,'#000');
}
}
};
C.onclick = function (ev) {
console.log(
this.unPosition({x:ev.offsetX, y:ev.offsetY}));
}
C.size({
height:function () {
return window.innerHeight;
},
width:function () {
return window.innerWidth;
}
})
The canvas can start an animaion loop for you using requestAnimationFrame to control it. Use the animate function to start and the stop function to end
canvas.animate()
canvas.stop()
The drawSpace function can be called outside of the animation loop to re-draw the canvas entirely. The clear function clears the entire canvas, and should be called before drawSpace.
canvas.clear()
canvas.drawSpace()
You can reset the canvas state, incuding position and scale; Get the current translation offset, accounting for zoom; Set the current view center, updating the offset; And set the current drawing layer.
canvas.reset()
canvas.getOffset(position)
canvas.setCenter(position)
canvas.setLayer(index)
The size function can be passed a {width:w,height:h} object, or can be passed the property and value separately. This will in turn run the Width or Height functions, which can be pased a number or a function that will update on window resize.
canvas.size(object OR prop, val)
canvas.Width(val)
canvas.Height(val)
To fill the screen with the canvas you might use this object.
canavs.size({
height:function () {
return window.innerHeight;
},
width:function () {
return window.innerWidth;
}
})
You can set and get properties from the canvas element using the config function, which will in turn call get or set. The config function can be passed an object to set multiple values at once, or a single property or name value pair to get or set it.
canvas.config(object OR prop, val)
canvas.set(prop, val)
canvas.get(prop)
To set context properties, such as fillStyle, use the configCtx, setCtx or getCtx functions. These functions provide many synonyms and abbreviations for common values, for strokeStyle: stroke-style, stroke_style, stroke, line, lineStyle,..
canvas.configCtx(object OR prop, val)
canvas.setCtx(prop, val)
canvas.getCtx(prop)
Pass a {x:0,y:0} coordinate to either function, the position function will translate the real coordiante to a canvas coordinate - but there is no need to transform these numbers with any of the drawing functions while in the draw loop. The unPosition function will take a canvas coordiate (such as a mouse click) and output the corresponding real-space coordinate.
canvas.position(position)
canvas.unPosition(position)
All functions that can be called from the context can now be called from the canvas element (or container). Drawing shapes from the canvas element will apply a transformation based on an offset and a zoom level - or a translation and a scale (though canvas translation is not used as it's buggy with large values). The context is not modified, and can still be used in the normal way. See this list of context methods for duplicated functions.
All shapes now have a paint(Shape) function, which fills and strokes a shape. fill(Shape) and stroke(Shape) functions can be called with an aditional style argument that will set the fillStyle or strokeStyle of the context.
canvas.paintRect(x, y, w, h, fillStyle, strokeStyle)
canvas.fillRect(x, y, w, h, style)
canvas.strokeRect(x, y, w, h, style)
There are also additional shapes that help avoid predictable duplication on your part. In the square functions bellow the third argument r is the length of any side.
canvas.square(x, y, r)
canvas.fillSquare(x, y, r, style)
canvas.strokeSquare(x, y, r, style)
canvas.clearSquare(x, y, r)
canvas.paintSquare(x, y, r, fillStyle, strokeStyle)
The arc has been given its own fill and stroke functions, and the circle function simply assumes angles a and b are 0 and 2 * PI.
canvas.fillArc(x, y, r, a, b, style)
canvas.strokeArc(x, y, r, a, b, style)
canvas.paintArc(x, y, r, a, b, fillStyle, strokeStyle)
canvas.circle(x, y, r)
canvas.fillCircle(x, y, r, style)
canvas.strokeCircle(x, y, r, style
canvas.paintCircle(x, y, r, fillStyle, strokeStyle)
The curveTo function takes between 2 and 6 arguments to define a lineTo(2 args), quadraticCurveTo(4 args), arcTo(5 args), or bezierCurveTo(6 args).
Normally the quadraticCurveTo and bezierCurveTo functions take the endpoint x, y last, but in this mapping they take that point first, and the cp arguments after in normal order.
canvas.curveTo(*args*)
The path function takes a list of points (as lists of coordinates), and can take many lists in unlimited arguments, or the points as the list of arguments.
This nesting also means you can pass more complicated lists of lists of lists, but each layer should be similarly nested, because it will assume all arguments are of the same type as the first (a line or point).
This function runs context.beginPath before each line.
canvas.path(path, path2,..)
The closedPath function will run the path function above, and then context.closePath.
canvas.closedPath(path, path2,..)
You can also treat the closed path like any other shape and fill or stroke it directly.
canvas.fillPath(path, style)
canvas.strokePath(path, style)
canvas.paintPath(path, fillStyle, strokeStyle)
The line functions below are maped directly to the path functions above.
canvas.line(path, path2,..)
canvas.closedLine(path, path2,..)
canvas.fillLine(path, style)
canvas.strokeLine(path, style)
canvas.paintLine(path, fillStyle, strokeStyle)
If a container element is given with several canvases within, then they will be taken as layers, zero-indexed in the order the dom will be traversed, and can also be refered to by element id when setting the current layer:
container.setLayer(0)
container.setLayer(1)
container.setLayer("my-layer-id")
All drawing functions will be applied to the current context at container.context (canvas.context in other examples), and the setLayer function simply sets this variable to the correct context, allowing you to switch layers at any time, and draw using the same functions and variables.
container.setLayer(0)
var a = container.context;
container.setLayer(1)
// a != container.context
This will initialise with the first canvas' context, if an unknown value is passed to setLayer then it will also default to the first context. If an index is given greater than possible then it will default to the last layer's context.
The canvas has events for the actions: Panning, Zooming and Resize-ing and will automatically make the canvas navigable and responsive.
Each action has three events: Start, Step and Stop, and each event has three callbacks: before, during and after. E.g.
canvas.beforePanStop = function () {}
canvas.zoomStep = function () {}
canvas.afterResizeStart = function () {}
Each actions runs the events and callbacks in this order:
before(Action)Start()
set action state
(action)Start()
STEP()
start animating
event.preventDefault
after(Action)Start()
before(Action)Step()
action logic
(action)Step()
event.preventDefault
after(Action)Step()
before(Action)Stop()
unset action state
(action)Stop()
stop animating
event.preventDefault
after(Action)Stop()
Hammer JS is also used to apply touch-screen panning and zooming, and works accurately with no intervention.
The PC-browser panning and zooming are set directly to the canvas.onmousedown and canvas.onmousewheel functions so can be easily overridden if necessary.