How to Make SVG Interactive with JavaScript
In this chapter, we cover a lightbulb that we can toggle on and off and an adjustable lamp that we can drag with the mouse. In both cases, we assign event listeners to SVG elements to make them interactive.
Example 1: Toggling the Lights
Let’s start with an easy example. By clicking the lightbulb, we switch the lights on or off. For this example, let’s reuse the lightbulb example from the arc lesson. Here’s its final source code. This chapter focuses on the interaction, so if you need to refresh your knowledge of how this icon is created, check back to the arc chapter.
How to Draw an Arc with SVGThe only difference in the example above is that the first path element now has an id
. We use this id to access the element in JavaScript.
Then, in JavaScript, we can assign an event handler to this element and toggle its fill color. We keep track of whether the light is on or off with the lightOn
variable, and based on this, we set the fill
property to gold or transparent.
In CSS we can add a cursor pointer to the bulb to indicate that it’s clickable.
Toggling the Light in React
We can do the same logic with a React component. We can create a new lightOn
state and set the fill property of the first path element based on this state. Then, we can also toggle this with the toggleLight
event handler bound to the same path element.
When using React, we need to convert some property names to camelCase. For
example, we use strokeWidth
instead of stroke-width
and strokeLinejoin
instead of stroke-linejoin
.
Example 2: Adjusting the Lamp
Now, let’s cover a more complex example. You can adjust the lamp by dragging its head. You can adjust the lamp’s height by dragging its head vertically and tilt it by dragging it horizontally.
How to Transform SVG ElementsFor this example, we reuse the lamp we created in a previous chapter. Here’s the source code that we ended up with. This one is a complex SVG that uses transformations to position its elements. Revisit the Transform chapter for a refresher.
The only difference in the example above is that some group elements now have an id
. We use these ids to access these groups in JavaScript.
This SVG is constructed in a way that allows us to tilt the arms of the lamp by simply adjusting some rotation values. You can see above that the first arm rotates 25°
to the left, the second arm turns 50°
to the right, and the third arm that connects the head tilts by 45°
to the right again.
These are the rotation values we need to change while dragging the head of the lamp. That’s why each of these groups has an id (arm1
, arm2
, arm3
). We get these groups by id in JavaScript.
Let’s say the second arm always balances out the first arm. If the first arm turns 25° to the left, the second one will turn 50° to the right. It’s always double the first rotation in the other direction.
So, in the code, we only need to keep track of two rotation values — the rotation of the first and third arms. Let’s call these values arm1Rotation
and arm3Rotation
. Let’s initialize these variables in JavaScript with values matching the rotations defined in SVG.
Then, we implement a simple drag-and-drop by adding the mousedown
event listener to the head of the lamp and a mousemove
and mouseup
event listener to the document.
We keep track if the mouse is dragging the head with the isDragging
variable. In the case of dragging, we calculate the horizontal and vertical movement of the mouse.
From dx
and dy
we calculate the new rotation of the first and the third arm. We change the rotation of arm one based on the vertical movement and the rotation of arm three based on the horizontal movement. We also limit the range of these rotations. Arm one can tilt between -60° and 0, while arm three can tilt between -90° and 90°.
We set these groups’ transform
attributes at each step with a new rotation value. Then, once the mouse button is released, we update the arm1Rotation
and arm3Rotation
to have the current state of the lamp.
As a finishing touch, we can change the cursor on the head element to drag to indicate that we can adjust the lamp.
We saw how we can manipulate SVG with JavaScript. The possibilities are endless. You can create infographics, charts, editors, or even a full-featured game with SVG and JavaScript.