react-native-skia
react-native-skia copied to clipboard
Canvas is not accessible for people with disabilities
Description
I can't use accessibility properties from React Native
I need to configure accessibility for the elements that are rendered over the Canvas, to make it accessible for visually impaired people who use VoiceOver and TalkBack. Such as accessibilityLabel
, accessibilityRole
and accessibilityHint
.
However accessibility properties are not supported on Canvas elements.
Documentation
https://reactnative.dev/docs/accessibility
For example:
import {Canvas, Circle, Group} from "@shopify/react-native-skia";
export const HelloWorld = () => {
const size = 256;
const r = size * 0.33;
return (
<Canvas style={{ flex: 1 }}>
<Group blendMode="multiply">
<Circle
cx={r}
cy={r}
r={r}
color="cyan"
accessibilityLabel="Sweets with blueberry"
accessibilityRole="button"
accessibilityHint="Go to product list"
/>
<Circle
cx={size - r}
cy={r}
r={r} color="magenta"
accessibilityLabel="Sweets with strawberry"
accessibilityRole="button"
accessibilityHint="Go to product list"
/>
<Circle
cx={size/2}
cy={size - r}
r={r}
color="yellow"
accessibilityLabel="Sweets with lemon"
accessibilityRole="button"
accessibilityHint="Go to product list"
/>
</Group>
</Canvas>
);
};
Version
0.1.196
Steps to reproduce
Try implementing accessibility properties on any Canvas element.
Snack, code example, screenshot, or link to a repository
Hi @GabrieleSuzart - thanks for submitting the issue! It should be possible to add accessibility information to the Canvas - but it will not be possible to add it for the components inside the Canvas.
The reason for this is that components in a Canvas are not real components in the sense that they have a corresponding Android or iOS view backing it. Those components are just a declarative description of the low level drawing operations that React Native Skia will use for rendering a 2D drawing using the GPU.
Due to the possible complex rendering operations it is really hard for us to know the bounding path of the Skia elements - they can be transformed, clipped and combined in ways that makes it heavy to calculate the positions and returning the correct accessibility information when a user explores the rendered drawing.
What we've previously discussed is to suggest building an alternative representation of UX built with regular views and maybe even simplified (compared to the Skia drawing) that can be displayed on top of the Skia drawing when there is a screen reader active.
I'm pinging @colinta here since he has been involved with some of the discussions about this topic - maybe you want to add something here?
@GabrieleSuzart, did you try whether drawing elements in react-native-svg
have these accessibility properties?
They employ a different approach to express drawing elements through React components (they utilize shadow nodes: https://reactnative.dev/architecture/render-pipeline), while we use our own React renderer: https://github.com/chentsulin/awesome-react-renderer. I'm curious to know if accessibility properties are available there (the code/documentation seems to suggest so). Currently, the shadow node approach is not possible for us. However, this might change if the React Native architecture allows for creating shadow nodes directly in C++ (vs making a android + ios implementation for each node).
Hello! Thanks for the answer :)
The Path
and Svg
elements (import { Path, Svg } from 'react-native-svg';
) have accessibility properties, as SvgProps
extends
from ViewProps
.
However, ImageSVG
(import { ImageSVG } from '@shopify/react-native-skia';
) does not have accessibility properties.
Would it be possible to use svg from react-native-svg
within Canvas
or would some Skia element also receive SvgProps (or ViewProps) properties?
Hi, you can't use regular components within a Canvas since a Canvas can only contain Skia components (they're basically descriptions of drawing operations). You can however use accessibility props on the Canvas itself as it is a View that accepts these. So the model is:
Canvas -> View with view props Canvas.children -> Declarative drawing operations that are rendered using the GPU - does not have view props.
The differences compared to react-native-svg is that in RNSvg all nodes are essentially views that has view properties including accessibility props.
I'll close this one for now, please open a discussion if needed.
Could we reopen this issue and mark it as a feature request?
Agree
@GabrieleSuzart There is a solution that we use for integrating Gesture handler and Skia which consisting of overlaying native views over the canvas: https://github.com/Shopify/react-native-skia/blob/main/example/src/Examples/Stickers/Stickers.tsx#L27 (in the example you can see that each sticker is drawn on the canvas and has a corresponding native view on top of it).
Presumably the same technic could be used for accessibility.
If at some point the new React Native architecture allows for creating shadow nodes in C++, this is definitely something that we will consider.
:tada: This issue has been resolved in version 1.3.3 :tada:
The release is available on:
Your semantic-release bot :package::rocket: