主要的技术点:
1、利用Canvas的lineTo方法和stroke方式绘制连续填充的线;
2、利用canvasContext的strokeStyle更改画笔颜色;
3、利用canvasContext的lineWidth更改画笔宽度;
一、支持的功能:
1、调整画笔的颜色;
2、调整画笔的宽度;
二、效果图:
三、React组件代码(注意我用的是tsx的文件格式,如果用jsx请移除数据类型声明即可)
import React from "react";
import styles from './index.less';
export default class CanvasComponent extends React.Component {
canvasRef: any;
paintColors = ['#000000', '#999999', '#CC66FF', '#FF0000', '#FF9900', '#FFFF00'];
paintWidths = [1, 2, 3, 4, 5, 6];
canvasContext: any;
// 颜色面板
paintColorPanel = this.paintColors.map((element, index) => {
return <span className={styles.bk} style={{backgroundColor: element}}
onClick={() => {
this.onColorSpanClick(index)
}
}/>
});
// 画笔宽度面板
paintWidthPanel = this.paintWidths.map((element, index) => {
return <span className={styles.bk}
onClick={() => {
this.onWidthSpanClick(index)
}
}>{element}</span>
});
constructor(props: {} | Readonly<{}>) {
super(props);
this.canvasRef = React.createRef();
}
/**
* 选择画笔颜色
* @param index
*/
onColorSpanClick = (index: number) => {
this.canvasContext.strokeStyle = this.paintColors[index];
}
/**
* 选择画笔宽度
* @param index
*/
onWidthSpanClick = (index: number) => {
this.canvasContext.lineWidth = this.paintWidths[index];
}
/**
* 初始化画笔和事件监听
*/
initPainter = () => {
let canvas = this.canvasRef.current;
this.canvasContext = canvas.getContext('2d');
let x = 0;
let y = 0;
this.canvasContext.lineWidth = 2;
this.canvasContext.strokeStyle = '#000000';
//鼠标按下事件
canvas.addEventListener('mousedown', (e: MouseEvent) => {
e.preventDefault();
x = e.offsetX;
y = e.offsetY;
this.canvasContext.beginPath();
this.canvasContext.moveTo(x, y);
//鼠标移动事件
let onm ouseMoveEvent = (e: MouseEvent) => {
let newX = e.offsetX;
let newY = e.offsetY;
this.canvasContext.lineTo(newX, newY);
this.canvasContext.stroke();
x = newX;
y = newY;
}
canvas.addEventListener('mousemove', onm ouseMoveEvent);
canvas.addEventListener('mouseup', () => {
canvas.removeEventListener('mousemove', onm ouseMoveEvent);
})
})
}
componentDidMount() {
this.initPainter();
}
render() {
return <>
画笔颜色:
<div id={styles.bk}>{this.paintColorPanel}</div>
画笔宽度:
<div id={styles.bk}>{this.paintWidthPanel}</div>
<canvas ref={this.canvasRef} id={'cav'} width={800} height={600} style={{background: '#1677ff'}}/>
</>;
}
}
四、less样式代码
body div {
margin: 0;
padding: 0;
text-align: center;
}
#cav {
border: 2px solid black;
border-radius: 4px;
box-shadow: 0 0 10px black;
-webkit-box-shadow: 0 0 10px black;
-moz-box-shadow: 0 0 10px black;
}
#bk{
margin: 10px auto;
width: 800px;
height: 36px;
}
.bk{
text-align: center;
width: 20px;
height: 20px;
margin: 12px;
display: inline-block;
border: 1px solid grey;
}