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

Skia is not rendering anything on ios simulator when new arch is turned on #2636

Open
matinzd opened this issue Sep 16, 2024 · 9 comments
Open
Labels
bug Something isn't working

Comments

@matinzd
Copy link

matinzd commented Sep 16, 2024

Description

After turning on new archtitecture I am not able to render anything with Skia on iOS simulator

Old architecture and physical device:

Image
Image

New architecture:

Image

Image

Version

1.3.13

Steps to reproduce

  1. Install latest version of React Native 0.75.3
  2. Turn on new arch and build it on simulator and physical device
  3. Simulator version does not render anything while physical device works

Snack, code example, screenshot, or link to a repository

import { colors } from '@kreddy-frontend/shared-ui';
import { Canvas, Path, Skia, Text, useFont } from '@shopify/react-native-skia';
import { useEffect } from 'react';
import {
  cancelAnimation,
  useSharedValue,
  withTiming,
} from 'react-native-reanimated';

interface Props {
  data: number;
  radius?: number;
  strokeWidth?: number;
  strokeColor?: string;
  background?: string;
  duration?: number;
}

export const CircularGraphSkia = ({
  data = 90,
  radius = 24,
  strokeWidth = 3.5,
  strokeColor = colors.black_10,
  background = colors.black_60,
  duration = 1000,
}: Props) => {
  // it's ok to use require here because the font is a static asset
  // eslint-disable-next-line @typescript-eslint/no-var-requires
  const font = useFont(require('../assets/fonts/ReadexPro-Regular.ttf'), 12);

  const end = useSharedValue(0);

  useEffect(() => {
    end.value = withTiming(data / 100, { duration });

    return () => {
      cancelAnimation(end);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data]);

  const innerRadius = radius - strokeWidth / 2;

  const path = Skia.Path.Make();
  path.addCircle(radius, radius, innerRadius);

  if (!font) {
    return null;
  }

  const text = `${Math.trunc(data)}%`;

  const fontSize = font?.measureText(text);

  const textX = radius - fontSize.width / 2;

  return (
    <Canvas style={{ width: radius * 2, height: radius * 2 }}>
      <Path
        path={path}
        style={'stroke'}
        color={background}
        start={0}
        end={1}
        strokeWidth={strokeWidth}
        strokeJoin="round"
        strokeCap="round"
      />
      <Path
        path={path}
        style={'stroke'}
        color={strokeColor}
        start={0}
        end={end}
        strokeWidth={strokeWidth}
        strokeJoin="round"
        strokeCap="round"
        origin={{ x: radius, y: radius }}
        // Rotate the circle so that the progress starts from the PI/2 position
        transform={[{ rotate: -Math.PI / 2 }]}
      />
      <Text
        x={textX}
        y={radius + fontSize.height / 2}
        color={colors.black_10}
        text={text}
        font={font}
        origin={{ x: radius, y: radius }}
      />
    </Canvas>
  );
};
@matinzd matinzd added the bug Something isn't working label Sep 16, 2024
@AndreasJJ
Copy link

AndreasJJ commented Oct 1, 2024

I am having the same problem on skia 1.4.2, React Native 0.75.3, Expo 51.0.34 and victory-native 41.4.0. Just shows an empty area on iOS simulator, but works on my real device.

@alexvcasillas
Copy link

This is happening to me as well when running it on my real device, none of the Skia components are being rendered

@matinzd
Copy link
Author

matinzd commented Nov 1, 2024

Sorry for tagging you but this seems like a regression. Can you take a look at it?

@wcandillon

@wcandillon
Copy link
Contributor

I just had a look at it but I need a reproduction. A community explained me that another issue might be related to this one which led me to believe that I might not need a reproduction but it turned out to be unrelated. I hope we can get to the bottom of this quickly.

@wcandillon
Copy link
Contributor

The example you provided works for me so I probably need a small app as a reproduction or something.

@aleksey-golovanov
Copy link

I am having the same problem on skia 1.4.2, React Native 0.75.3, Expo 51.0.34 and victory-native 41.4.0. Just shows an empty area on iOS simulator, but works on my real device.

I had the exact same problem, and I tried to reproduce it on a new project, but I can't. Somehow it works, despite all the libraries being the same versions. An absolute beauty of React Native development.

So what I ended up doing is copy-pasting the code from the old project to the new one. The new one works, package.json is identical, the new architecture is turned on. I have no idea what was the reason.

"@shopify/react-native-skia": "^1.5.1",
"react-native": "^0.75.4",
"expo": "~51.0.28",

@matinzd
Copy link
Author

matinzd commented Nov 2, 2024

I would say it is also very random on my own project as well. Sometimes it shows up sometimes it doesn't. There might be something messing with rn skia from outside.

@padge
Copy link

padge commented Nov 17, 2024

I encountered this on the new arch – sometimes Skia components will render just fine, other times they won't. I haven't had time to try and reproduce on a new project yet.

@shopify/react-native-skia@1.5.3
expo@^52.0.0
react-native@0.76.2

@padge
Copy link

padge commented Nov 18, 2024

Alright I got a minimal example together reproducing the issue.

If I render the example from my other issue in two bottom tabs and navigate between them, the whole Skia canvas disappears.

// index.tsx
import { registerRootComponent } from "expo";
import React, { useEffect, useState } from "react";
import { NavigationContainer } from "@react-navigation/native";
import { Button, Dimensions, View } from "react-native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { Canvas, Group, Rect } from "@shopify/react-native-skia";
import {
  useDerivedValue,
  useSharedValue,
  withTiming,
} from "react-native-reanimated";

const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();

function AppNavigator() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Home" component={TabNavigator} />
    </Stack.Navigator>
  );
}

