在MouseMove事件上的React组件内的画布上选择矩形

时间:2017-01-14 19:14:34

标签: javascript html5 reactjs canvas html5-canvas

我需要能够在canvas元素中进行矩形选择。 这是一个小型的编解码器,显示了我正在尝试实现的近似功能:http://codepen.io/yakovenkodenis/pen/EZyBjm

我已经用Google搜索并找到了几个示例,但他们大部分都没有使用canvas元素,而是使用了div。我试图将这个“div方法”集成到我的React组件中,但它没有用。

我有一个名为CanvasVideo的受控React组件来控制canvas元素,这是其中的一部分:

export default class CanvasVideo extends Component {
    // ............... more stuff above ...........
    getCanvas() {
        return this.refs.canvas;
    }

    render () {
        return (
            <div className="canvas-video">
                <canvas
                    height={this.props.height}
                    ref="canvas"
                    width={this.props.width}
                />
            </div>
        );
    }
}

我在另一个名为VideoContainer的组件中使用此组件:

class VideoContainer extends Component {
    componentDidMount() {
        const { video } = this.refs;

        // this is how I can access the actual canvas DOM element.
        const canvas = video.getCanvas();
    }
    render() {
        const videoSrc = {
            src: 'http://www.w3schools.com/html/mov_bbb.mp4',
            type: 'video/mp4'
        };

        return (
            <div className="canvas-video">
                <CanvasVideo
                    autoPlay={true}
                    height={480}
                    width={640}
                    loop={true}
                    muted={true}
                    ref='video'
                    src={videoSrc}
                />
            </div>
        );
    }
}

在我的VideoContainer内我需要能够进行矩形选择,类似于codepen above中的那些,获取该矩形相对于画布大小和mouseup事件的坐标将这些坐标分配到VideoContainer组件的状态。

我尝试将this example集成到我的组件中,但选择不起作用,而且,它本身就有点儿错误。

您能帮我正确实现此功能吗?

1 个答案:

答案 0 :(得分:2)

这里是使用画布进行矩形选择的React组件的demo implementation

这是逻辑的核心:

  onMouseDown = (e) => {
    this.isDrag = true
    this.curX = this.startX = e.offsetX
    this.curY = this.startY = e.offsetY
    requestAnimationFrame(this.updateCanvas)
  };

  onMouseMove = (e) => {
    if (! this.isDrag) return
    this.curX = e.offsetX
    this.curY = e.offsetY
  };

  onMouseUp = (e) => {
    this.isDrag = false

    const rect = {
      x: Math.min(this.startX, this.curX),
      y: Math.min(this.startY, this.curY),
      w: Math.abs(e.offsetX - this.startX),
      h: Math.abs(e.offsetY - this.startY),
    }
    this.props.onSelected(rect)
  };

请注意,此组件使用requestAnimationFrame来调度画布绘图以获得更好的性能。

如果我理解正确,你需要在画布上绘制更多东西。如果是这样,您可以将该组件作为叠加层放在另一个画布组件的顶部,或者修改它以绘制您需要的其他东西。