Virtual Joystick Custom Element | Web Component | HTML Element | Vanilla Javascript
Virtual Joystick is a simple, reusable custom web element for touch-enabled user interfaces. Its functionality is strongly encapsulated, separate from the rest of the code.
- Very light weight (less than 4kb minified).
- Perfect for mobile game development
- Uses default JavaScript APIs, no dependencies.
- Configurable and extendable.
- Library-agnostic, which means it can be added to any JavaScript project regardless of the framework or library being used.
Import it the way you want into your project :
// CommonJS
const manager = require('virtual-joystick');
// Module
import 'virtual-joystick';
<!-- Classic script -->
<script src="./virtual-joystick.js"></script>
<!-- Module script -->
<script type="module" src="./virtual-joystick.js">
<virtual-joystick></virtual-joystick>
Check out the demo here.
<virtual-joystick data-mode="fixed"></virtual-joystick>
Check out the demo here.
<virtual-joystick data-mode="semi"></virtual-joystick>
Check out the demo here.
<virtual-joystick data-mode="dynamic"></virtual-joystick>
Check out the demo here.
<virtual-joystick data-lock="y"></virtual-joystick>
Check out the demo here.
<virtual-joystick data-shape="box"></virtual-joystick>
virtual-joystick::part(joystick),
virtual-joystick::part(joystick):before,
virtual-joystick::part(joystick):after {
border-radius: 0;
}
Check out the demo here.
<virtual-joystick></virtual-joystick>
virtual-joystick::part(joystick),
virtual-joystick::part(joystick):before,
virtual-joystick::part(joystick):after {
border-radius: 14px;
}
virtual-joystick::part(joystick):after {
transition-timing-function: cubic-bezier(.17, .67, .52, 1.48);
}
Check out the demo here.
<virtual-joystick></virtual-joystick>
virtual-joystick::part(joystick) {
background-color: rgba(31, 223, 108, 0.4);
}
virtual-joystick::part(joystick):after {
background-color: rgba(31, 223, 108, 0.6);
}
virtual-joystick::part(joystick),
virtual-joystick::part(joystick):before,
virtual-joystick::part(joystick):after {
border: 0;
}
Check out the demo here.
<virtual-joystick>
<div>...</div>
</virtual-joystick>
Check out the demo here.
<virtual-joystick></virtual-joystick>
virtual-joystick {
--radius: 60px;
}
virtual-joystick::part(joystick),
virtual-joystick::part(joystick):before,
virtual-joystick::part(joystick):after {
background-color: transparent;
border: 7px solid #673ab7;
}
Check out the demo here.
The data-* attribute is used to apply custom data options to the component, allowing us to configure the joystick component in different ways:
This determines the strength needed to trigger a directional event. It measures the distance between the center of the component and the focal point. The 'threshold' value ranges from 0.0 to 1.0.
Four modes are possible :
- the joystick element is positioned in the normal flow of the document.
- each new touch triggers a new direction.
- cannot be multitouch.
- the joystick element is positioned in the normal flow of the document.
- allows the joystick to be activated by touch outside of the joystick area.
- can be multitouch.
- the joystick is repositioned on every touch event.
- cannot be multitouch.
- the joystick is repositioned on every touch event.
- the component is faded out when released but not destroyed.
- can be multitouch.
This option locks the joystick's movement to either the X (horizontal) or Y (vertical) axis.
This determines the shape of the region within which the joystick can move. 'circle'
creates a circular region for joystick movement, while 'box' creates a square region.
Events are fired to notify the code of "interesting changes" that may affect code execution. These events arise from user interactions with the joystick component. Event handlers can be used to handle and verify user input and actions:
const $joystick = document.querySelector('virtual-joystick');
const handleKeyEvents = () => {
$joystick.dataset.release.split('').forEach(()=>{});
$joystick.dataset.capture.split('').forEach(()=>{});
};
$joystick.addEventListener('joystickdown', handleKeyEvents);
$joystick.addEventListener('joystickmove', handleKeyEvents);
$joystick.addEventListener('joystickup', handleKeyEvents);
The 'joystickdown' event is fired when the virtual joystick is pressed while the pointer is located within the specified area.
The 'joystickmove' event is fired when the pointer's coordinates change, and the pointer has not been canceled by a browser touch-action.
The 'joystickup' event is fired when the virtual joystick is released while the pointer is located within the specified area. This event is the counterpart to the 'joystickdown' event.
Various 'data-*' output attributes are used to represent the results of calculations performed by the component. Continuous output monitoring can be achieved through different methods:
const $joystick = document.querySelector('virtual-joystick');
const log = () => $joystick.dataset.direction;
requestAnimationFrame(log);
setInterval(log, 1000);
This represents the counter-clockwise angle measured in degrees from the positive X-axis *.
This represents the counter-clockwise angle measured in radians from the positive X-axis *.
* The rotation angle is measured in both radians and degrees counterclockwise from horizontal, and measures the rotation of the primary axis from horizontal.
This matches one of the eight principal winds, which include the four cardinal directions (N, E, S, W) and the four "intercardinal" or "ordinal directions" (NE, SE, SW, NW), at 45ยฐ intervals. The four cardinal directions (N, S, E, W) are the main compass directions. Relative to the north, the east, south, and west directions are at 90ยฐ intervals in the clockwise direction. The ordinal directions (also called intercardinal directions) are northeast (NE), southeast (SE), southwest (SW), and northwest (NW).
This attribute value represents one of the eight points of the compass rose with ordinal and cardinal directions: N, NE, E, SE, S, SW, W, and NW. It indicates which point transitions from an active to an inactive state.
This attribute value represents one of the eight points of the compass rose with ordinal and cardinal directions: N, NE, E, SE, S, SW, W, and NW. It indicates which point transitions from an inactive to an active state.
This is a float that represents the distance between the center and a vertex. The value is between 0.0 and 1.0 when inside and above 1.0 when outside.
This is an integer that represents the distance between the center of the component and the focal point. The distance is measured only within the component in pixels.
This is an integer that represents the distance between the center of the component and the focal point. The distance is measured only within the specified area in pixels. It matches the 'data-distance' value when the pointer is inside the joystick area.
This is a float that represents the horizontal coordinate within the application's viewport at which the virtual joystick event occurred.
This is a float that represents the vertical coordinate within the application's viewport at which the virtual joystick event occurred.