【问题标题】:Cyclejs and moving an element by x and yCyclejs并通过x和y移动元素
【发布时间】:2017-04-18 11:25:11
【问题描述】:

我正在学习 cyclejs,但在处理如何使 div 可移动时遇到了一些麻烦。

首先,我隔离了 3 个必须计算的事件

  • 鼠标按下
  • 鼠标移动
  • 鼠标移动

目的是在地图向下和鼠标移动时产生移动,并在鼠标向上时停止

这是我得到的:

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 比一千个单词更好:

【问题讨论】:

    标签: javascript rxjs xstream cyclejs


    【解决方案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 mouseUp 事件等待侦听器留在 div 元素上,所以您需要将 div 放在容器上。并将 mouseUp 侦听器带到此容器元素。例如容器可以是body元素。

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

    我向您推荐大理石 div 'user-selection': 'none' 的 css 样式。当您点击弹珠时,这将停用选择模式。

    【讨论】:

    • 我在函数之间添加了。与 Rxjs 中的 takeUntill 相同。有关更多信息,您可以查看 CycleJS 自动完成搜索示例。你的问题帮助我在功能之间找到,谢谢:)
    猜你喜欢
    • 2019-12-29
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    相关资源
    最近更新 更多