'use client'
import { useEffect, useLayoutEffect, useRef, useState } from 'react'
const DrawingCanvasPage: React.FC = () => {
const [width, setWidth] = useState(0)
const [height, setHeight] = useState(0)
useLayoutEffect(() => {
setWidth(window.innerWidth)
setHeight(window.innerHeight)
}, [])
let canvasRef = useRef<HTMLCanvasElement | null>(null)
let mouseX: number | null = null
let mouseY: number | null = null
const preventPullToRefresh = (e: any) => {
if (e.touches.length !== 1) return
e.preventDefault()
}
useEffect(() => {
const canvasElement = canvasRef.current
canvasElement?.addEventListener('touchstart', preventPullToRefresh, { passive: false })
canvasElement?.addEventListener('touchmove', preventPullToRefresh, { passive: false })
return () => {
canvasElement?.removeEventListener('touchstart', preventPullToRefresh)
canvasElement?.removeEventListener('touchmove', preventPullToRefresh)
}
}, [])
const getContext = (): CanvasRenderingContext2D => {
const canvas: any = canvasRef.current
return canvas.getContext('2d')
}
const handleStart = (x: number, y: number) => {
Draw(x, y)
}
const handleMove = (x: number, y: number) => {
Draw(x, y)
}
const OnTouchStart = (e: React.TouchEvent<HTMLCanvasElement>) => {
const touch = e.touches[0]
const canvas: any = canvasRef.current
const rect = canvas.getBoundingClientRect()
const x = ~~(touch.clientX - rect.left)
const y = ~~(touch.clientY - rect.top)
handleStart(x, y)
}
const OnTouchMove = (e: React.TouchEvent<HTMLCanvasElement>) => {
const touch = e.touches[0]
const canvas: any = canvasRef.current
const rect = canvas.getBoundingClientRect()
const x = ~~(touch.clientX - rect.left)
const y = ~~(touch.clientY - rect.top)
handleMove(x, y)
}
const OnMouseDown = (e: React.MouseEvent<HTMLCanvasElement, MouseEvent>) => {
const canvas: any = canvasRef.current
const rect = canvas.getBoundingClientRect()
const x = ~~(e.clientX - rect.left)
const y = ~~(e.clientY - rect.top)
handleStart(x, y)
}
const OnMouseMove = (e: React.MouseEvent<HTMLCanvasElement, MouseEvent>) => {
if (e.buttons !== 1) return
const canvas: any = canvasRef.current
const rect = canvas.getBoundingClientRect()
const x = ~~(e.clientX - rect.left)
const y = ~~(e.clientY - rect.top)
handleMove(x, y)
}
const Draw = (x: number, y: number) => {
const ctx = getContext()
ctx.beginPath()
ctx.globalAlpha = 1.0
if (mouseX === null || mouseY === null) {
ctx.moveTo(x, y)
} else {
ctx.moveTo(mouseX, mouseY)
}
ctx.lineTo(x, y)
ctx.lineCap = 'round'
ctx.lineWidth = 10
ctx.strokeStyle = '#000000'
ctx.stroke()
mouseX = x
mouseY = y
}
const DrawEnd = () => {
mouseX = null
mouseY = null
}
const Reset = () => {
const ctx = getContext()
ctx.clearRect(0, 0, width, height)
}
return (
<section>
<button className='mt-1 ml-1 absolute shadow-lg p-2' onClick={Reset}>
リセット
</button>
<canvas
id='canvasId'
onTouchStart={OnTouchStart}
onTouchMove={OnTouchMove}
onTouchEnd={DrawEnd}
onTouchCancel={DrawEnd}
onMouseDown={OnMouseDown}
onMouseMove={OnMouseMove}
onMouseUp={DrawEnd}
onMouseLeave={DrawEnd}
ref={canvasRef}
width={width}
height={height}
/>
</section>
)
}
export default DrawingCanvasPage