Getting Started With Paper.js: User Interaction

After reading the first two tutorials, you should be able to create paths and some basic predefined shapes. You should also be able to simplify or flatten your paths as well as draw them on different layers and blend them together. 

Even though we have come a long way, there is still one thing missing. Up to this point, there has been no interaction between our canvas and the user. It would be nice if we could give users the ability to interact with various paths or draw something on their own. This tutorial will cover all the basics of user interaction, starting with the tool variable.

Tool and ToolEvent

There is a global tool variable that only exists in scripts which contain handler functions to interact with either the mouse or the keyboard. This variable gives you access to properties like minDistance, which is the minimum distance after which the mouse can again fire the onMouseDrag event, since it was last fired. Similarly, the property maxDistance allows you to specify a maximum distance after which the onMouseDrag event needs to fire again.

Paper.js also has a ToolEvent object. It is an extension of the event object and the only parameter that is passed to all mouse event handlers. It contains all the relevant information about these mouse events like:

  • type, which tells you if the event is mouseup, mousedown, mousemove or mousedrag.
  • point, which gives you the position of the mouse when the event was fired.
  • delta, which gives you the distance between the current and last mouse position when the event was fired.
  • count, which gives you the number of times the mouse event was fired.
  • item, which gives you the item that was present at the location of the mouse event. If the item is part of a group or compound path then the topmost level of group or compound  path is returned.
  • lastPoint, which gives the position of the mouse when the event was last fired.
  • downPoint, which gives you the position of the mouse in project co-ordinates when it was last clicked.
  • middlePoint, which gives you the point in the middle of lastPoint and point

You should keep all of these in mind because they will be used frequently in most of your projects.

Mouse Interactions

Paper.js has various handler functions that are called automatically to handle different mouse events. The three mouse handler functions are listed below.

Let's create a basic demo based on the onMouseDown and onMouseUp handlers. Every time a user presses a mouse button, we will create a new Path and mark that point as the beginning of our Path

Every time the user releases the mouse button, we will add a new point as the end of our Path. This will create a straight line from the point where the mouse button was pressed to the point where it was released. Here is the code:

I have also set the strokeColor to purple and strokeWidth to one-tenth of the value of x co-ordinate using the event.point property. If you try to draw some vertical lines in the gray area below, you will notice that all of them have a width directly proportional to their distance from the left side.

Now, let's create some circles using the onMouseDrag event. Every time a drag event is fired, we will draw a circle with its center at the middle point of the last and current drag point. The radius of the circle will depend directly on the drag speed of the user. 

To locate the center of our circle, we can use the middlePoint property that we discussed in the previous section. To determine the radius of the circle, we can use the delta property and divide the result by 2. Here is the code that we need:

If the user were to drag the mouse too quickly or too slowly, the circles would become too big or too small. 

This issue can be resolved by using the maxDistance and minDistance properties. If the user drags too quickly, the maxDistance property will fire the drag event every 50 pixels. If the user's dragging speed is too slow, the minDistance property will not be fired until the minimum distance threshold that we specified has been reached. You can test the code above by dragging your mouse in the gray area below:

Keyboard Interactions

The event object has three properties that you can use for your interactions with the keyboard. The event.key property will tell you which key was pressed, and the event.character property will tell you the character that was generated on key press. To determine whether it was a keyup or keydown event, you can use the event.type property.

Let's use these properties together to create tiny circles and move them around. Take a look at the code below:

We create a variable step which will be used to determine the speed at which our circle moves around. The variable centerPoint stores the location of the center of our circles.  The onKeyDown handler has the code to handle all keydown events. This event is fired continuously as long as a key is being pressed. 

This is the reason that new circles are created continuously. Based on the key pressed, we change the value of centerPoint to move our newly created circle to a different location. You can see the code in action in the demo below:

Some keys, for instance the Shift key and Option key, don't directly produce a character when pressed. These keys are called modifier keys. The event object has an event.modifiers property which you can use to determine the modifier key which was pressed. Consider the code below:

Whenever a user presses a mouse button, the onMouseDown handler creates a new Path and adds a point to it. After you start dragging, the onMouseDrag handler adds a new point to it on every drag event. 

If you are dragging the mouse with the Shift key pressed, the handler detects it with the event.modifiers.shift property. In that case, instead of adding a new point on each drag event, it just sets the co-ordinates of the last segment to the current location of the mouse pointer. It also simplifies the complete path that was drawn. You can drag your mouse in the gray area below to see how the path behaves when the Shift key is pressed.

If the Shift key does not seem to work, that's probably because the canvas does not have focus. In that case, you should first click inside the little white space below the canvas to give it focus.

Final Thoughts

The event handlers that we discussed today cover the most common interactivity scenarios. As is evident from the tutorial, it is not hard to manipulate the items in a canvas based on a user's actions. The best way to learn is by practicing. So I would like to suggest that you create your own demos combining everything that you have learned in the three tutorials up to this point.

If you have any questions regarding this tutorial, please let me know in the comments.



Related Articles