vue实现悬浮拖拽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | <template> <div class = "ys-float-btn" :style= "{'width':itemWidth+'px','height':itemHeight+'px','left':left+'px','top':top+'px'}" ref = "div" @click = "onBtnClicked" > <slot name= "icon" ></slot> <image class = "su_img" src= "@/assets/images/nosaas-icon_ problem.png" ></image> </div> </template> <script> export default { name: "dragPressButton" , props:{ itemWidth:{ type:Number, default :60 }, itemHeight:{ type:Number, default :60 }, gapWidth:{ type:Number, default :10 }, coefficientHeight:{ type:Number, default :0.8 } }, created(){ this .clientWidth = document.documentElement.clientWidth; this .clientHeight = document.documentElement.clientHeight; this .left = this .clientWidth - this .itemWidth - this .gapWidth; this .top = this .clientHeight* this .coefficientHeight; }, mounted(){ this .$nextTick(()=>{ const div = this .$refs.div; div.addEventListener( "touchstart" ,(e)=>{ e.stopPropagation(); div.style.transition = 'none' ; }); div.addEventListener( "touchmove" ,(e)=>{ e.stopPropagation(); if (e.targetTouches.length === 1) { let touch = event .targetTouches[0]; this .left = touch.clientX - this .itemWidth/2; this .top = touch.clientY - this .itemHeight/2; } }, false ); div.addEventListener( "touchend" ,(e)=>{ e.stopPropagation(); div.style.transition = 'all 0.3s' ; if ( this .left> this .clientWidth/2){ this .left = this .clientWidth - this .itemWidth - this .gapWidth; } else { this .left = this .gapWidth; } if ( this .top<=36) { this .top=36+ this .gapWidth } else { let bottom= this .clientHeight-50- this .itemHeight- this .gapWidth console.log(bottom, this .top) if ( this .top>=bottom) { this .top=bottom } } }); }); }, methods:{ onBtnClicked(){ this .$emit( "onFloatBtnClicked" ); }, }, data(){ return { timer: null , currentTop:0, clientWidth:0, clientHeight:0, left:0, top:0, } } } </script> <style lang= "scss" scoped> .ys- float -btn{ background:rgba(56,181,77,1); box-shadow:0 2px 10px 0 rgba(0,0,0,0.1); border-radius:50%; color: #666666; z-index: 20; transition: all 0.3s; display: flex; flex-direction: column; justify-content: center; align-items: center; position: fixed ; bottom: 20vw; img{ width: 50%; height: 50%; object -fit: contain; margin-bottom: 3px; } } .su_img{ width: 40px; height: 40px; margin: 8px 0 0 0; } </style> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了