Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在touchmove事件上更改transformX值时,如何计算定位点?_Javascript_Jquery_Touch_Css Transforms - Fatal编程技术网

Javascript 在touchmove事件上更改transformX值时,如何计算定位点?

Javascript 在touchmove事件上更改transformX值时,如何计算定位点?,javascript,jquery,touch,css-transforms,Javascript,Jquery,Touch,Css Transforms,我正在创建一个滑块,通过在容器内水平移动来显示全景图像 正在开发的功能或意图: 默认情况下,动画自动发生,在每个步骤中更改transformX值; 用户能够触摸元素并将其向左或向右拖动; 触发touchend事件时,滑块将从用户拖动的x位置恢复动画; 问题在于,当用户触摸该元素并开始拖动时,transformX上的输入值会使该元素跳跃,这显然是因为用户每次触摸可拖动的元素时,定位点都不同 我想知道的是,如何计算锚点或位置,用户从何处拖动?或者,最好的做法是始终从同一点计算,以避免出现这种跳跃 目

我正在创建一个滑块,通过在容器内水平移动来显示全景图像

正在开发的功能或意图:

默认情况下,动画自动发生,在每个步骤中更改transformX值; 用户能够触摸元素并将其向左或向右拖动; 触发touchend事件时,滑块将从用户拖动的x位置恢复动画; 问题在于,当用户触摸该元素并开始拖动时,transformX上的输入值会使该元素跳跃,这显然是因为用户每次触摸可拖动的元素时,定位点都不同

我想知道的是,如何计算锚点或位置,用户从何处拖动?或者,最好的做法是始终从同一点计算,以避免出现这种跳跃

目前我做了很多研究,但都没有成功。您可以在下面的链接中找到一个实例。请打开浏览器上的触摸模拟器,因为目前我还不支持鼠标拖动

您还可以根据jQuery查看以下代码:

sass:

html:

Javascript:

   /*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);

    });