canvas尺寸自适应,canvas点位获取,标尺跟随鼠标移动

React+canvas

React.js

自适应:less里面设置rem会变形,所以用fontSize在页面设置canvas的尺寸。

父类div:为positionrelative,里面的canvas为positionabsolute;比较好计算距离屏幕的距离。

标尺跟随鼠标移动:跟随鼠标移动的标尺positionabsolute;比较好计算距离屏幕的距离。

 

class SecondaryZone extends Component {

  state = {

    isBut: {

      isButEdit: true,

      isButReset: false,

      isButSave: false,

    },

    scenemarList: []

  }

  componentDidMount() {

    const { isBut } = this.state

    let { secondaryZone, isButEdit } = this.props

    isBut.isButEdit = isButEdit

    this.setState({ isBut, scenemarList: secondaryZone }, () => {

      this.setCanvas()

    })

  }

// 数值渲染到canvas上面

  setCanvas = () => {

    const { scenemarList } = this.state

    const { fontSize } = this.props

    const c = document.getElementById("canvasBox");

    const cxt = c.getContext("2d");

    cxt.clearRect(0, 0, c.width, c.height);

    cxt.beginPath();

    cxt.strokeStyle = "#000";

    cxt.lineWidth = 0.2 * fontSize;

    cxt.fillStyle = "#000";

    

    if (scenemarList) { 

      cxt.beginPath();

      cxt.strokeStyle = "#FEF448";

      cxt.setLineDash([4, 4]);

      for (var k in scenemarList) {

        if (k === 0) {

          // cxt.moveTo(scenemarList[k][0] / 16 * fontSize, scenemarList[k][1] / 16 * fontSize);

          cxt.moveTo(scenemarList[k][0], scenemarList[k][1]);

        } else {

          // cxt.lineTo(scenemarList[k][0] / 16 * fontSize, scenemarList[k][1] / 16 * fontSize);

          cxt.lineTo(scenemarList[k][0], scenemarList[k][1]);

        }

      }

      cxt.closePath();

      cxt.stroke();

    }

  }

 

  // canvas 点击事件,添加点位

  changeCanvas = (event) => {

    const { isBut } = this.state

    if (isBut.isButSave) {

      const pointTop = document.getElementsByClassName("videoBox")[0].offsetTop

      const pointLeft = document.getElementsByClassName("videoBox")[0].offsetLeft

      const addModalTop = document.getElementsByClassName("secondary")[0].offsetTop

      const addModalLeft = document.getElementsByClassName("secondary")[0].offsetLeft

      const top = event.pageY - pointTop - addModalTop

      const left = event.pageX - pointLeft - addModalLeft

      // console.log("top:", top, top / 16, "   left:", left, left / 16)

      let { scenemarList } = this.state

      const scenemarArr = Object.keys(scenemarList)

      scenemarList[scenemarArr.length] = [left, top]

      this.setState({ scenemarList }, this.setCanvas)

    }

  }

 

  //场景设置,鼠标移动

  canvasMouseMove = (event) => {

    if (document.getElementsByClassName("canvasX")[0]) {

      const pointTop = document.getElementsByClassName("videoBox")[0].offsetTop

      const pointLeft = document.getElementsByClassName("videoBox")[0].offsetLeft

      const addModalTop = document.getElementsByClassName("secondary")[0].offsetTop

      const addModalLeft = document.getElementsByClassName("secondary")[0].offsetLeft

      const top = event.pageY - pointTop - addModalTop

      const left = event.pageX - pointLeft - addModalLeft

      if (event.pageY - top >= 0) {

        document.getElementsByClassName("canvasX")[0].style.top = top + "px";

      }

      if (event.pageX - left >= 0) {

        document.getElementsByClassName("canvasY")[0].style.left = left + "px";

      }

    }

  }

 

  render() {

    const { fontSize, saveModle, cancelModle } = this.props

    const { isBut, scenemarList } = this.state

    return <div className="secondaryZone">

      <div className="videoBac">

        <div className="videoBox">

          <video id="video" width={fontSize * 75.2} height={fontSize * 41.25}></video>

          <canvas id="canvasBox" width={fontSize * 75.2} height={fontSize * 41.25} onClick={this.changeCanvas} onMouseMove={this.canvasMouseMove}></canvas>

          {isBut.isButSave ? <div className="canvasX"></div> : ""}

          {isBut.isButSave ? <div className="canvasY"></div> : ""}

        </div>

      </div>

    </div>

  }

}

export default SecondaryZone

 

 

Less

.secondaryZone {

  min-height: 52rem;

  .videoBac {

    width: 83.13rem;

    height: 50rem;

    background: url(../img/videoBig.svg) no-repeat;

    background-size: 100%;

 

    .videoBox {

      width: 75.2rem;

      height: 41.25rem;

      position: relative;

      z-index: 888;

      right: 0;

      left: 0;

      top: 4.12rem;

      margin: auto;

      > video {

        position: absolute;

        top: 0;

        left: 0;

        transform: rotateY(180deg);

        width: 100%;

        height: 100%;

      }

      #canvasBox {

        position: absolute;

        top: 0;

        left: 0;

        width: 100%;

        height: 100%;

        z-index: 100;

      }

      .canvasX {

        border-top: 1px dashed pink;

        width: 100%;

        position: absolute;

        top: 0;

        left: 0;

      }

      .canvasY {

        border-left: 1px dashed pink;

        width: 1px;

        height: 100%;

        position: absolute;

        top: 0;

        left: 0;

      }

    }

  }

}

 

posted @ 2020-06-17 14:01  米娅m  阅读(654)  评论(0编辑  收藏  举报