将 react-draggable 移动到屏幕的一侧?
Posted
技术标签:
【中文标题】将 react-draggable 移动到屏幕的一侧?【英文标题】:Moving react-draggable to side of screen? 【发布时间】:2019-01-07 22:04:03 【问题描述】:我有一个 react-draggable 组件,我希望它的行为类似于 assistive touch
我想在让动画工作之前,我只需要在用户放开拖动时将 x 位置设置为窗口的最左边或最右边,我尝试了以下操作:
import Draggable, ControlPosition from 'react-draggable'; // The default
import * as React from 'react';
import './style.less'
export default class FloatingScreenSpace extends React.Component<, position:ControlPosition>
state =
position: x:90,y:0
draggable: React.RefObject<Draggable> = React.createRef();
onDragEnd = (e:MouseEvent)=>
if(this.draggable.current)
this.setState(
position:
x: 0,
y: e.clientY
)
public render()
return <Draggable position=this.state.position ref=this.draggable onStop=this.onDragEnd>
<div className="floatingActionButton" style= width: '100px', height: '100px' ></div>
</Draggable>
我认为在 setState 函数中将 x 位置设置为 0 会将其设置为屏幕的最左侧,但是这并没有发生。事实上,它似乎根本没有影响。
理想情况下,当用户放手时,我希望将按钮动画到屏幕最近的边缘(上、下、左、右)。
【问题讨论】:
它是否在无条件下工作if(this.draggable.current)
?
@xadm 拖动工作正常,我只是不知道如何在停止拖动后使其动画到屏幕边缘
我很确定拖动是有效的 - onDragEnd
会发生什么 - 有什么反应吗? setState 被执行了吗?
@tweetypi 你能检查一下我的实现吗?另外,如果您有任何问题,请随时提出。
@JordanEnev 我试过了,看起来它可以工作,但没有动画到屏幕边缘,而是捕捉它
【参考方案1】:
在onStop
处理程序中实现辅助触摸行为听起来不错。
请检查我的实现并遵循 cmets:
const Draggable = ReactDraggable
class Example extends React.Component
constructor(props)
super(props)
this.state = position: x:0, y:0
onStop(event, data)
// Viewport (wrapper)
const documentElement = document.documentElement
const wrapperHeight = (window.innerHeight || documentElement.clientHeight)
const wrapperWidth = (window.innerWidth || documentElement.clientWidth)
// Draggable element center coordinates (x,y)
// Here we assume that the Draggable Button (from the question)
// is a rectangle. But we can easily change it with whatever
// figure we want and fine-tune the calculation.
// Credits: https://***.com/a/18932029/4312466
const center =
x: data.x + (data.node.clientWidth / 2),
y: data.y + (data.node.clientHeight / 2)
// The margin from the draggable's center,
// to the viewport sides (top, left, bottom, right)
const margin =
top: center.y - 0,
left: center.x - 0,
bottom: wrapperHeight - center.y,
right: wrapperWidth - center.x
// When we get the nearest viewport side (below), then we can
// use these metrics to calculate the new draggable sticky `position`
const position =
top: y: 0, x: data.x ,
left: y: data.y, x: 0 ,
bottom: y: (wrapperHeight - data.node.clientHeight), x: data.x ,
right: y: data.y, x: (wrapperWidth - data.node.clientWidth)
// Knowing the draggable's margins to the viewport sides,
// now we can sort them out and get the smaller one.
// The smallest margin defines the nearest viewport side to draggable.
const sorted = Object.keys(margin).sort((a,b) => margin[a]-margin[b])
const nearestSide = sorted[0]
this.setState( position: position[nearestSide] )
render()
return <Draggable
position=this.state.position
onStop=(event, data) => this.onStop(event, data)
>
<div className='handle'>Drag</div>
</Draggable>
ReactDOM.render(
<Example />,
document.getElementById('container')
)
body
overflow-x: hidden;
overflow-y: hidden;
padding: 0;
margin: 0;
.handle
width: 40px;
height: 40px;
line-height: 40px;
background-color: #2662c1;
color: #fff;
cursor: move;
text-align: center;
.handle:not(.react-draggable-dragging)
-webkit-transition: -webkit-transform 0.5s ease-out; /* Safari */
transition: transform 0.5s ease-out;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://unpkg.com/react-draggable@3.0.5/dist/react-draggable.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
【讨论】:
我对这个包做了很多工作,直到我意识到实现“可放置”空间的概念需要做多少工作。不过,这是一个很棒的实现。 听到这个消息我真的很高兴!谢谢?以上是关于将 react-draggable 移动到屏幕的一侧?的主要内容,如果未能解决你的问题,请参考以下文章
使用react-draggable和react-resizable实现Ant Design Modal的拖动和拖拽改变宽度
使用react-draggable和react-resizable实现Ant Design Modal的拖动和拖拽改变宽度