基于Vue實(shí)現(xiàn)圖片在指定區(qū)域內(nèi)移動(dòng)的思路詳解
當(dāng)圖片比要顯示的區(qū)域大時(shí),需要將多余的部分隱藏掉,我們可以通過(guò)絕對(duì)定位來(lái)實(shí)現(xiàn),并通過(guò)動(dòng)態(tài)修改圖片的left值和top值從而實(shí)現(xiàn)圖片的移動(dòng)。具體實(shí)現(xiàn)效果如下圖,如果我們移動(dòng)的是div 實(shí)現(xiàn)思路相仿。
此處需要注意的是
我們?cè)谝苿?dòng)圖片時(shí),需要通過(guò)draggable="false"
將圖片的 <img src="/static/pano-dev/test/image-2.jpg" draggable="false" />,
否則按下鼠標(biāo)監(jiān)聽(tīng)onmousemove事件時(shí)監(jiān)聽(tīng)不到
然后還需要禁用圖片的選中css
/*禁止元素選中*/ -moz-user-select: none; /*火狐*/ -webkit-user-select: none; /*webkit瀏覽器*/ -ms-user-select: none; /*IE10*/ -khtml-user-select: none; /*早期瀏覽器*/ user-select: none;
Vue 代碼
<style lang="less" scoped> @import url("./test.less"); </style> <template> <div class="page"> <div class="image-move-wapper"> <div class="image-show-box" ref="imageShowBox"> <div class="drag-container" ref="dragContainer" :style="'left:' + dragContainer.newPoint.left+'px; top:' + dragContainer.newPoint.top+'px'" @mousedown="DragContainerMouseDown"> <div class="drag-image-box"> <img src="/static/pano-dev/test/image-2.jpg" draggable="false" /> <div class="point" style="left:10%; top:10%" @mousedown="PointMouseDown"></div> </div> </div> </div> </div> </div> </template> <script> export default { data() { return { dragContainer: { box: { w: 0, h: 0 }, point: { left: 0, top: 0 }, newPoint: { left: 0, top: 0 } }, mousePoint: { x: 0, y: 0 }, imageShowBox: { box: { w: 0, h: 0 }, dragcheck: { h: true, v: true } } }; }, updated() { let _this = this; // 確保DOM元素已經(jīng)渲染成功,然后獲取拖拽容器和顯示區(qū)域的大小 _this.$nextTick(function() { _this.dragContainer.box = { w: _this.$refs.dragContainer.offsetWidth, h: _this.$refs.dragContainer.offsetHeight }; _this.imageShowBox.box = { w: _this.$refs.imageShowBox.offsetWidth, h: _this.$refs.imageShowBox.offsetHeight }; // 判斷是否允許拖拽 _this.imageShowBox.dragcheck = { h: _this.imageShowBox.box.w > _this.dragContainer.box.w ? false : true, v: _this.imageShowBox.box.h > _this.dragContainer.box.h ? false : true }; }); }, methods: { // 鼠標(biāo)在拖拽容器中按下時(shí)觸發(fā) DragContainerMouseDown(e) { const _this = this; // 記錄鼠標(biāo)點(diǎn)擊時(shí)的初始坐標(biāo) this.mousePoint = { x: e.clientX, y: e.clientY }; _this.dragContainer.point = _this.dragContainer.newPoint; document.body.onmousemove = _this.DragContainerMouseMove; document.onmouseup = _this.DragContainerMouseUp; return false; }, // 容器拖拽時(shí)觸發(fā) DragContainerMouseMove(e) { const _this = this; // 鼠標(biāo)偏移量 = 初始坐標(biāo) - 當(dāng)前坐標(biāo) let dx = e.clientX - _this.mousePoint.x; let dy = e.clientY - _this.mousePoint.y; // 獲取拖拽容器移動(dòng)后的left和top值 if (_this.imageShowBox.dragcheck.h) var newx = dx > 0 ? Math.min(0, _this.dragContainer.point.left + dx) : Math.max(- _this.dragContainer.box.w + _this.imageShowBox.box.w, _this.dragContainer.point.left + dx ); if (_this.imageShowBox.dragcheck.v) var newy = dy > 0 ? Math.min(0, _this.dragContainer.point.top + dy) : Math.max(- _this.dragContainer.box.h + _this.imageShowBox.box.h, _this.dragContainer.point.top + dy ); _this.dragContainer.newPoint = { left: typeof newx != 'undefined' ? newx : _this.dragContainer.point.left, top: typeof newy != 'undefined' ? newy : _this.dragContainer.point.top }; console.log(_this.dragContainer.newPoint); return false; }, // 移動(dòng)完成 取消onmousemove和onmouseup事件 DragContainerMouseUp(e) { document.body.onmousemove = null; document.onmouseup = null; }, PointMouseDown(e) { //阻止事件冒泡 e.stopPropagation(); } } }; </script>
樣式表
.page { background: #444; width: 100%; height: 100%; position: relative; .image-move-wapper { position: absolute; right: 50px; top: 50px; background: #fff; box-shadow: rgba(255, 255, 255, 0.5); padding: 10px; } .image-show-box { height: 400px; width: 400px; cursor: move; overflow: hidden; position: relative; .drag-container { position: absolute; left: 0px; top: 0; /*禁止元素選中*/ -moz-user-select: none; /*火狐*/ -webkit-user-select: none; /*webkit瀏覽器*/ -ms-user-select: none; /*IE10*/ -khtml-user-select: none; /*早期瀏覽器*/ user-select: none; .drag-image-box { position: relative; .point { position: absolute; background: red; height: 30px; width: 30px; border-radius: 50%; } } } } }
總結(jié)
以上所述是小編給大家介紹的基于Vue實(shí)現(xiàn)圖片在指定區(qū)域內(nèi)移動(dòng)的思路詳解,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
相關(guān)文章
Vue安裝sass-loader和node-sass版本匹配的報(bào)錯(cuò)問(wèn)題
這篇文章主要介紹了Vue安裝sass-loader和node-sass版本匹配的報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04vue2與vue3雙向數(shù)據(jù)綁定的區(qū)別說(shuō)明
這篇文章主要介紹了vue2與vue3雙向數(shù)據(jù)綁定的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue實(shí)現(xiàn)個(gè)人信息查看和密碼修改功能
本文通過(guò)實(shí)例代碼給大家介紹了vue實(shí)現(xiàn)個(gè)人信息查看和密碼修改功能,文中給大家補(bǔ)充介紹了vue實(shí)現(xiàn)密碼顯示隱藏切換功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,感興趣的朋友一起看看吧2018-05-05vue實(shí)現(xiàn)全選組件封裝實(shí)例詳解
這篇文章主要介紹了vue?全選組件封裝,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02區(qū)分vue-router的hash和history模式
這篇文章主要介紹了區(qū)分vue-router的hash和history模式,幫助大家更好的理解和學(xué)習(xí)vue路由,感興趣的朋友可以了解下2020-10-10