2017-04-18 121 views
2

我正在學習cyclejs和遇到一些麻煩,如何使一個div movabble處理。Cyclejs和移動元素x和y

首先,我已經分離,我必須計算3個事件

  • 鼠標按下
  • 鼠標鬆開
  • 鼠標移動

目的是當圖是向下,以產生移動和鼠標移動和停止時,我的MouseUp

下面是我得到了什麼:

import {div} from '@cycle/dom' 
import xs from 'xstream' 

const getStyle = left => top => { 
    return ({ 
     style: { 
      position: 'absolute', 
      left: left + 'px', 
      top: top + 'px', 
      backgroundColor: '#FF0000', 
      cursor: 'pointer' 
     } 
    }) 
} 

function intent(DOMSources) { 
    const marble$ = DOMSources.select('.marble') 
    const marbleDown$ = marble$.events('mousedown') 
    const marbleMove$ = marble$.events('mousemove') 
    const marbleUp$ = marble$.events('mouseup') 
    return {marbleDown$, marbleUp$, marbleMove$} 
} 

function model({marbleDown$, marbleUp$, marbleMove$}) { 
    return xs.combine(marbleDown$, marbleMove$) 
     .map(([marbleDown, marbleMove]) => marbleMove) 
     .map(ev => ({x: ev.pageX, y: ev.pageY})) 
     .endWhen(marbleUp$) 
} 

function view(state$) { 
    return state$ 
     .startWith({x: 0, y: 0}) 
     .map(value => div('.marble', getStyle(value.x)(value.y), 'Move me ! ' + value.x + ' - ' + value.y)) 
} 


export function Marble(sources) { 
    const changes$ = intent(sources.DOM) 
    const state$ = model(changes$) 
    const vTree$ = view(state$) 
    return {DOM: vTree$} 
} 

我的問題似乎出現在模型的一部分。當我輸入div和mousedown並移動元素時,我只能將元素向下和向右移動,而不是向上和向左移動。

我的第二個問題是,當我離開我的鼠標布頓,繼續當我重新把重點放在它移動。

看來我錯過了一些不好的方面。

一個GIF倒不如說千言萬語:

enter image description here

回答

1

你的問題是,你的鼠標是DIV之外,當你將鼠標移動到左。你可以這樣解決這個問題:

function between(first, second) { 
    return (source) => first.mapTo(source.endWhen(second)).flatten() 
} 

function model({marbleDown$, marbleUp$, marbleMove$}) { 
    return xs.combine(marbleDown$, marbleMove$) 
     .map(([marbleDown, marbleMove]) => ({x: marbleMove.pageX - marbleDown.layerX, y: marbleMove.pageY - marbleDown.layerY})) 
     .compose(between(marbleDown$, marbleUp$)) 
} 

但是你會遇到mouseUp事件的問題。由於您在div元素上留下了您的div mouseUp事件等待偵聽器,因此您需要將div放在容器上。並把mouseUp監聽器帶到這個容器元素。例如容器可以是body元素。

const marbleUp$ = DOMSources.select('body').events('mouseup') 

我向你推薦css style for marble div'user-selection':'none'。當您點擊大理石時,這將停用選擇模式。

+0

我在功能之間添加了。這與Rxjs中的takeUntill一樣。有關更多信息,可以查看CycleJS自動完成搜索示例。你的問題幫我找到功能之間,謝謝:) –