Javascript 在touchmove事件上更改transformX值时,如何计算定位点?
我正在创建一个滑块,通过在容器内水平移动来显示全景图像 正在开发的功能或意图: 默认情况下,动画自动发生,在每个步骤中更改transformX值; 用户能够触摸元素并将其向左或向右拖动; 触发touchend事件时,滑块将从用户拖动的x位置恢复动画; 问题在于,当用户触摸该元素并开始拖动时,transformX上的输入值会使该元素跳跃,这显然是因为用户每次触摸可拖动的元素时,定位点都不同 我想知道的是,如何计算锚点或位置,用户从何处拖动?或者,最好的做法是始终从同一点计算,以避免出现这种跳跃 目前我做了很多研究,但都没有成功。您可以在下面的链接中找到一个实例。请打开浏览器上的触摸模拟器,因为目前我还不支持鼠标拖动 您还可以根据jQuery查看以下代码: sass: html: Javascript:Javascript 在touchmove事件上更改transformX值时,如何计算定位点?,javascript,jquery,touch,css-transforms,Javascript,Jquery,Touch,Css Transforms,我正在创建一个滑块,通过在容器内水平移动来显示全景图像 正在开发的功能或意图: 默认情况下,动画自动发生,在每个步骤中更改transformX值; 用户能够触摸元素并将其向左或向右拖动; 触发touchend事件时,滑块将从用户拖动的x位置恢复动画; 问题在于,当用户触摸该元素并开始拖动时,transformX上的输入值会使该元素跳跃,这显然是因为用户每次触摸可拖动的元素时,定位点都不同 我想知道的是,如何计算锚点或位置,用户从何处拖动?或者,最好的做法是始终从同一点计算,以避免出现这种跳跃 目
/*globals $, window */
'use strict';
$('document').ready(function () {
var panorama = {
// properties
$panorama: $('.panorama'),
$moveElement: $('.panorama img'),
timestart: 0,
seconds: 12,
msTotal: 0,
direction: -1,
positionX: 0,
percentage: 0,
animationFrameID: false,
myRequestAnimationFrame: (function () {
return function (callback) {
return window.setTimeout(callback, 1000 / 60);
};
})(),
touchPlayTimeout: 3000,
moveTimeoutID: null,
rightBoundary: null,
// methods
step: function (timestart) {
var self = this,
timestamp,
positionX;
timestamp = Date.now();
self.progress = timestamp - timestart;
self.percentage = (self.progress * (100 / self.msTotal));
positionX = self.direction * self.percentage;
positionX = self.positionBounderies(positionX);
positionX += '%';
self.position(positionX);
if (self.progress < self.msTotal) {
timestamp += 10;
self.animationFrameID = self.myRequestAnimationFrame(function () {
self.step.call(self, timestart);
});
}
},
positionBounderies: function (positionX) {
// move the next line to init method, after image preload done!
this.rightBoundary = 100 - (100 * (this.$panorama.width() / this.$moveElement.width()));
positionX = positionX > 0 ? 0 : positionX;
positionX = (positionX < 0 && Math.abs(positionX) > this.rightBoundary) ? this.direction * this.rightBoundary : positionX;
return positionX;
},
progressByPercentage: function (percentage) {
return percentage * (this.msTotal / 100);
},
dragIt: function (touchX) {
var positionX,
percentage = (this.progress * (100 / this.msTotal));
positionX = this.direction * percentage;
positionX = positionX + (touchX / 100);
positionX = this.positionBounderies(positionX);
positionX += '%';
// update percentage
this.percentage = Math.abs(parseFloat(positionX));
this.position(positionX);
},
position: function (posX) {
this.$moveElement.css('transform', 'translateX(' + posX + ')');
},
init: function () {
var self = this;
// set initial values
this.msTotal = this.seconds * 1000;
// set listeners
this.$moveElement.on('touchstart mousedown', function (e) {
// on mousedown prevent browser default `img` drag
e.preventDefault();
clearTimeout(self.animationFrameID);
clearTimeout(self.moveTimeoutID);
});
this.$moveElement.on('touchend mouseup', function (e) {
// on mousedown prevent browser default `img` drag
e.preventDefault();
// calculate where to play from using current progress
var playFrom = null;
self.progress = self.progressByPercentage(self.percentage);
self.moveTimeoutID = setTimeout(function () {
clearTimeout(self.moveTimeoutID);
playFrom = Date.now();
playFrom = playFrom - self.progress;
self.step(playFrom);
}, self.touchPlayTimeout);
});
this.$moveElement.on('touchmove', function (e) {
console.log(e);
var touch = e.originalEvent.touches[0],
touchPosition = touch.pageX - self.$panorama.width();
self.dragIt(touchPosition);
});
this.step(Date.now());
}
};
panorama.init();
});
我发现我的问题与我如何计算阻力距离有关。上面的代码清楚地表明,我只使用pageX的位置来计算transformX,这是绝对错误的。正确的方法是存储开始拖动的起点,并且应使用当前的拖动x值来计算距离 比如说,
this.$moveElement.on('touchstart mousedown', function (e) {
var touch = e.originalEvent.touches[0];
self.touchDistance.start = touch.pageX;
});
this.$moveElement.on('touchmove', function (e) {
var touch = e.originalEvent.touches[0],
distance = 0;
self.touchDistance.end = touch.pageX;
distance = self.touchDistance.end - self.touchDistance.start;
self.dragIt(distance);
});
有了这个,我有了一个有效的解决方案,正如我们在这里看到的
感谢您的关注,希望这对以后的其他人有用 哈哈,试图找出一个类似的问题,来到这里,在这篇帖子上找到了我自己的答案,很有趣:D
/*globals $, window */
'use strict';
$('document').ready(function () {
var panorama = {
// properties
$panorama: $('.panorama'),
$moveElement: $('.panorama img'),
timestart: 0,
seconds: 12,
msTotal: 0,
direction: -1,
positionX: 0,
percentage: 0,
animationFrameID: false,
myRequestAnimationFrame: (function () {
return function (callback) {
return window.setTimeout(callback, 1000 / 60);
};
})(),
touchPlayTimeout: 3000,
moveTimeoutID: null,
rightBoundary: null,
// methods
step: function (timestart) {
var self = this,
timestamp,
positionX;
timestamp = Date.now();
self.progress = timestamp - timestart;
self.percentage = (self.progress * (100 / self.msTotal));
positionX = self.direction * self.percentage;
positionX = self.positionBounderies(positionX);
positionX += '%';
self.position(positionX);
if (self.progress < self.msTotal) {
timestamp += 10;
self.animationFrameID = self.myRequestAnimationFrame(function () {
self.step.call(self, timestart);
});
}
},
positionBounderies: function (positionX) {
// move the next line to init method, after image preload done!
this.rightBoundary = 100 - (100 * (this.$panorama.width() / this.$moveElement.width()));
positionX = positionX > 0 ? 0 : positionX;
positionX = (positionX < 0 && Math.abs(positionX) > this.rightBoundary) ? this.direction * this.rightBoundary : positionX;
return positionX;
},
progressByPercentage: function (percentage) {
return percentage * (this.msTotal / 100);
},
dragIt: function (touchX) {
var positionX,
percentage = (this.progress * (100 / this.msTotal));
positionX = this.direction * percentage;
positionX = positionX + (touchX / 100);
positionX = this.positionBounderies(positionX);
positionX += '%';
// update percentage
this.percentage = Math.abs(parseFloat(positionX));
this.position(positionX);
},
position: function (posX) {
this.$moveElement.css('transform', 'translateX(' + posX + ')');
},
init: function () {
var self = this;
// set initial values
this.msTotal = this.seconds * 1000;
// set listeners
this.$moveElement.on('touchstart mousedown', function (e) {
// on mousedown prevent browser default `img` drag
e.preventDefault();
clearTimeout(self.animationFrameID);
clearTimeout(self.moveTimeoutID);
});
this.$moveElement.on('touchend mouseup', function (e) {
// on mousedown prevent browser default `img` drag
e.preventDefault();
// calculate where to play from using current progress
var playFrom = null;
self.progress = self.progressByPercentage(self.percentage);
self.moveTimeoutID = setTimeout(function () {
clearTimeout(self.moveTimeoutID);
playFrom = Date.now();
playFrom = playFrom - self.progress;
self.step(playFrom);
}, self.touchPlayTimeout);
});
this.$moveElement.on('touchmove', function (e) {
console.log(e);
var touch = e.originalEvent.touches[0],
touchPosition = touch.pageX - self.$panorama.width();
self.dragIt(touchPosition);
});
this.step(Date.now());
}
};
panorama.init();
});
this.$moveElement.on('touchstart mousedown', function (e) {
var touch = e.originalEvent.touches[0];
self.touchDistance.start = touch.pageX;
});
this.$moveElement.on('touchmove', function (e) {
var touch = e.originalEvent.touches[0],
distance = 0;
self.touchDistance.end = touch.pageX;
distance = self.touchDistance.end - self.touchDistance.start;
self.dragIt(distance);
});