zoukankan      html  css  js  c++  java
  • 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 {
    
         83.13rem;
    
        height: 50rem;
    
        background: url(../img/videoBig.svg) no-repeat;
    
        background-size: 100%;
    
     
    
        .videoBox {
    
           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);
    
             100%;
    
            height: 100%;
    
          }
    
          #canvasBox {
    
            position: absolute;
    
            top: 0;
    
            left: 0;
    
             100%;
    
            height: 100%;
    
            z-index: 100;
    
          }
    
          .canvasX {
    
            border-top: 1px dashed pink;
    
             100%;
    
            position: absolute;
    
            top: 0;
    
            left: 0;
    
          }
    
          .canvasY {
    
            border-left: 1px dashed pink;
    
             1px;
    
            height: 100%;
    
            position: absolute;
    
            top: 0;
    
            left: 0;
    
          }
    
        }
    
      }
    
    }
  • 相关阅读:
    Python 进度条
    python多线程的使用
    Python 进程间通信问题—Manager方法
    生产消费者模型(进程通信,队列)
    进程锁 购票问题
    多进程并行实现socket并发代码
    一次完整的socket文件的传输
    python实现基本计算器(可处理括号和负值)
    模拟论坛登录
    JS
  • 原文地址:https://www.cnblogs.com/miam/p/13152116.html
Copyright © 2011-2022 走看看