Space
provides a general context for its points to be expressed. Each subclass of Space
represents a specific context. Currently Pts
includes CanvasSpace
which corresponds to the canvas
element, and SVGSpace
which lets you create vector graphics in svg format instead. There is also an experimental HTMLSpace
which renders forms in basic html elements. Soon we will have spaces for other contexts too.
CanvasSpace
can be created like this:
let space = new CanvasSpace( "#hello" );
space.setup({ bgcolor: "#123", retina: true });
The "#hello" is a selector string
that selects an element in the html page. If the element is a <canvas>
, it will be used by CanvasSpace. If the element is a <div>
or other block element, a new <canvas>
will be appended into it. You may also pass a HTMLElement directly, instead of a query selector string.
Once the space is created, you can optionally call the setup
function to specify its background color (bgcolor
) and other properties. Take a look at the setup
documentation for more.
Now the space is set up, let's look at what it can do.
A space by itself is void of form. Let's add a "player" to it. A player can be either a function or an object with specific properties.
space.add( (time, ftime) => {
// do things
});
In the above, we use add
to add a simple callback function. It has 2 parameters: time
which gives the current running time, and ftime
which gives the time taken to draw the previous frame. This callback is like an animation loop, which will be called continuously when the player plays.
Let's look at a more elaborate player:
space.add( {
start: (bound, space) => {
// code for init
},
animate: (time, ftime, space) => {
// code for animation
},
action: (type, x, y, event) => {
// code for interaction
},
resize: (size, event) => {
// code for resize
}
} );
Here we add an object that conforms to the IPlayer interface, which defines 4 optional callback functions:
start
function is called when the space is ready. It includes 2 parameters: bound
which returns the bounding box, and space
which returns its space.animate
function is called continuously when the space plays. It includes 2 parameters: time
which gives the current running time, and ftime
which gives the time taken to draw the previous frame.
action
function is called when an user event is detected. It includes 4 parameters: type
is a string that returns the action's name. ("up", "down", "move", "drag", "drop", "over", and "out"). x
and y
returns the position at which the action happened, and event
returns the actual event object. See also: bindMouse
resize
function is called when the space is resized. It includes 2 parameter: size
which returns the new size, and event which returns the event object. You'll also need to add {resize: true}
in setup
to enable tracking.
You may add multiple players into a space, each taking care of specific parts of a scene. Use add
and remove
to manage a space's players.
You can tell a space to play or stop its players using play
, stop
and other functions:
space.play();
space.playOnce( 1000 ); // play 1 sec then stop
space.pause();
space.resume();
space.stop();
Using bindMouse
and bindTouch
, you can easily make the space respond to user interactions. Once the space can receive mouse or touch events, you can track the events using a player's action
callback function, as described above.
// You can chain multiple functions together
space.bindMouse().bindTouch().play();
CanvasSpace also provides a couple convenient properties which you may access once the space is initiated. .pointer
gives you the current pointer position. .size
, .center
, .width
, .height
and .innerBound
are handy to get a space's size and center point. .element
and .parent
returns the html elements of this space.
CanvasSpace also supports offscreen rendering which may help with rendering complex scene. Take a look at the source code of this study for more.
In the Get Started guide, we made an analogy of paper and pencil when introducing Space and Form. So CanvasForm
represents a pencil to draw on CanvasSpace. You can get the form with a single function call.
let space = new CanvasSpace("#paper");
let form = space.getForm(); // get default CanvasForm
CanvasForm
includes many convenient functions to draw shapes on <canvas>
element. Usually, you'll use these drawing functions in a player's animate
function like this:
// Draw points inside the animate callback function
space.add( (time, ftime) => {
form.stroke("#fff").fill("#f03").circle( c );
form.point( p, 10 );
} );
If you need more advanced canvas functions, you can get canvas' rendering context by accessing ctx
property. For example: form.ctx.clip()
.
And since both Space and Form are javascript classes, you can extend them to override its functions and add new ones.
You can easily switch you code from CanvasSpace
to SVGSpace
in 3 easy steps:
First, initiate space as SVGSpace
instead of CanvasSpace
. If you use space.getForm()
, then it will return an SVGForm
instead of CanvasForm
automatically.
Second, in the beginning of your animate callback function, add this line:
form.scope( this );
This keeps track of the created svg or dom elements to optimize rendering.
Lastly, if you use es6 arrow function in a player's callback functions, for example:
animate: (time, ftime) => ...
You should change it back to the standard form:
animate: function( time, ftime) ...
The arrow function automatically binds this
and will confuse the form.scope(this)
call.
Take a look at the source code of the svg demo. It's pretty straightforward.
There's also experimental support for rendering HTML elements using HTMLSpace
, which you can use by making similar changes in your code as described in SVG section above.
Take a look at the html demo and its source code. Because of the limitations of HTML, you cannot draw polygon, arc, and some other shapes with it.
If you use Pts with React or other web rendering frameworks, it will be better to use the props and states of their virtual DOM implementations instead.
The quickest way to start is to use the quickStart
function, which initiates a CanvasSpace
and adds space
and form
instances into current scope. You can create an interactive piece in 2 lines of code:
Pts.namespace( this ); // not needed if using npm package
let run = Pts.quickStart( "elemID", "#f03" )
run( (time, ftime) => form.fill("#f03").point( space.pointer, 10, "circle" ) );
The following snippet is a typical template for creating a Pts space and form. Use this if you need more than an animation loop. You can add either an animation function or an IPlayer
object to a space. (See above for details)
Pts.namespace( this ); // not needed if using npm package
var space = new CanvasSpace("elemID").setup({ retina: true });
var form = space.getForm();
space.add( (time, ftime) => {
form.fill("#f03").point( space.pointer, 10, "circle" );
} );
space.bindMouse().bindTouch().play();