import React, { Component } from "react" import "./areaSelete.css" export default class AreaSelete extends Component { constructor() { super(); this.state = { id: new Date().getTime() + Math.floor(Math.random() * (10000 - 1)) + 1, mode:"", width: "100px", height: "100px", circleRadius: 10,//圆半径 circleBorderWidth: 4,//圆边线的半径宽 circleBorderColor: "#28B1D9",//圆边线的颜色 circleInColor: "#28B1D9",//圆里里面的颜色 circleSelectColor:"#FFF", lineColor: "#28B1D9",//线的颜色 lineWidth: 2,//线的宽度 areaColor: "rgba(40, 177, 217, 0.2)",//选中区域颜色 serviceData: [] } } static getDerivedStateFromProps(props, state) { var obj = {}; for(var key in props){ if(props[key]&&props[key]!==state[key]){ obj[key] = props[key] } } if(Object.keys(obj).length>0){ return obj; }else{ return null } } shouldComponentUpdate(nextProps){ if(this.props.serviceData.length !== nextProps.serviceData){ return true }else{ return false } } componentDidMount() { this.init() window.onresize = this.init.bind(this) } init() { this.setCanvasSize();//根据父盒子宽高大小设置画布的大小 } setCanvasSize() { let { id } = this.state; var canvasEl = document.getElementById(id) var parentEl = canvasEl.parentNode; var parentWidth = parentEl.offsetWidth;//父标签的宽度 var parentHeight = parentEl.offsetHeight;//父标签的高度 this.setData({ width: parentWidth + "px", height: parentHeight + "px" }) } draw() { let { id, serviceData, width, height,mode } = this.state; var canvasEl = document.getElementById(id) var ctx = canvasEl.getContext("2d"); ctx.clearRect(0, 0, parseFloat(width), parseFloat(height)); this.drawLine(ctx, serviceData); this.drawCircleAll(ctx, serviceData); // this.clickMove()//点击模式 // this.mouseMove()//鼠标移动模式 // this.touchMove()//手指触摸移动模式 if(mode === 'click'){ this.isontouchend()?this.touchMove():this.clickMove() }else{ this.isontouchend()?this.touchMove():this.mouseMove() } } isontouchend() {//判断是否支持触屏 return "ontouchend" in document ? true : false; } drawCircleAll(ctx, data) {//画所有圆 for (var i = 0; i < data.length; i++) { this.drawCircle(ctx, data[i][0], data[i][1],this.selectedIndex===i) } } drawCircle(ctx, x, y,selected) {//画单个圆 let { circleRadius, circleInColor, circleBorderColor, circleBorderWidth,circleSelectColor } = this.state ctx.fillStyle = selected?circleSelectColor:circleInColor;//画里面 ctx.beginPath(); ctx.arc(x, y, parseInt(circleRadius) , 0, Math.PI * 2, true); ctx.closePath(); ctx.fill(); ctx.beginPath();//画外面的空心圆 ctx.arc(x, y, parseInt(circleRadius), 0, Math.PI * 2, true); ctx.lineWidth = parseInt(circleBorderWidth); ctx.strokeStyle = circleBorderColor; ctx.stroke(); //画空心圆 ctx.closePath(); } drawLine(ctx, data) {//画线 let { lineColor, lineWidth, areaColor } = this.state ctx.beginPath(); for (var i = 0; i < data.length; i++) { if (i === 0) { ctx.moveTo(data[i][0], data[i][1]); } else { ctx.lineTo(data[i][0], data[i][1]); } } ctx.lineWidth = parseInt(lineWidth); ctx.strokeStyle = lineColor; ctx.closePath(); ctx.fillStyle = areaColor; ctx.fill(); ctx.stroke(); } clickMove() {//鼠标点击移动 let { id, serviceData } = this.state; var canvasEl = document.getElementById(id) canvasEl.onclick = (e) => { var left = e.layerX var top = e.layerY if (this.selectedIndex || this.selectedIndex === 0) {//此时已经选中了点 serviceData[this.selectedIndex] = [left, top] this.selectedIndex = null this.setData({ serviceData: serviceData }) this.props.change(serviceData) } else { this.selectBox(left, top) this.setData({ serviceData: serviceData }) } } } mouseMove() {//鼠标移动 let { id, serviceData } = this.state; var canvasEl = document.getElementById(id) canvasEl.onmousedown = (e) => { var left = e.layerX var top = e.layerY if (this.selectBox(left, top)) { canvasEl.onmousemove = (e) => { serviceData[this.selectedIndex] = [e.layerX, e.layerY]; this.setData({ serviceData: serviceData }) }; } } canvasEl.onmouseup = (e) => { canvasEl.onmousemove = null; this.selectedIndex = null; this.setData({ serviceData: serviceData }) var left = e.layerX var top = e.layerY if (this.selectBox(left, top)) { this.props.change(serviceData) } }; } touchMove() {//手指触摸移动 let { id, serviceData } = this.state; var canvasEl = document.getElementById(id) var parentEl = canvasEl.parentNode; var pingmuTop = parentEl.getBoundingClientRect().top; //画布距离屏幕上面的距离 这里要计算出触摸距离当前画布的距离好进行移动 var pingmuLeft = parentEl.getBoundingClientRect().left; //画布距离屏幕左面的距离 canvasEl.ontouchstart = (e) => { var left = e.touches[0].pageX - pingmuLeft var top = e.touches[0].pageY - pingmuTop if (this.selectBox(left, top)) { canvasEl.ontouchmove = (e) => { serviceData[this.selectedIndex] = [e.touches[0].pageX - pingmuLeft, e.touches[0].pageY - pingmuTop]; this.setData({ serviceData: serviceData }) } } } canvasEl.ontouchend = (e) => { this.selectedIndex = null canvasEl.ontouchmove = null; this.setData({ serviceData: serviceData }) var left = e.changedTouches[0].pageX - pingmuLeft var top = e.changedTouches[0].pageY - pingmuTop if (this.selectBox(left, top)) { this.props.change(serviceData) } }; } selectBox(x, y) {//判断是否选中 let { serviceData, circleRadius, circleBorderWidth } = this.state; let rangeMax = circleRadius + circleBorderWidth; this.selectedIndex = null;//选中点后把下面传过去 for (var i = 0; i < serviceData.length; i++) { var dianX = serviceData[i][0]; var dianY = serviceData[i][1]; if ((dianX - x) * (dianX - x) + (dianY - y) * (dianY - y) < rangeMax * rangeMax) { this.selectedIndex = i;//选中后返回下标然后返回真 return true } } if (i == serviceData.length) { return false } } setData(data) {//设置值发生变化重新画 this.setState(data, () => { this.draw() }) } render() { let { id, width, height } = this.state; return () } }