使用creat-react-app简单搭建一个react-hooks项目
return(<Fragment>
<canvas
ref={canvasRef}
width={window.innerWidth}
height={window.innerHeight}
/>
<div className='SSS' onClick={clearCanvas}>清除</div>
</Fragment>)
创建一个canvas绘图区域
import React, { Fragment } from 'react'
const HOOK_SVG = 'm129.03125 63.3125c0-34.914062-28.941406-63.3125-64.519531-63.3125-35.574219 0-64.511719 28.398438-64.511719 63.3125 0 29.488281 20.671875 54.246094 48.511719 61.261719v162.898437c0 53.222656 44.222656 96.527344 98.585937 96.527344h10.316406c54.363282 0 98.585938-43.304688 98.585938-96.527344v-95.640625c0-7.070312-4.640625-13.304687-11.414062-15.328125-6.769532-2.015625-14.082032.625-17.960938 6.535156l-42.328125 64.425782c-4.847656 7.390625-2.800781 17.3125 4.582031 22.167968 7.386719 4.832032 17.304688 2.792969 22.160156-4.585937l12.960938-19.71875v42.144531c0 35.582032-29.863281 64.527344-66.585938 64.527344h-10.316406c-36.714844 0-66.585937-28.945312-66.585937-64.527344v-162.898437c27.847656-7.015625 48.519531-31.773438 48.519531-61.261719zm-97.03125 0c0-17.265625 14.585938-31.3125 32.511719-31.3125 17.929687 0 32.511719 14.046875 32.511719 31.3125 0 17.261719-14.582032 31.3125-32.511719 31.3125-17.925781 0-32.511719-14.050781-32.511719-31.3125zm0 0'
const HOOK_PATH = new Path2D(HOOK_SVG)
const SCALE = 0.3
const OFFSET = 80
function draw(
ctx: {
fillStyle: string; shadowColor: string; shadowBlur: number;
save: () => void; scale:
(arg0: number, arg1: number) => void;
translate: (arg0: number, arg1: number) => void;
fill: (arg0: Path2D) => void; restore: () => void
},
location: { x: any; y: any }) {
ctx.fillStyle = 'deepskyblue'
ctx.shadowColor = 'dodgerblue'
ctx.shadowBlur = 20;
ctx.save()
ctx.scale(SCALE, SCALE)
ctx.translate(location.x / SCALE - OFFSET, location.y / SCALE - OFFSET)
ctx.fill(HOOK_PATH)
ctx.restore()
}
function App() {
const canvasRef = React.useRef<any>(null);
let [Flag, setFlat] = React.useState(false)
React.useEffect(() => {
const canvas = canvasRef.current
const ctx = canvas.getContext('2d')
ctx.fillStyle = 'white';
ctx.fillRect(10, 10, window.innerWidth, window.innerHeight);
// 画图
ctx.beginPath();
ctx.moveTo(75, 50);
ctx.lineTo(100, 75);
ctx.lineTo(100, 25);
ctx.lineWidth = '1';
ctx.fillStyle = 'pink';
ctx.fill();
})
const writing = (
beginX: number,
beginY: number,
stopX: number,
stopY: number,
ctx: { beginPath: () => void; globalAlpha: number; lineWidth: number; strokeStyle: string; moveTo: (arg0: any, arg1: any) => void; lineTo: (arg0: any, arg1: any) => void; closePath: () => void; stroke: () => void },
) => {
ctx.beginPath() // 开启一条新路径
ctx.globalAlpha = 1 // 设置图片的透明度
ctx.lineWidth = 3 // 设置线宽
ctx.strokeStyle = 'pink' // 设置路径颜色
ctx.moveTo(beginX, beginY) // 从(beginX, beginY)这个坐标点开始画图
ctx.lineTo(stopX, stopY) // 定义从(beginX, beginY)到(stopX, stopY)的线条(该方法不会创建线条)
ctx.closePath() // 创建该条路径
ctx.stroke() // 实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色。
}
React.useEffect(() => {
let beginX: number; let beginY: number
const canvas = canvasRef.current
const ctx = canvas.getContext('2d')
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvas.width, canvas.height)
console.log(ctx, 'canvas');
// pc端 和 移动端事件
canvas.addEventListener('click', function (event: { preventDefault: () => void; clientX: number; clientY: number }) {
event.preventDefault() // 阻止在canvas画布上签名的时候页面跟着滚动
beginX = event.clientX
beginY = event.clientY
setFlat(true)
ctx.fillStyle = 'deepskyblue'
ctx.shadowColor = 'dodgerblue'
ctx.shadowBlur = 20;
ctx.save()
ctx.scale(SCALE, SCALE)
ctx.translate(event.clientX / SCALE - OFFSET, event.clientY / SCALE - OFFSET)
ctx.fill(HOOK_PATH)
ctx.restore()
})
canvas.addEventListener('mousemove', (event: { preventDefault: () => void; clientX: number; clientY: number }) => {
event.preventDefault() // 阻止在canvas画布上签名的时候页面跟着滚动
if (Flag === false) {
return
}
const stopX = event.clientX - canvas.offsetLeft
const stopY = event.clientY - canvas.offsetTop
writing(beginX, beginY, stopX, stopY, ctx)
beginX = stopX // 这一步很关键,需要不断更新起点,否则画出来的是射线簇
beginY = stopY
})
canvas.addEventListener('mouseleave', function (event: { preventDefault: () => void; }) {
event.preventDefault() // 阻止在canvas画布上签名的时候页面跟着滚动
})
canvas.addEventListener('touchstart', function (event: { preventDefault: () => void; touches: { clientX: number; pageY: any }[] }) {
event.preventDefault() // 阻止在canvas画布上签名的时候页面跟着滚动
beginX = event.touches[0].clientX
beginY = event.touches[0].pageY
})
canvas.addEventListener('touchmove', (event: { preventDefault: () => void; touches: any[]; clientX: number; pageY: number }) => {
event.preventDefault() // 阻止在canvas画布上签名的时候页面跟着滚动
event = event.touches[0]
const stopX = event.clientX - canvas.offsetLeft
const stopY = event.pageY - canvas.offsetTop
writing(beginX, beginY, stopX, stopY, ctx)
beginX = stopX // 这一步很关键,需要不断更新起点,否则画出来的是射线簇
beginY = stopY
})
})
function clearCanvas() { // 清除画图 ,重新画布 ,或者设置白色背景色
const canvas = canvasRef.current
const ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
}