function TabNavigator() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Tab A" component={TestScreen} />
      <Tab.Screen name="Tab B" component={TestScreen} />
    </Tab.Navigator>
  );
}

const { width } = Dimensions.get("window");

function TestScreen() {
  const scale = useSharedValue(1);
  const [zoomed, setZoomed] = useState(false);

  useEffect(() => {
    scale.value = withTiming(zoomed ? 2 : 1, { duration: 500 });
  }, [zoomed, scale]);

  const transform = useDerivedValue(() => {
    return [{ scale: scale.value }];
  }, []);

  const n = 20;
  const size = width / n;

  return (
    <View style={{ flex: 1, justifyContent: "center" }}>
      <Button onPress={() => setZoomed((prev) => !prev)} title="Scale" />
      <Canvas style={{ width: width, height: width }}>
        <Group transform={transform}>
          {[...Array(n * n)].map((_, i) => {
            const x = (i % n) * size;
            const y = Math.floor(i / n) * size;
            const pos = { x, y, width: size, height: size };
            return <Rect key={i} {...pos} color={`hsl(${i}, 80%, 70%)`} />;
          })}
        </Group>
      </Canvas>
    </View>
  );
}

export default function App() {
  return (
    <View style={{ flex: 1 }}>
      <NavigationContainer>
        <AppNavigator />
      </NavigationContainer>
    </View>
  );
}

registerRootComponent(App);

package.json

"@react-navigation/bottom-tabs": "^6.5",
"@react-navigation/elements": "^1.3",
"@react-navigation/native": "^6.1",
"@react-navigation/native-stack": "^6.9",
"@shopify/react-native-skia": "1.5.1",
"expo": "^52.0.0",
"react": "18.3.1",
"react-native": "0.76.2",
"react-native-reanimated": "~3.16.1",

Edit: Hmm so I tested it on a new expo project in the simulator and it worked, so I downgraded @react-navigation and the issue appeared again. So I'll try upgrading @react-navigation in my main project and see how that goes.

Edit 2: I upgraded @react-navigation to ^7.0.0 and it seems better so far, but the Skia components will disappear if I tap "Show Perf Monitor" and then navigate to a screen with the Skia components (interestingly I can't tap Expo's "Toggle performance monitor" as it just flashes the perf panel on/off, I have to enable it through "Open React Native dev menu"). However in a fresh test project I can't reproduce it... I'm wondering if I transfer my old project into a new expo project using continuous native generation if that would help things or not - maybe I have some cruft in my "expo ejected" ios directory 🤔

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

6 participants