2017-01-14 32 views
0

我需要能夠使畫布元素內的矩形選擇。 這裏有一個小codepen,顯示我試圖實現一個近似的功能:http://codepen.io/yakovenkodenis/pen/EZyBjm矩形選框內作出反應組件MouseMove事件

我周圍的一派,發現了幾個例子,但他們大多沒有使用canvas元素,但div代替。我試圖將這個「div方法」整合到我的React組件中,但它不起作用。

我有一個可控陣營組件調用CanvasVideo是controlls的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的矩形選擇,獲取該矩形相對於畫布大小的座標,以及o在mouseup事件中,將這些座標分配到VideoContainer組件的狀態。

我試圖將this example整合到我的組件中,但是選擇不起作用,而且它本身有點bug。


您能否幫我正確實施此功能?

+0

對不起,我不清楚你的問題是什麼?問題實際上沒有任何反應,但畫布選擇?第二個例子可以繪製一個畫布並執行那個? – FabioCosta

+0

@FabioCosta那麼,第二個例子實際上不能畫一個畫布(如果你把div元素改成一個畫布元素,這個例子就會中斷)。我的問題是將第一個示例的功能集成到我的反應組件中。事情是,第一個例子不適用於畫布,只有div。這就是爲什麼我在這裏發佈這個問題的原因。我認爲這個問題仍然與React有關,因爲它是關於正確使用ref,在組件上設置正確的事件監聽器,總而言之,它是關於實現我需要的功能「React方式」。 –

+0

React上的一些內容沒有很好的定義。如果你需要用dom做一些瘋狂的事情,那麼反應的方式就是使用你已經使用的Refs等等。更多的反應方式海事組織將通過像組件和重繪,但如果我理解正確重繪是不希望的 – FabioCosta

回答

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安排畫布繪製有更好的表現。

如果我理解正確的話,你需要在畫布上繪製更多的事情。如果是這樣,您可以將組件作爲疊加層使用在另一個畫布組件的頂部,或者修改它以繪製所需的其他內容。