I'm currently building a website with help of React and docusaurus, and there I want to have a svg image (located in static/astronaut-light.svg) that switches color as soon as I poke it.
The problem is that the onClick/onMouseEnter event gets triggered on the transparent parts too,
which isn't a preferred behavior. (See video)
-> It should only switch its color if I click happens on a non transparent part.
Youtube Video: https://youtu.be/tZ2UfWE1Aw4
Website: https://agile-ts.org/
SourceCode: https://github.com/agile-ts/documentation/blob/develop/src/_pages/LandingPage/components/HeaderView/components/Astronaut/index.tsx
I tried to solve this problem by checking if the pixel is transparent or not.. but I couldn't get it to work. (See code below)
const imageRef = useRef<HTMLImageElement>(null);
const ctx = document.createElement('canvas').getContext('2d');
// https://medium.com/@pdx.lucasm/canvas-with-react-js-32e133c05258
// https://stackoverflow.com/questions/38487569/click-through-png-image-only-if-clicked-coordinate-is-transparent
const trigger = (event: React.MouseEvent<HTMLImageElement, MouseEvent>) => {
// Get click coordinates
const x = event.pageX - imageRef.current.offsetLeft;
const y = event.pageY - imageRef.current.offsetTop;
const w = (ctx.canvas.width = imageRef.current.width);
const h = (ctx.canvas.height = imageRef.current.height);
// Draw image to canvas
// and read Alpha channel value
ctx.drawImage(imageRef.current, 0, 0, w, h);
const alpha = ctx.getImageData(x, y, 1, 1).data[3]; // [0]R [1]G [2]B [3]A
// If pixel is transparent,
// retrieve the element underneath and trigger it's click event
if (alpha === 0) {
console.log('alpha0');
imageRef.current.style.pointerEvents = 'none';
const element = document.elementFromPoint(event.clientX, event.clientY);
// element.trigger('click');
imageRef.current.style.pointerEvents = 'auto';
} else {
setIsRaised(true);
console.log('LOGO clicked!');
}
return (
<div className={clsx(styles.Container, className)}>
<animated.img
ref={imageRef}
onMouseEnter={trigger}
style={animated_Astronaut}
className={styles.Image}
src={`img/astronaut-${dark ? 'dark' : 'light'}.svg`}
alt={'Astronaut'}
/>
<div className={styles.Text}>Poke me to mutate my color State.</div>
</div>
);
Maybe you have an idea how to solve this problem.
Thank you :D