All Projects → pmndrs → React Three A11y

pmndrs / React Three A11y

Licence: other
♿️ Accessibility tools for React Three Fiber

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to React Three A11y

Aframe
🅰️ web framework for building virtual reality experiences.
Stars: ✭ 13,428 (+5841.59%)
Mutual labels:  threejs
Forgejs
ForgeJS is a javascript framework that unleashes immersive WebVR experiences.
Stars: ✭ 207 (-8.41%)
Mutual labels:  threejs
Three Seed
A Three.js starter project with ES6 and Webpack
Stars: ✭ 213 (-5.75%)
Mutual labels:  threejs
React Three Next
React Three Fiber, Nextjs, Tailwind starter
Stars: ✭ 195 (-13.72%)
Mutual labels:  threejs
Magicshader
🔮 Tiny helper for three.js to debug and write shaders
Stars: ✭ 205 (-9.29%)
Mutual labels:  threejs
Hdri To Cubemap
Image converter from spherical map to cubemap
Stars: ✭ 207 (-8.41%)
Mutual labels:  threejs
Ar.js
Image tracking, Location Based AR, Marker tracking. All on the Web.
Stars: ✭ 3,048 (+1248.67%)
Mutual labels:  threejs
Xplan
A rotating earth H5 page with Vue and threejs
Stars: ✭ 226 (+0%)
Mutual labels:  threejs
Three.interaction.js
three.js interaction toolkit, help you built an interaction event-system for three.js, binding interaction event like browser-dom
Stars: ✭ 206 (-8.85%)
Mutual labels:  threejs
Ifc.js
Ifc viewer for client applications.
Stars: ✭ 211 (-6.64%)
Mutual labels:  threejs
Droneworld
droneWorld: a 3D world map and a three.js playground
Stars: ✭ 197 (-12.83%)
Mutual labels:  threejs
Demos
One repo to rule them all.
Stars: ✭ 204 (-9.73%)
Mutual labels:  threejs
Blueprint Js
The Javascript es6 version of the original furnishup/blueprint3d. Need some royalty free low poly models for the inventory. Can someone help me with this?
Stars: ✭ 208 (-7.96%)
Mutual labels:  threejs
Three Nebula
WebGL based particle system engine for three.js
Stars: ✭ 192 (-15.04%)
Mutual labels:  threejs
Three Text2d
Render texture from canvas into THREE's Mesh or Sprite.
Stars: ✭ 223 (-1.33%)
Mutual labels:  threejs
Robot Gui
A three.js based 3D robot interface.
Stars: ✭ 181 (-19.91%)
Mutual labels:  threejs
Pathfinding Visualizer Threejs
A visualizer for pathfinding algorithms in 3D with maze generation, first-person view and device camera input.
Stars: ✭ 209 (-7.52%)
Mutual labels:  threejs
Terrain Builder
🏔 Procedural terrain using Three.js and perlin noise, Now Accelerated by your GPU!
Stars: ✭ 228 (+0.88%)
Mutual labels:  threejs
Maptalks.three
A maptalks Layer to render with THREE.js.
Stars: ✭ 226 (+0%)
Mutual labels:  threejs
Three.vrcontroller
Support hand controllers for Oculus, Vive, Windows Mixed Reality, Daydream, GearVR, and more by adding VRController to your existing Three.js-based WebVR project.
Stars: ✭ 213 (-5.75%)
Mutual labels:  threejs

@react-three/a11y

Version Downloads Discord Shield

Imgur

npm install @react-three/a11y

@react-three/a11y brings accessibility to webGL with easy-to-use react-three-fiber components:

  • Focus and focus indication
  • Tab index and keyboard navigation
  • Screen reader support and alt-text
  • Roles and cursor shapes
  • Descriptive links

Live demo: https://n4rzi.csb.app

How to use

First, place the A11yAnnouncer component next to the R3F Canvas component. This is critical, because it will manage the screen-reader and help emulate focus!

import { Canvas } from 'react-three-fiber'
import { A11yAnnouncer } from '@react-three/a11y'

function App() {
  return (
    <>
      <Canvas />
      <A11yAnnouncer />
    </>
  )
}

To add accessibility features to your scene you'll have to wrap components you want to make focusable with the A11y component:

import { A11y } from '@react-three/a11y'

<A11y>
  <MyComponent />
</A11y>

MyComponent can now receive focus. More accurately, the emulated "focus" will handled at the A11y components which acts as a provider for children to access its state. But even if objects are focusable, nothing will be displayed or shown by default.

Accessing the hover, focused & pressed state

For each child wrapped in the A11y component, you can access the focus, hover and pressed state like so:

import { useA11y } from '@react-three/a11y'

function Box(props) {
  const a11y = useA11y()
  return (
    <mesh {...props}>
      <boxBufferGeometry />
      <meshStandardMaterial color={a11y.hover || a11y.focus ? 'hotpink' : 'orange'} />
    </mesh>
  )
}

Call function on focus

The focusCall prop of A11y will be called each time this component receives focus (usually through tab navigation).

<A11y role="content" focusCall={()=> console.log("in focus")} ... />

Call function on click / keyboard Click

The actionCall prop of A11y will be called each time this component gets clicked, focused, keyboard activated etc.

<A11y role="button" actionCall={()=> console.log("clicked")} ... />

Provide a description of the currently focused / hovered element

When using the description prop, the A11y component will provide a description to the screen reader users on focus/hover. Optionally, you can also show the description to the user on hover by setting showAltText={true}.

// Reads "A rotating red square" to screen readers on focus / hover
<A11y role="content" description="A rotating red square" ... />
// Reads "A bouncing blue sphere" to screen readers on focus / hover while also showing it on mouseover
<A11y role="content" description="A bouncing blue sphere" showAltText ... />

If your A11y component has the role="button", you can use three more props:

  • activationMsg: When the user will click/activate the "button" the screen reader will read the passed message
  • deactivationMsg: When set, it turns your button in a togglable button. Which means it now has a on/off state. Screen readers will read the state of the button as well as the activation/disactivation messages passsed.
  • pressedDescription: When set, it turns your button in a togglable button. Which means it now has a on/off state. This description will replace the one passed via description when the toggle is active.
// Reads the description on hover/focus then will read activationMsg if clicked/pressed
<A11y role="button" description="Sends a thank you email to the team" activationMsg="Email is sending" ... />
// Reads the description on hover/focus then will read activationMsg if turned on or deactivationMsg if tuned off
<A11y
  role="button"
  description="This button can enable dark theme. Dark theme is off"
  pressedDescription="This button can disable dark theme. Dark theme is on"
  activationMsg="Dark theme enabled"
  deactivationMsg="Dark theme disabled" ... />

The three roles of the A11y component

Like in HTML, you can focus different kind of elements and expect different things depending on what you're focusing.

Content

<A11y role="content" ... />

Uses the default cursor. This role is meant to provide information to screen readers or to serve as a step for a user to navigate your site using Tab for instance. It's not meant to trigger anything on click or to be activable with the Keyboard. Therefore it won't show a pointer cursor on hover.

Buttons

<A11y
  role="button"
  activationMsg="Button activated"
  deactivationMsg="Button deactivated"
  pressedDescription="Button pressed" ... />

Uses the pointer cursor. Special attributes: activationMsg, deactivationMsg and pressedDescription.

This role is meant to emulate the behaviour of a button or a togglable button. It will display a cursor pointer when your cursor is over the linked 3D object. It will call a function on click but also on any kind of action that would trigger a focused button (Enter, Double-Tap, ...). It is also actionnable by user using a screen reader.

You can turn it into a button with aria-pressed by using the role togglebutton, you'll then be able to use the following propertie deactivationMsg in addition to the usual description and activationMsg properties.

Links

<A11y role="link" href="https://url.com" ... />

Uses the pointer cursor. Special attributes: href.

This role is meant to emulate the behaviour of a regular html link. It should be used in combination with something that will trigger navigation on click.

- Don't forget to provide the href attribute as he is required for screen readers to read it correctly !
- It will have no effect on the navigation, it's just used as information

Screen Reader Support

In order to provide informations to screen reader users and use this package at its full potential, fill the description prop of all your A11y components and use the appropriate role prop on each of them.

Use of section

For screen readears, it might be useful to provide additionnal information on how to use some unconventional UI. You can do it by wrapping the concerned part of your code relative to this UI in the A11ySection like so.

<A11ySection
            label="Shape carousel"
            description="This carousel contains 5 shapes. Use the Previous and Next buttons to cycle through all the shapes.">
           [...]
</A11ySection>

Access user preferences

The A11yUserPreferences component i available in order to access user preferences such as

  • prefers-reduced-motion
  • prefers-color-scheme

Take a look at the wiki section or the demo to see it in action and how to use it. The demo will adapt to your system preferences.

Additionals Features

Use a custom tabindex with for your A11y components by providing a number to the tabIndex attribute

<A11y tabIndex={-1} ... />

⚠⚠⚠
Avoid using tabindex values greater than 0. Doing so makes it difficult for people who rely on assistive technology to navigate and operate page content. Instead, write the document with the elements in a logical sequence.
More about the use of tabIndex on developer.mozilla.org

Next Steps

  • [ ] Provide a documentation inside the IDE
  • [ ] Provide more examples showing how to use it

Author:

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].