transform实现一个可以拖拽的图片,跟着鼠标移动,释放鼠标后图片回到初始位置
目标
1,position:absolute实现一个可以拖拽的图片,从位置A拖动到位置B
2,transform实现一个可以拖拽的图片,跟着鼠标移动,释放鼠标后图片回到初始位置
前言
拖拽的事件:
onDragStart:开始拖拽元素onDrag:元素拖拽中onDragEnd:结束拖拽元素onDragEnter:拖拽的元素进入到目标元素时触发onDragLeave:拖拽的元素移出目标元素时触发onDragOver:拖拽的元素在目标元素(容器)范围内拖拽时触发
解决拖拽过程中出现小的缩略图和黑色禁止符号的问题:-webkit-user-drag和draggable
笔者是基于react和ant design,其他框架(或没用框架)也是一样的使用。
一、实现目标:position:absolute将图片从位置A拖动到位置B
笔者这里使用的是绝对定位(position:absolute),原理就是通过改变top和left来修改图片的位置。如果初始位置是固定需要通过bottom和right定位的,可以先转成top和leftcss 鼠标图片,例如:
let h =
- window.innerHeight ||
- document.documentElement.clientHeight ||
- document.body.clientHeight;
- let w =
- window.innerWidth ||
- document.documentElement.clientWidth ||
- document.body.clientWidth;
- setLeft(w - 352);
-
首先获取可视窗口的宽高,用这个宽减去图片的(宽+右边距)即可得到left,高度亦如此,得出top的值,笔者这里为了满足其他需求,在img外层套了个div,设置样式如下:
handleDragStart(e)}
- onDragEnd={(e) => handleDragEnd(e)}
- >
- {}}
- />
-
当鼠标开始拖动时,在onDragStart中记录当前鼠标点击的位置,当鼠标停止拖动时,在onDragEnd中获取两次鼠标位置之差,这个差也就是两次left之差,得出最新的left值,top亦是如此:
const handleDragStart = (e) => {
- setClickLeft(e.clientX);
- setClickTop(e.clientY);
- };
- const handleDragEnd = (e) => {
- setLeft(left - clickLeft + e.clientX);
- setTop(top - clickTop + e.clientY);
-
现在,已经实现将图片从A拖到B的需求,但还要些优化,例如鼠标拖动过程中,显示了黑色禁止图标(cursor),这是因为当我们把拖拽元素拖动到其他地方(目标元素),但目标元素不允许这种行为,所以在目标元素上设置如下:
onDragEnter={(e) => e.preventDefault()}
- onDragLeave={(e) => e.preventDefault()}
-
现在黑色的禁止图标已经没有了。
针对拖拽过程中img会出现小的缩略图的问题,针对img设置WebkitUserDrag(对应css的-webkit-user-drag)为none,会发现这时不可拖拽了,不要慌,这是因为外层的div和img尺寸一样,img作为里层元素不可拖拽,但是只需要在div上加上draggable={true},此时会发现又可以拖拽了,且小的缩略图已经没有了,取而代之的是与img尺寸相同的图片,这是因为拖拽的是整个divcss 鼠标图片,img是div内的元素,所以这个图其实是div的内容。
二、实现目标:transform实现图片跟着鼠标移动,释放鼠标后图片回到初始位置
笔者这里使用的是绝对定位和transform,通过设置偏移量改变图片的位置。这里鼠标移动的距离就是偏移量,因为需要根据鼠标移动,所以加上事件onDrag,代码如下:
const handleDragStart = (e) => {
- setClickLeft(e.clientX);
- setClickTop(e.clientY);
- e.dataTransfer.effectAllowed = "move";
- };
- const handleDrag = (e) => {
- e.preventDefault && e.preventDefault();
- setTranslateX(e.clientX - clickLeft);
- setTranslateY(e.clientY - clickTop);
- };
- const handleDragEnd = (e) => {
- setTranslateX(0);
- setTranslateY(0);
-
根据上文,我们可以很自然的将拖拽元素加上onDragStart和onDragEnd事件,在目标元素上设置onDragEnter、onDragLeave和onDragOver达到拖拽过程中不显示黑色禁止图标的目的。通过draggable={true}和img设置WebkitUserDrag达到去掉拖拽过程中缩略图的效果。
handleDragStart(e)}
- onDrag={(e) => handleDrag(e)}
- onDragEnd={(e) => handleDragEnd(e)}
- draggable={true}
- >
-
-
总结
本篇介绍了两种拖拽图片的方法:
读者可以根据实际情况甄选使用,如有其他建议,欢迎讨论!
发表评论
热门文章
Spimes主题专为博客、自媒体、资讯类的网站设计....
仿制主题,Typecho博客主题,昼夜双版设计,可....
一款个人简历主题,可以简单搭建一下,具体也比较简单....
用于作品展示、资源下载,行业垂直性网站、个人博客,....
油腻男
2天前
感谢分享