Code Monkey home page Code Monkey logo

Comments (10)

wcandillon avatar wcandillon commented on August 29, 2024 1

What we will do as a first step is document this better.

from react-native-skia.

daehyeonmun2021 avatar daehyeonmun2021 commented on August 29, 2024

CleanShot 2024-04-17 at 18 32 02@2x

I found out those two textures shows different results. (RN Skia v.1.0.2, RN v.0.73.6)

Left: drawing on canvas from offscreen, Right: drawing on canvas from PictureRecoder.

Is this because offscreen doesn't respect pixel density?

from react-native-skia.

wcandillon avatar wcandillon commented on August 29, 2024

yes this is very likely:

// TODO: We're not sure yet why PixelRatio is not needed here.

Could you share the example with me?

from react-native-skia.

daehyeonmun2021 avatar daehyeonmun2021 commented on August 29, 2024

@wcandillon Here is the code. You can see the density issue and paint stroke goes different if setting strokeWidth is skipped on the two textures.

I attached the result image (above: offscreen, below: pictureRecorder) and code.

Thanks :)

Versions:
RN skia: 1.1.0
react-native: 0.73.6

CleanShot 2024-04-18 at 13 03 19@2x

import {
  Canvas,
  Group,
  Image,
  Line,
  PaintStyle,
  Picture,
  rect,
  SkCanvas,
  Skia,
  vec,
} from '@shopify/react-native-skia';
import { Dimensions } from 'react-native';
import { useDerivedValue } from 'react-native-reanimated';

const { width: stageWidth, height: stageHeight } = Dimensions.get('screen');
const stageHeightHalf = stageHeight / 2;

const TOTAL = 1000;
const RADIUS = 10;
const BALL_STYLE = Skia.Paint();
BALL_STYLE.setStyle(PaintStyle.Stroke);
// BALL_STYLE.setStrokeWidth(1); // * If you skip setting strokeWidth, the two textures shows different result.
const BALLS = Array.from({ length: TOTAL }, () => ({
  x: RADIUS + Math.random() * (stageWidth - RADIUS),
  y: RADIUS + Math.random() * (stageHeightHalf - RADIUS),
  r: RADIUS,
}));

const Page = () => {
  const drawBalls = (canvas: SkCanvas) => {
    'worklet';

    canvas.save();
    for (let i = 0; i < BALLS.length; i++) {
      const ball = BALLS[i];
      canvas.drawCircle(ball.x, ball.y, ball.r, BALL_STYLE);
    }
    canvas.restore();
  };
  const offscreen = useDerivedValue(() => {
    const offscreen = Skia.Surface.MakeOffscreen(stageWidth, stageHeightHalf)!;
    const canvas = offscreen.getCanvas();
    drawBalls(canvas);
    return offscreen.makeImageSnapshot();
  }, []);
  const pictureRecorder = useDerivedValue(() => {
    const recorder = Skia.PictureRecorder();
    const canvas = recorder.beginRecording(rect(0, 0, stageWidth, stageHeightHalf));
    drawBalls(canvas);
    return recorder.finishRecordingAsPicture();
  }, []);

  return (
    <Canvas
      style={{
        width: stageWidth,
        height: stageHeight,
        backgroundColor: 'lightblue',
      }}
    >
      <Group transform={[{ translate: [0, 0] }]}>
        <Image image={offscreen} width={stageWidth} height={stageHeightHalf} />
      </Group>
      <Group transform={[{ translate: [0, stageHeightHalf] }]}>
        <Picture picture={pictureRecorder} />
      </Group>
      <Group>
        <Line p1={vec(0, stageHeightHalf)} p2={vec(stageWidth, stageHeightHalf)} strokeWidth={10} color="blue" />
      </Group>
    </Canvas>
  );
};

export default Page;

from react-native-skia.

wcandillon avatar wcandillon commented on August 29, 2024

I think this is the expected result.
This is how you need to write the code:

const pd = PixelRatio.get();

  const offscreen = useDerivedValue(() => {
    const off = Skia.Surface.MakeOffscreen(
      stageWidth * pd,
      stageHeightHalf * pd
    )!;
    const canvas = off.getCanvas();
    canvas.scale(pd, pd);
    drawBalls(canvas);
    canvas.restore();
    return off.makeImageSnapshot();
  }, []);

from react-native-skia.

daehyeonmun2021 avatar daehyeonmun2021 commented on August 29, 2024

@wcandillon Nice :) Thanks for the insight ! 🥰

from react-native-skia.

daehyeonmun2021 avatar daehyeonmun2021 commented on August 29, 2024

@wcandillon Oh I have a question, so you are planning to fix this offscreen density issue to make users don't need to add the pixel density configuration for offscreen canvas?

from react-native-skia.

wcandillon avatar wcandillon commented on August 29, 2024

I don't think it makes sense to add it in this API because the offscreen API has nothing to do with the screen.
But now I am trying to see if this causes inconsistencies with higher-level API (e.g useTexture) which are indeed on screen.

from react-native-skia.

daehyeonmun2021 avatar daehyeonmun2021 commented on August 29, 2024

Got it! Thanks 🙏🥰

from react-native-skia.

wcandillon avatar wcandillon commented on August 29, 2024

I'm closing it for now, as the current situation seems to make sense.

from react-native-skia.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.