funAreaSelectPlus.js 7.63 KB
import React, { Component } from 'react';
import FunAreaSelect from "../funAreaSelect/funAreaSelect.js"
export default class FunAreaSelectPlus extends Component {
    constructor() {
        super();
        this.state = {
            id: new Date().getTime() + "waiceng",
            disabled: "false",//判断是否可以移动  false是可以移动
            circleRadius: 5,//圆半径
            circleBorderWidth: 2,//圆边线的半径宽
            circleBorderColor: "#28B1D9",//圆边线的颜色
            circleInColor: "#28B1D9",//圆里里面的颜色
            circleSelectColor: "#FFF",
            lineColor: "#28B1D9",//线的颜色
            lineWidth: 2,//线的宽度
            areaColor: "rgba(40, 177, 217, 0.2)",//选中区域颜色
            disabled: "false",//判断是否可以移动  false是可以移动
            title: "",//文字的内容
            titleColor: "#000",//文字的颜色
            titleFont: "14px bold 黑体",//文字的字体
            titleLineHeight: "",//文字的行高
            position: [10, 10],//文字的位置
        }
    }
    static getDerivedStateFromProps(props, state) {
        var obj = {};
        for (var key in props) {
            if (props[key] && props[key] !== state[key]) {
                if (typeof props[key] === "object") {
                    obj[key] = JSON.parse(JSON.stringify(props[key]))
                } else {
                    obj[key] = props[key]
                }
            }
        }
        if (Object.keys(obj).length > 0) {
            return obj;
        } else {
            return null
        }
    }
    componentDidMount() {
        let {list} = this.props;
        if(list&&list.length>0){
            this.selectIndex = list[list.length - 1].id;
        }
        this.selectArea();
    }
    clickIt(mode) {
        let { list } = this.props;
        var id = new Date().getTime()
        if (!list||list.length === 0) {
            list = []
            list.push({
                id: id,
                mode: mode
            })
            this.selectIndex = id;
        } else {
            var boo = this[list[list.length - 1].id + list[list.length - 1].mode].isNull()//判断画布是否为空

            if (boo) {//画布为空
                this.props.err(false,"画布为空,请先绘制在添加。")
            } else if (!list[list.length - 1].serviceData) {
                this.props.err(false,"画布没有保存,请先绘制完成在添加")
            } else {
                list.push({
                    id: id,
                    mode: mode
                })
                this.selectIndex = id;//这个地方是用来判断当前点击或者添加的第几个,通过这个控制着list父子组件的同时赋值
            }
        }
        this.props.change(list)
    }
    delete(){
        this.props.delete(this.selectIndex,"发出删除指令")
    }
    change(val) {//保存后把最后一个放入这个list中储存,这样可以判断是否储存,点击的时候是否在点内
        let { list } = this.props;
        list  = list.map(item=>{
            if(item.id === this.selectIndex){
                item.serviceData = JSON.parse(JSON.stringify(val));
            }
            return item
        })
        this.props.change(list)
    }
    selectArea() {//选中区域z-index应该增大放在最上面
        let { id } = this.state;
        var waiceng = document.getElementById(id);
        waiceng.onclick = (e) => {
            // let { list } = this.state;
            let list = this.props.list//这里用里this.list因为有时候在change中setState不好使不能设置list怀疑是this指向问题但是打印出来没什么问题所以还没解决
            var left = e.layerX
            var top = e.layerY
            this.indexflag = false;//这里是为了防止点击到重复的区域导致无法选区的情况
            if(list){
                for (var i = 0; i < list.length; i++) {
                    if (list[i].serviceData) {
                        var myRef = this[list[i].id + list[i].mode].state.id;//获取内部id
                        if (this.isInPolygon([left, top], JSON.parse(JSON.stringify(list[i].serviceData)), this[list[i].id + list[i].mode][myRef])) {//选中之后放在最上层
                            var id = this[list[i].id + list[i].mode][myRef].state.id
                            if (this.indexflag) {
                                document.getElementById(id).style.zIndex = 0
                            } else {
                                document.getElementById(id).style.zIndex = 99
                                this.selectIndex = list[i].id;
                                this.indexflag = true
                            }
                        } else {
                            var id = this[list[i].id + list[i].mode][myRef].state.id
                            document.getElementById(id).style.zIndex = 0
                        }
                    }
                }
            }
        }
    }
    isInPolygon(point, vs, childEl) {//判断多边形是否在点内
        var x = point[0], y = point[1];
        var inside = false;
        for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
            var xi = vs[i][0], yi = vs[i][1];
            var xj = vs[j][0], yj = vs[j][1];
            var intersect = ((yi > y) != (yj > y))
                && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
            if (intersect) inside = !inside;
        }
        if (!intersect) {
            if (childEl.selectBox(point[0], point[1])) {
                return true;
            }
        }
        return inside;
    }
    render() {
        let { id, disabled, circleRadius,
            circleBorderWidth,
            circleBorderColor,
            circleInColor,
            circleSelectColor,
            lineColor,
            lineWidth,
            areaColor,
            title,
            titleColor,
            titleFont,
            titleLineHeight,
            position } = this.state;
        let {list} = this.props
        return (
            <div id={id} style={{ width: "100%", height: "100%", position: "relative" }}>
                <button style={{ position: "absolute", right: "-70px", top: "0" }} onClick={() => this.clickIt("react")}>添加矩形</button>
                <button style={{ position: "absolute", right: "-83px", top: "40px" }} onClick={() => this.clickIt("polygon")}>添加多边形</button>
                <button style={{ position: "absolute", right: "-43px", top: "80px" }} onClick={() => this.delete()}>删除</button>
                {
                   list&&list.map((item, index) => {
                        return <FunAreaSelect
                            disabled={disabled}
                            circleRadius={circleRadius}
                            circleBorderWidth={circleBorderWidth}
                            circleBorderColor={circleBorderColor}
                            circleSelectColor={circleSelectColor}
                            circleInColor={circleInColor}
                            lineColor={lineColor}
                            lineWidth={lineWidth}
                            areaColor={areaColor}
                            title={item.title?item.title:""}
                            titleColor={titleColor}
                            titleFont={titleFont}
                            titleLineHeight={titleLineHeight}
                            position={position} key={item.id} serviceData={item.serviceData}ref={(inst) => { this[item.id + item.mode] = inst }} mode={item.mode} change={(val) => this.change(val)}></FunAreaSelect>
                    })
                }
            </div>)
    }
}