skip to Main Content

I’m pretty new to react-native-skia, I have a grayscale shader applied on an Image and I would like to apply this kind of transition animation on press to switch between grayscale and full colored picture. Here is the code that I’m using to apply a grayscale effect.

const GRAYSCALE_SHADER = Skia.RuntimeEffect.Make(`
uniform shader image;

half4 main(in vec2 xy)
{
  //Grabbing the texture color at the current pixel.
  vec4 texColor = image.eval(xy).rgba;
  
  vec3 gray_scale = vec3(dot(vec3(0.5, 0.2, 0.2), texColor.rgb));
      
  // Output to screen
  return vec4(gray_scale, texColor.a) ;
}
`)!;

const image = useImage('../path/to/image.png');

return (
    <Canvas
      style={{ flex: 1 }}
    >
      <Image
        image={image}
        fit="cover"
        x={0}
        y={0}
        width={200}
        height={200}
      >
        <RuntimeShader source={GRAYSCALE_SHADER} />
      </Image>
    </Canvas>
)

2

Answers


  1.     const TRANSITION_SHADER = Skia.RuntimeEffect.Make(`
        uniform float smoothness; // = 0.3
        uniform bool opening; // = true
        
        const vec2 center = vec2(0.5, 0.5);
        const float SQRT_2 = 1.414213562373;
        
        vec4 transition (vec2 uv) {
          float x = opening ? progress : 1.-progress;
          float m = smoothstep(-smoothness, 0.0, SQRT_2*distance(center, uv) - x*(1.+smoothness));
          return mix(getFromColor(uv), getToColor(uv), opening ? 1.-m : m);
        }
        `)!;
    
    
    
    
    ------------------
    
     
    
           const progress = useSharedValue(0.0);
            
            const getFromColor = (xy) => {
              const fromColor = Skia.Paint.Make();
              fromColor.color = Skia.Color.FromRGBA(0, 0, 0, 1); // Set the from color to black
              return fromColor;
            }
            
            const getToColor = (xy) => {
              const toColor = Skia.Paint.Make();
              toColor.color = Skia.Color.FromRGBA(1, 1, 1, 1); // Set the to color to white
              return toColor;
            }
            
            const transitionShader = useDerivedValue(() => {
              const fromColor =Skia.Shader.Make(getFromColor, []);
              const toColor = Skia.Shader.Make(getToColor, []);
              const transition = TRANSITION_SHADER.makeShader({ smoothness: 0.3, opening: true });
              return Skia.Shader.Make(transition, [fromColor, toColor]);
            });
        
        
        -----------------------
        this one for image 
        
        <Image
          image={image}
          fit="cover"
          x={0}
          y={0}
          width={200}
          height={200}
          shader={transitionShader}
        />
    
    ---------------------------------
    
        const [isPressed, setIsPressed] = useState(false);
        
        const pressHandler = () => {
          setIsPressed(!isPressed);
          if (isPressed) {
            progress.value = 0;
          } else {
            progress.value = withTiming(1, { duration: 500 });
          }
        };
        
        <Image
          image={image}
          fit="cover"
          x={0}
          y={0}
          width={200}
          height={200}
          shader={transitionShader}
          onPress={pressHandler}
        />
    
    Login or Signup to reply.
  2. To create a transition animation between a grayscale image and a full colored image in React Native Skia, you can achieve this by toggling between two different shaders for the Image component. One shader will apply the grayscale effect, while the other will display the full colored image.

    Here’s an approach to implement this transition animation:

    1. Define two shaders: one for grayscale and one for full color.
    2. Create a state variable to keep track of the current shader being applied.
    3. Toggle between the grayscale shader and the full color shader on press.

    Here’s an example code snippet to achieve this:

    import React, { useState } from 'react';
    import { Canvas, Image, RuntimeShader, Skia } from 'react-native-skia';
    
    const GRAYSCALE_SHADER = Skia.RuntimeEffect.Make(
      uniform shader image;
    
      half4 main(in vec2 xy)
      {
        vec4 texColor = image.eval(xy).rgba;
        vec3 gray_scale = vec3(dot(vec3(0.5, 0.2, 0.2), texColor.rgb));
        return vec4(gray_scale, texColor.a);
      }
    )!;
    
    const FULL_COLOR_SHADER = Skia.RuntimeEffect.Make(
      uniform shader image;
    
      half4 main(in vec2 xy)
      {
        return image.eval(xy);
      }
    )!;
    
    const MyComponent = () => {
      const [isGrayscale, setIsGrayscale] = useState(true);
    
      const toggleShader = () => {
        setIsGrayscale((prev) => !prev);
      };
    
      const shaderToApply = isGrayscale ? GRAYSCALE_SHADER : FULL_COLOR_SHADER;
    
      const image = useImage('../path/to/image.png');
    
      return (
        <Canvas style={{ flex: 1 }}>
          <Image
            image={image}
            fit="cover"
            x={0}
            y={0}
            width={200}
            height={200}
            onPress={toggleShader}
          >
            <RuntimeShader source={shaderToApply} />
          </Image>
        </Canvas>
      );
    };
    
    export default MyComponent;
    

    In this code snippet:

    • We define two shaders: GRAYSCALE_SHADER and FULL_COLOR_SHADER.
    • We use the useState hook to maintain the state of whether the image should be displayed in grayscale or full color.
    • The toggleShader function toggles the state between grayscale and full color on press.
    • We conditionally select the shader to apply based on the current state.
    • The onPress event on the Image component triggers the shader toggle when the image is pressed.

    This setup allows you to switch between grayscale and full color with a press interaction on the image. You can further customize the transition animation or effects based on your requirements.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search