我有一个在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
感谢。
答案 0 :(得分:1)
我不是一个三人家伙,不过你所要求的也适用于其他领域。所以我将在这里提出一般解决方案。首先是概念证明:
https://jsfiddle.net/ibowankenobi/u4xwnLam/4/
我将开始声明我需要的全局变量,并根据需要将它们包起来:
var rotation = 0;
var bar = document.getElementById("bar");
var container = document.getElementById("container");
我需要在没有three.js的情况下展示这个,所以我需要一个容器和一些旋转的东西,这样你就不需要bar
和container
了。您的案例中的轮换是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);
你去吧。如果你想知道如何自己做,这可能会让你开始。我想使用其他技术堆栈的人也可以根据自己的情况进行调整。
有人提到延迟,在这种情况下稍微修改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秒延迟的小提琴: