question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Problem with resizing canvas

See original GitHub issue

I’ve been having the same problem. This is my code:

import React, { Component } from 'react';
import {
  AppRegistry,
  View,
  PanResponder,
} from 'react-native';

import Canvas, {Image as CanvasImage} from 'react-native-canvas';

export default class ImagePainter extends Component {
  constructor(props) {
    super(props);
  }

  state = {
      image: this.props.image,
      originalImage: this.props.image,
      width: this.props.width,
      height: this.props.height,
      positionX: undefined,
      positionY: undefined,
      canvas: undefined,
  };

  panResponder = PanResponder.create({
    onStartShouldSetPanResponder: (evt, gestureState) => true,
    onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
    onMoveShouldSetPanResponder: (evt, gestureState) => true,
    onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,

    onPanResponderGrant: (evt, gestureState) => {
      const x = Math.floor(evt.nativeEvent.locationX);
      const y = Math.floor(evt.nativeEvent.locationY);
      this.positionX = x;
      this.positionY = y;
    },
    onPanResponderMove: (evt, gestureState) => {
      if(!this.canvas){
        return;
      }

      const x0 = this.positionX;
      const y0 = this.positionY;
      const x1 = Math.floor(evt.nativeEvent.locationX);
      const y1 = Math.floor(evt.nativeEvent.locationY);
      const ctx = this.canvas.getContext('2d');
      ctx.moveTo(x0, y0);
      ctx.lineTo(x1, y1);
      ctx.stroke();
      this.positionX=x1
      this.positionY=y1;
    },
    onPanResponderTerminationRequest: (evt, gestureState) => true,
    onPanResponderRelease: (evt, gestureState) => {
    },
    onPanResponderTerminate: (evt, gestureState) => {
    },
    onShouldBlockNativeResponder: (evt, gestureState) => {
      return true;
    },
  });

  componentDidMount() {
    const canvas = this.canvas;
    if(canvas){
      canvas.width = this.props.width;
      canvas.height = this.props.height;
      this.renderCanvas();
    }
  }

  renderCanvas = async () => {
    if (this.canvas) {
      const canvas = this.canvas;
      const ctx = await canvas.getContext('2d');
      const image = new CanvasImage(canvas, this.props.height, this.props.width);
      image.addEventListener('load', function() {
        ctx.drawImage(image, 0, 0);
      });
      image.addEventListener('error', err => console.log(err))
      image.src = `data:image/jpeg;base64,${this.state.image}`;
    } else {
      console.log('No canvas?')
    }
  }

  componentDidUpdate() {
    this.renderCanvas();
  }

  render() {
    return (
          <View {...this.panResponder.panHandlers} style={{width: this.props.width, height: this.props.height}}>
            <Canvas ref={ canvas => this.canvas = canvas } 
                    style={{borderWidth: 3, borderStyle: 'dashed', width: this.props.width, height: this.props.height}}
                    width={this.props.width}
                    height={this.props.height}
                  />
          </View>
    );
  }
}

AppRegistry.registerComponent('ImagePainter', () => ImagePainter);

From what is written here, it should work.

I narrowed down the problem to the resizing. It looks like resizing changes the reference to the canvas?

On my componentDidMount if I leave the canvas.width and height assignments, nothing shows up. If I comment it how, I get a canvas that’s too small (300x150px instead of 300x400) but everything works.

I installed react-native-canvas 2 days ago so it should be the most up-to-date…

_Originally posted by @edbrito in https://github.com/iddan/react-native-canvas/issues/94#issuecomment-504378489_

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
Vanneveljcommented, May 8, 2020

I’m facing the same problem as well. @iddan do you perhaps have an example where a Canvas has dimensions X, resizes to dimensions Y, draws something and it shows up? Just to rule out us doing something wrong.

Edit: I looked into it more and it appears that this is expected behaviour. When the canvas its width or height changes, it will clear everything that was rendered. I’ve verified this in non-native React and sources corroborate this: https://stackoverflow.com/a/5517885/1864167 & https://stackoverflow.com/questions/56120082/how-to-get-correct-width-and-height-for-a-canvas-in-react#comment98873492_56120235

Note that this might just be me and the others their problem is slightly different. I’ll update this if I find myself in the same situation as they are. That being said, this example draws a rectangle on the canvas, resizes the canvas and draws a new rectangle: https://gist.github.com/Vannevelj/eca9ab7da0d543c84964ecdbcad00879

0reactions
blwinterscommented, Oct 15, 2022

Similar to @dandan-drori , I used the onLayout handler to get the size of my canvas container (which varies a bit based on the device). From that handler I set the width and height of the ref.

Also, TypeScript was showing an error when I tried to pass in the width and height as props for some reason, so I skipped those.

const onContainerLayout = (event: LayoutChangeEvent) => {
  const { layout } = event.nativeEvent
  if (canvasRef?.current) {
    canvasRef.current.height = layout.height * 0.6
    canvasRef.current.width = layout.width
  }
}
<View onLayout={onContainerLayout}>
  <Canvas ref={canvasRef} />
</View>
Read more comments on GitHub >

github_iconTop Results From Across the Web

Resizing canvas, where's the problem? - Stack Overflow
If the pictures height becomes to big for the window then the picture should resize itself according to the height and not the...
Read more >
BUG: Resizing canvas makes componenents end up ... - GitHub
The Canvas is not the correct width then (slightly smaller) but everything seems to work fine nonetheless... I am not going to close...
Read more >
Resize canvas problem - Questions - Babylon.js Forum
My canvas doesn't resizing like in playground, so I can't get full screen on my mobile devices. I want to my cut clear...
Read more >
Problem with canvas resizing - PlayCanvas Forum
We just resize canvas to fill the page and vice versa. Our solution works perfectly on:
Read more >
Problem with canvas either being blurry or not responding to ...
When you open the example, the page is resizing correctly, but the canvas content is blurred. This is a know issue, and to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found