0

I'm build a react application. On macos and ios browsers (including CHROME) the drawing feature is working like it should. But on android, it does't matter if I'm using a default browser, chrome or a web view. It wont work. I also tried with dp instead of px but nothing changed. I can share the code

Canvas.js

import React, { useEffect } from "react";
import { useCanvas } from "./CanvasContext";

export function Canvas() {
  const {
    canvasRef,
    prepareCanvas,
    startDrawing,
    finishDrawing,
    draw,
  } = useCanvas();

  useEffect(() => {
    prepareCanvas();
  }, []);

  return (
    <canvas
      style={{backgroundColor: "white"}}
      onPointerDown={startDrawing}
      onPointerUp={finishDrawing}
      onPointerMove={draw}
      ref={canvasRef}
    />
  );
}

CanvasContext.js

import React, { useContext, useRef, useState } from "react";

const CanvasContext = React.createContext();

export const CanvasProvider = ({ children }) => {
  const [isDrawing, setIsDrawing] = useState(false)
  const canvasRef = useRef(null);
  const contextRef = useRef(null);

  const prepareCanvas = () => {
    const canvas = canvasRef.current

    
    canvas.width = window.innerWidth * 2;
    canvas.height = window.innerHeight * 2;


    canvas.style.width = `${window.innerWidth}dp`;
    canvas.style.height = `${window.innerHeight}dp`;

    const context = canvas.getContext("2d")
    context.scale(2, 2);
    context.lineCap = "round";
    context.strokeStyle = "black";
    context.lineWidth = 5;
    contextRef.current = context;
  };

  const startDrawing = ({ nativeEvent }) => {
    const { offsetX, offsetY } = nativeEvent;
    contextRef.current.beginPath();
    contextRef.current.moveTo(offsetX, offsetY);
    setIsDrawing(true);
  };

  const finishDrawing = () => {
    contextRef.current.closePath();
    setIsDrawing(false);
  };

  const draw = ({ nativeEvent }) => {
    if (!isDrawing) {
      return;
    }
    const { offsetX, offsetY } = nativeEvent;
    contextRef.current.lineTo(offsetX, offsetY);
    contextRef.current.stroke();
  };

  const clearCanvas = () => {
    const canvas = canvasRef.current;
    const context = canvas.getContext("2d")
    context.fillStyle = "white"
    context.fillRect(0, 0, canvas.width, canvas.height)
  }

  return (
    <CanvasContext.Provider
      value={{
        canvasRef,
        contextRef,
        prepareCanvas,
        startDrawing,
        finishDrawing,
        clearCanvas,
        draw,
      }}
    >
      {children}
    </CanvasContext.Provider>
  );
};

export const useCanvas = () => useContext(CanvasContext);

DrawingCanavs.js

import React, { useState, useRef, useEffect } from 'react';
import { Modal, useModal, Button, Text } from "@nextui-org/react";

import { Canvas } from './Canvas'
import { ClearCanvasButton } from './ClearCanvasButton';
const DrawingCanvas = ({children}) => {
  const { setVisible, bindings } = useModal();

  return (
<div>
<Button auto flat onPress={() => setVisible(true)}>
  {children}
      </Button>
      {/* <canvas style={{backgroundColor: 'white'}} onMouseDown={startDrawing} ontouchstart={startDrawing} onMouseUp={finishDrawing} onTouchEnd={finishDrawing} onMouseMove={draw} ref={canvasRef}/> */}

      <Modal
        fullScreen
        closeButton
        aria-labelledby="modal-title"
        aria-describedby="modal-description"
        {...bindings}
        
      >
        <Modal.Header>
          <Text id="modal-title" size={18}>
            Sign
          </Text>
        </Modal.Header>
        <Modal.Body style={{margin: 0, height: "100%", overflow: "hidden"}}>
          {/*  id="modal-description"*/}
          <Canvas/>
      <ClearCanvasButton/>
    
              </Modal.Body>
        <Modal.Footer>
          <Button flat auto color="error" onPress={() => setVisible(false)}>
            Close
          </Button>
          {/* <Button onPress={() => setVisible(false)}>Agree</Button> */}
        </Modal.Footer>
      </Modal>
    </div>
  );
};

export default DrawingCanvas;
Crocker
  • 1
  • 3
  • Could be [this issue](https://stackoverflow.com/a/43275544) – set CSS `touch-action: none` on the canvas element so that the pointer events aren't intercepted before you can use them for drawing. – motto Mar 30 '23 at 19:09
  • @motto it was exactly my issue. If u make an answer I can approve it – Crocker Mar 30 '23 at 19:45
  • glad it fixed the issue, but this is technically a dupe so you get this one for free :-) – motto Mar 30 '23 at 20:58

0 Answers0