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}
          >
            

  总结

  本篇介绍了两种拖拽图片的方法:

  读者可以根据实际情况甄选使用,如有其他建议,欢迎讨论!

文章由官网发布,如若转载,请注明出处:https://www.veimoz.com/1971
0 评论
549

发表评论

!