Sg2.9
Creating Mouse Tools
Index RSS

This tutorial explains the different ways to create Scriptographer tools that the user can interact with by using the mouse.

My First Mouse Tool

We start with an example of a very simple tool that creates an empty path on execution and adds segments to it whenever you click the mouse:

// Create a new path once, when the script is executed:
var myPath = new Path();

// This function is called whenever the user
// clicks the mouse in the document:
function onMouseDown(event) {
	// Add a segment to the path at the position of the mouse:
	myPath.add(event.point);
}

Mouse Handler Functions

Scriptographer offers mouse handlers for the different actions you can perform with a mouse. You can use these mouse handlers to produce different types of tools that have different ways of reacting to mouse interaction and movement.

Please note:

In JavaScript, functions are blocks of code that are only executed when they are called from another part of the script. Handler functions are functions that are called by Scriptographer when a certain event happens.

To see when the different handler functions are called, copy-paste the following code into a new JavaScript file, execute it and interact with the Scriptographer tool:

function onMouseDown(event) {
	console.log('You pressed the mouse!');
}

function onMouseDrag(event) {
	console.log('You dragged the mouse!');
}

function onMouseUp(event) {
	console.log('You released the mouse!');
}
Please note:

To find out how to execute tool scripts and interact with the Scriptographer tool button, please read the Executing Scripts tutorial.

The Event Object

The mouse handler functions receive an event object which contains information about the mouse event, such as the current position of the mouse (event.point), the position where the mouse was pressed (event.downPoint), the pressure of the mouse event (event.pressure) etc.

Did you know?

The properties of the event object are explained in detail in the Mouse Tool Events tutorial.

Line Tool Example

Here is a simple tool that mimics the behaviour of the Line Segment Tool of Adobe Illustrator:

function onMouseUp(event) {
	var myPath = new Path();
	myPath.add(event.downPoint);
	myPath.add(event.point);
}

When the mouse is released, the onMouseUp(event) handler is called.

In the onMouseUp handler we create a new path:

	var myPath = new Path();

Then we add two segments to it using the path.add(segment) function.

First, we add a segment at event.downPoint, which is the position where the mouse button was pressed:

	myPath.add(event.downPoint);

Then, we add a segment at event.point, which is the position where the mouse button was released:

	myPath.add(event.point);

Click, Drag and Release Example

As a next step, we are going to make a small drawing tool:

When you click the mouse it will make a new Path.
When you drag the mouse it will add segments to the path.
When you release the mouse it will add a circle shaped path at that position with a radius of 5.

var myPath;

function onMouseDown(event) {
	myPath = new Path();
}

function onMouseDrag(event) {
	myPath.add(event.point);
}

function onMouseUp(event) {
	var myCircle = new Path.Circle(event.point, 5);
}

Now lets go through the script line by line to see whats happening:

To be able to access the myPath variable from both mouse handlers we declare it outside of the onMouseDown and onMouseDrag handlers:

var myPath;

In the onMouseDown handler we create a new path and store it in the myPath variable:

function onMouseDown(event) {
	myPath = new Path();
}

In the onMouseDrag handler we add event.point (the position of the mouse) to myPath every time the user drags the mouse:

function onMouseDrag(event) {
	myPath.add(event.point);
}

In the onMouseUp handler we create a circle shaped path with its center point at the position of the mouse when it was released and a radius of 5:

function onMouseUp(event) {
	var myCircle = new Path.Circle(event.point, 5);
}

Using the Distance that the Mouse has Moved

Another handy property in the event object is event.delta which describes the difference between the current position and the last position of the mouse when the event was fired. So in an onMouseUp handler, event.delta would describe the difference between the position where the mouse was clicked and the position where the mouse was released.

For example, if we would like to mimic Illustrator's circle path tool, we could write the following code:

function onMouseUp(event) {
	var myRadius = event.delta.length;
	var myCircle = new Path.Circle(event.downPoint, myRadius);
}

This small script creates a circular path whenever you click, drag and release. It uses the position where the mouse was clicked (event.downPoint) for the center point of the circle, and the distance between the down point and the position where the mouse was released (the length of event.delta) for its radius.

Minimum Distance

Normally while dragging, the onMouseDrag handler is called as often as possible, no matter how far the mouse has dragged. We can set the minimum distance the mouse has to drag before firing the onMouseDrag event by setting the tool.minDistance property.

For example, in the following tool script the onMouseDrag function is only called when the mouse has moved more than 50 points:

tool.minDistance = 50;

function onMouseDrag(event) {
	var radius = event.delta.length / 2;
	new Path.Circle(event.middlePoint, radius);
}

Maximum Distance

We can also set the maximum distance until the firing of the next onMouseDrag event by setting the tool.maxDistance property. This will repeatedly fire the onMouseDrag event until the distance between the event point and the mouse is less than tool.maxDistance.

In the following code we set tool.maxDistance to be 5 pt. Therefore, if the user were to drag the mouse by 50 pt, it would call the onMouseDrag handler 10 times.

tool.maxDistance = 5;

function onMouseDrag(event) {
	var radius = event.delta.length / 2;
	new Path.Circle(event.middlePoint, radius);
}

Fixed Distance Drag Events

To set both the minimum and maximum distances we can set the tool.fixedDistance property. Then onMouseDrag events are fired with intervals of fixed distances.

tool.fixedDistance = 5;

function onMouseDrag(event) {
	var radius = event.delta.length / 2;
	new Path.Circle(event.middlePoint, radius);
}

Event Interval

Normally the onMouseDrag handler is only fired when you actually drag the mouse. Scriptographer can also repeatedly call the onMouseDrag with a fixed time delay after the user clicks the mouse. Setting the tool.eventInterval property to an interval means the onMouseDrag event is called repeatedly after the initial onMouseDown until the user releases the mouse:

The following example creates a path when the user clicks and then adds a segment every 30 ms at 1/30th of the distance between the last point of the path and the current mouse position:

// Call the onMouseDrag function every 30 ms:
tool.eventInterval = 30;

var path;
function onMouseDown(event) {
	// Create a new path and add the first segment where
	// the user clicked:
	path = new Path();
	path.add(event.point);
}

function onMouseDrag(event) {
	var lastPoint = path.segments.last.point;

	// the difference between the current position of the mouse
	// and the last segment point of the path:
	var vector = event.point - lastPoint;
	
	// the position of the new point that we will add to the path:
	var point = lastPoint + vector / 30;
	path.add(point);
}