vue 實現流暢拖動效果


最近在項目上遇到了圖片拖動的需求,自己做了好久效果都不怎么好,最后參考了 vue自定義指令實現div拖動,找到了思路,解決了困惑。不過項目業務上的問題是復雜的,不僅僅能拖動那么簡單,我在工作上遇到的需求如下幾點:

1.實現一個電子地圖,包括底圖和圖標,底圖能拖動,圖標也能拖,圖標拖動時底圖不動

2.滾動鼠標滾輪實現底圖和圖標的縮放,並保持比例,即圖標和底圖的相對位置不變

3.圖標可點擊,點擊選中,圖標樣式變化,能圖標相對坐標,傳入后台保存。

我已開始的思路是:創建一個div,將底圖設為此div的background-image,拖動的時候使用onmousedown,onmousemove和onmouseup,圖標拖動用drag,drop,縮放改變div寬高。后來發現這種方式太不友好了,后面出現的問題越來越多,代碼一行一行增多,體驗越來越差,只要一放大縮小底圖,再拖動圖標就要不斷地計算,相對位置也不准確。雖然勉強做了出來,可是當要改需求的時候,再來改代碼,自己都看不懂,頭皮發麻,重新寫吧!當看到huahua_0825的博客時,頓時眼前一亮,使用自定義指令原來如此簡潔清晰,就在昨天2019/1/1跨年之夜將之前的臃腫代碼剔除了,使用css3 transform scale來縮放,使用它的好處就是不會改變原來元素的大小。

拖動核心代碼(main.js全局指令):

Vue.directive('drag',{

    inserted:function(el,binding){
        el.onmousedown=function(e){
            e.stopPropagation();
            let disx = e.pageX - el.offsetLeft;
            let disy = e.pageY - el.offsetTop;
            document.onmousemove = function (e){
                e.preventDefault();
                el.style.left = e.pageX - disx+'px';
                el.style.top = e.pageY - disy+'px';
            }
            document.onmouseup = function(){
                document.onmousemove = document.onmouseup = null;
                //binding 傳參,可忽略
                if(binding && binding.value){
                    binding.value.clientX=parseInt(el.style.left);
                    binding.value.clientY=parseInt(el.style.top);
                }

            }
        }
    },
});

縮放代碼(main.js全局指令):

Vue.directive('wheel',{
    inserted:function(el){
        el.onmousewheel=function(e){
            // 賦初值
            if(!window.per) window.per=1;
            
            window.per=window.per+(e.deltaY<0?0.1:-0.1);
            window.per=window.per<=0.5?0.5:window.per;
            window.per=window.per>=3.0?3.0:window.per;
            if(window.per>0.5 && window.per<3.0){
                el.style.transform="scale("+window.per+")";
                el.style.transformOrigin=e.offsetX+'px '+e.offsetY+'px';
            }
        }
    }
})

也可以寫成局部指令:

拖動(組件局部指令)

directives: {
    drag: {
      inserted:function(el,binding){
        el.onmousedown=function(e){
            e.stopPropagation();
            let disx = e.pageX - el.offsetLeft;
            let disy = e.pageY - el.offsetTop;
            document.onmousemove = function (e){
                e.preventDefault();
                el.style.left = e.pageX - disx+'px';
                el.style.top = e.pageY - disy+'px';
            }
            document.onmouseup = function(){
                document.onmousemove = document.onmouseup = null;
                //binding 傳參,可忽略
                if(binding && binding.value){
                    binding.value.clientX=parseInt(el.style.left);
                    binding.value.clientY=parseInt(el.style.top);
                }

            }
        }
    }
    }
  }

縮放(組件局部指令)

    wheel:{
      inserted:function(el){
        el.onmousewheel=function(e){
            // 賦初值
            if(!window.per) window.per=1;
            
            window.per=window.per+(e.deltaY<0?0.1:-0.1);
            window.per=window.per<=0.5?0.5:window.per;
            window.per=window.per>=3.0?3.0:window.per;
            if(window.per>0.5 && window.per<3.0){
                el.style.transform="scale("+window.per+")";
                el.style.transformOrigin=e.offsetX+'px '+e.offsetY+'px';
            }
        }
    }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM