Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canvas disappears when updating style prop of its parent View element #2976

Open
1 task done
thisisgit opened this issue Feb 25, 2025 · 1 comment
Open
1 task done
Labels
bug Something isn't working

Comments

@thisisgit
Copy link

Description

Hi I recently bumped into this issue after updating my app from expo SDK 51 -> 52 & enabling new arch.
This issue comes from enabling new architecture since I can confirm that it doesn't show when new arch is disabled.

Please check this video first:

Simulator.Screen.Recording.-.iPhone.16.-.2025-02-25.at.15.20.59.mp4

You can see there're 3 rings drawn with skia and each being wrapped in a View/Animated.View together with Text component.
What each wrapper element does is to apply opacity to 1/0.4 to both ring & text when it's selected/de-selected.
The first and second rings are wrapped with View and the third is wrapped with Animated.View(reanimated).

They are properly rendered on init. But once I press on that "Change" button to change selected state to next element, the first&second ring disappears. Canvas elements are disappeared but Text elements are rendered correctly as they get their parent's opacity.
The third one in the other hand, is rendered as expected. It's wrapped with Animated.View and its style prop is from useAnimatedStyle, which differs from the other 2 as they are View elements using ViewStyle objects.

I'll paste reproducible code below.

React Native Skia Version

Expo go: 1.5.0 / Expo dev build: 1.11.8

React Native Version

0.76.7

Using New Architecture

  • Enabled

Steps to Reproduce

Copy below reproducible code and run.

Snack, Code Example, Screenshot, or Link to Repository

Ring component:

import { Canvas, Circle, Group } from '@shopify/react-native-skia';
import React, { ReactElement } from 'react';
import { StyleSheet } from 'react-native';

const SIZE = 64;
const RADIUS = SIZE / 2;
const DEFAULT_STROKE_WIDTH = 12;
const r = RADIUS - DEFAULT_STROKE_WIDTH / 2;

export const SampleRing = (): ReactElement => {
  return (
    <Canvas style={styles.canvas}>
      <Circle cx={RADIUS} cy={RADIUS} r={r} color={'#FFFFFF'} />
      <Group
        style={'stroke'}
        strokeCap={'round'}
        strokeWidth={DEFAULT_STROKE_WIDTH}
      >
        <Circle cx={RADIUS} cy={RADIUS} r={r} color={'#DEDEDE'} />
      </Group>
    </Canvas>
  );
};

const styles = StyleSheet.create({
  canvas: {
    width: SIZE,
    height: SIZE,
  },
});

Screen:

import { Button, StyleSheet, View, ViewStyle, Text } from 'react-native';

import { SampleRing } from '@/components/SampleRing';
import { useMemo, useState } from 'react';
import Animated, { useAnimatedStyle } from 'react-native-reanimated';

export default function HomeScreen() {
  const [selectedRing, setSelectedRing] = useState<0 | 1 | 2>(0);

  const testStyle = useMemo<ViewStyle>(() => {
    return {
      opacity: selectedRing === 0 ? 1 : 0.4,
      alignItems: 'center',
    };
  }, [selectedRing]);

  const testStyle2: ViewStyle = {
    opacity: selectedRing === 1 ? 1 : 0.4,
    alignItems: 'center',
  };

  const testStyle3 = useAnimatedStyle<ViewStyle>(() => {
    return {
      opacity: selectedRing === 2 ? 1 : 0.4,
      alignItems: 'center',
    };
  });

  function handlePress() {
    setSelectedRing((prev) => {
      if (prev === 0) {
        return 1;
      } else if (prev === 1) {
        return 2;
      } else {
        return 0;
      }
    });
  }

  return (
    <View style={styles.container}>
      <View style={styles.ringWrapper}>
        <View style={testStyle}>
          <SampleRing />
          <Text>First</Text>
        </View>
        <View style={testStyle2}>
          <SampleRing />
          <Text>Second</Text>
        </View>
        <Animated.View style={testStyle3}>
          <SampleRing />
          <Text>Third</Text>
        </Animated.View>
      </View>
      <Button title={'Change'} onPress={handlePress} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    paddingTop: 80,
    paddingHorizontal: 24,
  },
  ringWrapper: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 24,
  },
});
@thisisgit thisisgit added the bug Something isn't working label Feb 25, 2025
@MrHazimAli
Copy link

Im facing the same issue as well. still looking and debugging on whats causing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants