Shapes¶
A drawing is composed of shapes. Shapes are added either by tools or by you,
programmatically. All shapes are created through the
LC.createShape()
function.
A “color” is a CSS color string.
Creating shapes¶
Note
This section might be out of date. Read the source.
-
LC.
createShape
('Image', {x, y, image})¶ - Arguments
x/y – Upper left corner position
scale – Scale of the image. Defaults to 1.0.
image – A DOM Image object
Note
If you’d like to add an
image.onload
callback, do not assign it directly! This will break several things. Instead, useLC.util.addImageOnload()
.
-
LC.
createShape
('Rectangle', {x, y, width, height, strokeWidth, strokeColor, fillColor})¶ - Arguments
x/y – Upper left corner position
width/height – Size of the rectangle
strokeWidth – Width of the border
strokeColor – Color of the border
fillColor – Color of the middle
-
LC.
createShape
('Line', {x1, y1, x2, y2, strokeWidth, color, capStyle, endCapShapes})¶ - Arguments
x1/y1 – One end of the line
x2/y2 – Other end of the line
strokeWidth – Width of the line
color – Color of the line
capStyle – Line cap style. Defaults to
'round'
. Read the HTML<canvas>
docs for other valid values.endCapShapes – Two-item list
[srcShapeId, destShapeId]
, where each value is'arrow'
ornull
.dash – Value to be passed to
ctx.setLineDash()
when this line is rendered.
-
LC.
createShape
('Text', {x, y, text, color, font})¶ - Arguments
x/y – Top left corner position
text – String to render
color – Text color
font – Font settings string. The format is apprimately
"[italic] [bold] fontSize fontName"
.forcedWidth – If
null
, this shape’s width is equal to the rendered width of the text. Otherwise, the text is wrapped to this width.forcedHeight – Height the user has specified for this text box. Ignored when rendering; only used to show the dragging box while resizing.
v – Version of the text shape API this shape was created with. Defaults to 1. Shapes from version 0 will be converted to version 1.
-
LC.
createShape
('LinePath', {points, smooth})¶ - Arguments
points – List of Point objects
smooth – If
true
, the given points will be smoothed to look more natural. Defaults totrue
.
-
LC.
createShape
('ErasedLinePath', {points, interpolate})¶ - Arguments
points – List of Point objects
smooth – If
true
, the given points will be smoothed to look more natural. Defaults totrue
.
-
LC.
createShape
('Polygon', {points, fillColor, strokeColor, strokeWidth, isClosed})¶ - Arguments
points – List of Point objects
fillColor – Fill color
strokeColor – Stroke color
strokeWidth – Width of the line around the edge.
isClosed – If
true
, draws a line between the first and last points.
-
LC.
createShape
('Ellipse', {x, y, width, height, strokeWidth, strokeColor, fillColor})¶ - Arguments
points – List of Point objects
fillColor – Fill color
strokeColor – Stroke color
strokeWidth – Width of the line around the edge.
-
LC.
createShape
('Point', {x, y, size, color})¶ - Arguments
x/y – Upper left corner position
size – Size of the rectangle
color – Color of the point
Point is primarily an internal data structure for LinePath and ErasedLinePath. It can’t currently be drawn.
-
LC.
createShape
('SelectionBox', {shape, backgroundColor})¶ Note
This shape is mostly for internal use.
- Arguments
shape – Shape to draw the box around
backgroundColor – Color to render behind the selection box
Shapes and JSON¶
Each shape has a JSON representation so that you can save and load drawings.
But just calling shape.toJSON()
won’t give you a value that you can
decode later; Literally Canvas wraps these values in containers with additional
information. Instead, you can use these functions to save and load shapes:
-
LC.
shapeToJSON
(shape)¶ - Returns
JSON-encoded string representing shape
-
LC.
JSONToShape
(jsonEncodedString)¶ - Returns
Shape instance constructed from jsonEncodedString
If you’ve saved a snapshot with LC.getSnapshot()
or
LC.getSnapshotJSON()
, you can convert that to a list of deserialized
shape objects with these functions:
-
LC.
snapshotToShapes
(snapshot)¶
-
LC.
snapshotJSONToShapes
(snapshotJSON)¶
Rendering shapes outside of an interactive session¶
-
LC.
renderShapesToCanvas
(shapes, bounds, scale=1, canvas=null)¶ Draws the given shapes to the given canvas. Creates a new canvas if none is provided. Returns the canvas containing the rendered shapes.
- Arguments
shapes – List of shapes
bounds – A dict
{x, y, width, height}
specifying which part of the image to draw, in drawing coordinates (before scaling).scale – Amount by which to scale the image output. Shapes will be rendered at full resolution. Defaults to
1
.canvas – Canvas object on which to render the shapes. If
null
, a new canvas will be created with the size specified by bounds.
This function can be used to render a snapshot to an image without instantiating a
LiterallyCanvas()
object like this:var snapshotJSON = localStorage['saved-snapshot']; var canvas = LC.renderShapesToCanvas( LC.snapshotJSONToShapes(snapshotJSON), {x: 0, y: 0, width: 100, height: 100}); // Now you can pull out the image using a data URL: var dataURL = canvas.toDataURL(); // Or pull out the bytes using the canvas API.
-
LC.
renderShapesToSVG
(shapes, bounds, backgroundColor)¶ Converts the list of shapes to an SVG string.
- Arguments
shapes – List of shapes
bounds – A dict
{x, y, width, height}
specifying which part of the image to draw, in drawing coordinates.backgroundColor – SVG color to draw behind the shapes.
This function can be used to render a snapshot to SVG without instantiating a
LiterallyCanvas()
object like this:var snapshotJSON = localStorage['saved-snapshot']; var svgString = LC.renderShapesToSVG( LC.snapshotJSONToShapes(snapshotJSON), {x: 0, y: 0, width: 100, height: 100}, 'transparent');
Defining shapes¶
If you want to make your own tool, or do some custom canvas rendering as the
background of your drawing, you’ll need to define a shape. Then you can create
it using the LC.createShape()
function.
-
LC.
defineShape
(name, methods)¶
-
LC.
defineCanvasRenderer
(name, drawShape)¶ - Arguments
name – Name of the shape
drawShape – A function that takes
(canvasContext, shape)
and renders the shape to the context.
-
LC.
defineSVGRenderer
(name, shapeToSVGString)¶ - Arguments
name – Name of the shape
shapeToSVGString – A function that returns an SVG string representing the given shape.
LC.defineShape('MyAwesomeShape', {
/* initialize using the args passed to LC.createShape() */
constructor: function(args) {
this.x = args.x;
this.y = args.y;
this.doStuff();
},
/* you can add arbitrary methods */
doStuff: function() {},
/* provide a bounding rectangle so getImage() can figure out the image
bounds (semi-optional) */
getBoundingRect: function() {
return {x: this.x, y: this.y, width: 0, height: 0};
},
/* return a dictionary representation of the shape from which this instance
can be reconstructed */
toJSON: function() {
return {x: this.x, y: this.y};
},
/* reconstruct the MyAwesomeShape from the representation given by
toJSON */
fromJSON: function(data) {
return LC.createShape('MyAwesomeShape', data);
}
});
/* Define canvas and SVG renderers */
LC.defineCanvasRenderer('MyAwesomeShape', function(ctx, shape) {
ctx.renderStuff();
})
// You can skip this step if you never export to SVG
LC.defineSVGRenderer('MyAwesomeShape', function(shape) {
return "<BestShapeEver />";
})
/* you can use it as a background */
var lc = LC.init(element, {
backgroundShapes: [LC.createShape('MyAwesomeShape', {x: 0, y: 0})]
});
/* you can add it as part of the drawing */
lc.saveShape(LC.createShape('MyAwesomeShape', {x: 100, y: 100}))
Adding shapes to drawings programmatically¶
You can add a shape to the drawing with the
LiterallyCanvas.saveShape()
method, like this:
// let's put a kitten in our drawing
var lc = LC.init(element, options);
var img = new Image();
img.src = 'http://placekitten.com/200/300';
lc.saveShape(LC.createShape('Image', {x: 100, y: 100, image: img}))