The preface

Vue element drag instruction, at the end of the simulation of apple mobile phone touch the ball to achieve automatic docking effect.

The code flow is accompanied by detailed comments that will not be covered in this article.

The code has been recommented in detail and the article has been streamlined (the gold digging theme works brilliantly).

I. Effect drawing:

Two, drag instruction

import Vue from 'vue'; Import autoStop from './methods'; {// Insert: function (el) {// Save the initial state variable let startX; let startY; // parentNode: {clientWidth: pW, clientHeight: {clientWidth: pW, clientHeight: PH}, // Calculate the width and height of the element (if you don't want to completely pull to the side, you can add the corresponding padding to the element) // touchstart event el.addeventlistener ('touchstart', (event) => { // 2, __VueDragTimer__ : Custom timer attributes, with double underscores at the beginning and end mounted on the element, to facilitate the unbind command to clear the timer, and can remove the attribute if (el.__vuedragtimer__) clearInterval(el.__vuedragtimer__); Const {pageX, pageY} = event.touches[0]; Const {// The distance to the left of the element from the limit area. startX = parseInt(pageX - eL); startY = parseInt(pageY - eT); }); // Drag the event el.addeventListener (' touchMove ', (event) => {// Add the event to prevent the elements from being impacted by the event event.preventDefault(); Const {pageX, pageY} = event.touches[0]; let movePageX = parseInt(pageX - startX); let movePageY = parseInt(pageY - startY); If (movePageX <= 0) {movePageX = 0; } else if (movePageX >= pW - eW) { movePageX = pW - eW; } if (movePageY <= 0) { movePageY = 0; } else if (movePageY >= pH - eH) { movePageY = pH - eH; } el.style.left = movePageX + 'px'; el.style.top = movePageY + 'px'; }); // Stop el.adDeventListener (' touchEnd ', () => {autoStop(el); }); }, // When unbinding an element, clear the timer and remove the custom timer attribute mounted on the element unbind: function (el) { if (el.__VueDragTimer__) clearInterval(el.__VueDragTimer__); delete el.__VueDragTimer__; }});Copy the code

Three, automatic docking method

Const autoMove = function (el, changeAttr, endValue) {let currentValue; Const {// left offsetTop: eT, offsetLeft: eL} = eL; If (changeAttr === 'left') currentValue = eL; If (changeAttr === 'top') currentValue = eT; Const step = (endValue-currentValue) / 33; If (el.__vuedragtimer__) clearInterval(el.__vuedragtimer__); // Set the automatic docking timer el.__vuedragtimer__ = setInterval(() => {// If the difference between the current position and the destination is less than the step, then directly locate the destination position (js calculation precision causes this judgment is necessary), If (math.abs (endValue - currentValue) < math.abs (step)) {el.style[changeAttr] = endValue + 'px'; clearInterval(el.__VueDragTimer__); delete el.__VueDragTimer__; } else { currentValue += step; el.style[changeAttr] = currentValue + 'px'; }}, 5); }; /** * automatic docking method: * Docking principle * 1, default left and right docking switch permanently on * 2, up and down docking switch on when the distance between up and down <=50 pixels * 3, final movement direction: */ const autoStop = function (el) {const {// There is a parent element and its width and height (i.e. the area where the element can move). ParentNode: {clientWidth: pW, clientHeight: pH}, EL, // Calculate the width and height of the element (if you don't want to completely pull to the side, you can add the corresponding padding to the element) Dock / * * * * changeAttr configuration: the current configuration scheme change element attributes' top '|' left '* endValue: When the docking animation ends, the value of the property to change (destination) * distance: current configuration, the distance to the destination end * toggle: configuration to switch on */ const stopConfigs = [{// Move up the edge configuration changeAttr: 'top', endValue: 0, distance: eT, toggle: eT <= 50}, {changeAttr: 'top', endValue: ph-eh, distance: Ph-et-eh, toggle: ph-et-eh <= 50}, {// Left edge configuration changeAttr: 'left', endValue: 0, distance: eL, toggle: ChangeAttr: 'left', endValue: pw-ew, distance: pw-el-ew, toggle: true}]; // Select the configuration whose switch is true from the reconfiguration, and then select the configuration with the smallest value according to distance. ChangeAttr, endValue const {changeAttr, endValue} = stopConfigs.filter(o => O.togle).sort((a, b) => a.distance - b.distance)[0]; autoMove(el, changeAttr, endValue); }; export default autoStop;Copy the code