鼠标按下时,旋转补间停止和补间开始

时间:2018-04-28 19:46:49

标签: javascript three.js

我有一个在z轴上旋转的物体。 onMouseDown旋转停止,onMouseUp旋转在2秒后恢复。 是否有一种方法可以让旋转缓慢恢复(比如容易进行css)?

旋转开始和停止的代码。

                if ( etaj1 !== undefined ) {
                    etaj1.rotation.z += delta * 0;
                    if(!isMouseDown){
                        etaj1.rotation.z += delta * 0.05 ;

                    }
                }

如果在2秒过后再次点击,则会出现resetTimer条件。

            var timerHandle = setTimeout (wait , 2000);
            function resetTimer () {
                window.clearTimeout (timerHandle);
                timerHandle = setTimeout (wait , 2000);
            }

            function onMouseDown(){
                console.log("Mouse DOWN");
                isMouseDown = true;               
            }

            function onMouseUp(){                   
                window.clearTimeout (timerHandle);
                timerHandle = setTimeout (wait , 2000);                 
            }

            function wait (){
                resetTimer;
                console.log("Mouse UP");
                isMouseDown = false;
            }

我们的想法是为isMouseDown = false;进行转换,为isMouseDown = true;

进行另一次转换

基本上我想做的是使用quart.out补间从下面的链接停止旋转,等待2秒,如果没有点击恢复使用夸脱夸脱的旋转。

https://threejs.org/examples/#webgl_loader_collada

感谢。

1 个答案:

答案 0 :(得分:1)

我不是一个三人家伙,不过你所要求的也适用于其他领域。所以我将在这里提出一般解决方案。首先是概念证明:

https://jsfiddle.net/ibowankenobi/u4xwnLam/4/

我将开始声明我需要的全局变量,并根据需要将它们包起来:

var rotation = 0;
var bar = document.getElementById("bar");
var container = document.getElementById("container");

我需要在没有three.js的情况下展示这个,所以我需要一个容器和一些旋转的东西,这样你就不需要barcontainer了。您的案例中的轮换是etaj1.rotation.z

我们首先需要一个将0-1再次映射到0-1的函数,但不是线性的。这些被称为插值,有许多,余弦,这,其中,最广泛使用的是一个缝合和变换的x ^ 3,并且给出了慢速输出"影响:

 function slowInSlowOut(t){
    if(2*t<<0){
        return 4*(t-1)*(t-1)*(t-1)+1;
    } else {
        return 4*t*t*t;
    }
}

我们必须对此功能执行某些操作,因此我将编写另一个动画

function changeSpeed(obj,newSpeed){
    var oldSpeed = obj.__oldSpeed || 0;
    var startTime;
    newSpeed = newSpeed || 0;
    obj.__currentFrame && window.cancelAnimationFrame(obj.__currentFrame);//cancel a previous changeSpeed if fired twice
    obj.__currentFrame = window.requestAnimationFrame(anim);
    function anim(t){
        startTime = startTime || t;
        var elapsed = t - startTime,
            parametric = slowInSlowOut(elapsed/2000);
        if(parametric>=1){
            obj.__oldSpeed = newSpeed;
        } else {
            obj.__oldSpeed = newSpeed + (oldSpeed-newSpeed) * (1-parametric);
            obj.__currentFrame = window.requestAnimationFrame(anim);
        }
    }
}

您为此函数提供了一个对象,它将附加一个专有的__oldSpeed属性,newSpeed参数以度/ 17ms 的方式测量(因为我是使用requestAnimationFrame并将每次触发~17ms)。因此,在您的情况下,obj是您的etaj1

在此功能中,您可以根据需要更新etaj1.rotation.z。但是我会写第三个函数来持续触发并听取__oldSpeed属性并根据它采取行动:

function animate(obj){
    rotation += (obj.__oldSpeed || 0);
    rotation = rotation % 360;
    obj.style.transform = "rotate("+rotation+"deg)";
    window.requestAnimationFrame(function(){animate(obj)});
}

此处,obj是您的etaj1,轮换是etaj1.rotation.z。我在这里使用DOM,所以我需要使用样式。您可以根据自己的情况进行调整。

Animate不会被解雇,所以我们需要解雇他:

window.requestAnimationFrame(function(){animate(bar)});

我按照你的描述添加eventListeners:

container.addEventListener("mousedown",function(){changeSpeed(bar,0)},false);
container.addEventListener("mouseup",function(){changeSpeed(bar,12)},false);

现在我们给它一个起始速度:

changeSpeed(bar,12);

你去吧。如果你想知道如何自己做,这可能会让你开始。我想使用其他技术堆栈的人也可以根据自己的情况进行调整。

PS:

有人提到延迟,在这种情况下稍微修改changeSpeed

function changeSpeed(obj,newSpeed,delay){
    delay = delay || 0;
    var oldSpeed = obj.__oldSpeed || 0;
    var startTime;
    newSpeed = newSpeed || 0;
    obj.__currentFrame && window.cancelAnimationFrame(obj.__currentFrame);
    obj.__currentFrame = window.requestAnimationFrame(anim);
    function anim(t){
        startTime = startTime || t;
        var elapsed = t - startTime;
    if(elapsed < delay) {
       return obj.__currentFrame = window.requestAnimationFrame(anim);
    }
        var parametric = slowInSlowOut((elapsed-delay)/2000);
        if(parametric>=1){
            obj.__oldSpeed = newSpeed;
        } else {
            obj.__oldSpeed = newSpeed + (oldSpeed-newSpeed) * (1-parametric);
            obj.__currentFrame = window.requestAnimationFrame(anim);
        }
    }
}

这是一个有2秒延迟的小提琴:

https://jsfiddle.net/ibowankenobi/u4xwnLam/10/