【问题标题】:Rectangle selection on canvas inside React component on MouseMove eventMouseMove 事件中 React 组件内画布上的矩形选择
【发布时间】:2017-01-14 19:14:34
【问题描述】:

我需要能够在画布元素内进行矩形选择。 这是一个小代码笔,显示了我正在尝试实现的近似功能:http://codepen.io/yakovenkodenis/pen/EZyBjm

我用谷歌搜索了几个例子,但他们大多没有使用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 集成到我的组件中,但选择不起作用,而且它本身有点错误。


您能帮我正确实现这个功能吗?

【问题讨论】:

  • 抱歉,我不清楚您的问题是什么?问题实际上与任何反应无关,而是画布选择?第二个示例可以在画布上进行绘制并实现它?
  • @FabioCosta 好吧,第二个示例实际上无法在画布上绘制(如果将那里的 div 元素更改为画布元素,示例将中断)。我的问题是将第一个示例中的功能集成到我的反应组件中。问题是,第一个示例也不适用于画布,只能用于 div。这就是为什么我在 SO 上发布了这个问题。我认为这个问题仍然与 React 相关,因为它是关于正确使用 refs,在组件上设置正确的事件侦听器,并且总的来说,它是关于实现我需要“React 方式”的功能。
  • React 上的一些东西没有很好的定义。如果你需要用 dom 做一些疯狂的事情,那么反应方式就是使用你已经在使用的 Refs 等等。 IMO 更 React 的方式是传递类似 组件并重绘,但如果我理解正确,则不需要重绘

标签: javascript html reactjs canvas html5-canvas


【解决方案1】:

这是一个 demo implementation 的 React 组件,用于使用画布进行矩形选择。

这是逻辑的核心:

  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 来安排画布绘制以获得更好的性能。

如果我理解正确,您需要在画布上绘制更多内容。如果是这样,您可以将该组件用作另一个画布组件之上的叠加层,或者对其进行修改以绘制您需要的其他内容。

【讨论】:

  • “你可以将组件用作另一个画布组件之上的叠加层” --> 我该如何做一个叠加层?
猜你喜欢
  • 2014-06-16
  • 2015-10-20
  • 2022-11-12
  • 2011-06-28
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 2016-12-03
  • 1970-01-01
相关资源
最近更新 更多