Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.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 平滑地将可旋转对象捕捉到度_Javascript_Animation_Rotation_Trigonometry - Fatal编程技术网

Javascript 平滑地将可旋转对象捕捉到度

Javascript 平滑地将可旋转对象捕捉到度,javascript,animation,rotation,trigonometry,Javascript,Animation,Rotation,Trigonometry,我对这个问题已经研究了一段时间,但似乎找不到解决办法(我不是三角学的朋友)。 我试图构建一个用户可以“抓取”然后旋转的元素。我有它的工作,除了最后一个功能,我似乎不明白: (虽然很长,但我只是想问一下snapTo()函数应该如何工作) 我想要的是基于增量值将对象捕捉到度。这意味着,如果snap==true,则代码应计算距离鼠标释放点最近的估计目标s,并根据旋转方向将对象平滑旋转到该目标旋转: 因为对象是“抓取”的,所以我计算了mousedown到对象当前旋转的偏移量,这就是它的来源,所以它不只

我对这个问题已经研究了一段时间,但似乎找不到解决办法(我不是三角学的朋友)。 我试图构建一个用户可以“抓取”然后旋转的元素。我有它的工作,除了最后一个功能,我似乎不明白:

(虽然很长,但我只是想问一下snapTo()函数应该如何工作)

我想要的是基于
增量值将对象捕捉到度。这意味着,如果
snap==true
,则代码应计算距离鼠标释放点最近的估计
目标
s,并根据旋转方向将对象平滑旋转到该
目标
旋转: 因为对象是“抓取”的,所以我计算了mousedown到对象当前旋转的偏移量,这就是它的来源,所以它不只是捕捉到鼠标

因此,在这种情况下,用户顺时针旋转对象,并在对象旋转介于90°和45°之间时释放鼠标。由于方向(由
角度
变量的符号标识)为正,目标将在当前旋转之后

任务是计算该目标,然后平滑地将对象旋转到该目标

我为它编写的函数基于by autoSpin()函数(在
spin==false
时执行),它采用翻转的时间指数乘数
delta
(从鼠标释放后的时间计算)<代码>增量
将随着时间的推移沿翻转指数减小,因此角度变慢

有一个spinTo()函数,请不要评判我,我有一种感觉,它非常愚蠢:

function snapTo() {      
    var elapsed, delta;    
    increments = (typeof increments === 'number') ? Math.floor(increments) : 4;    
    var ia = 360 / increments; //increment angle - snapping points should occur "every ia degrees"
    if (Math.abs(angle % ia) > 0) { //if user turned for more than 1 increment
      var a = lastRot % ia; //check the distance from 
      if (angle > 0){ //positive direction
        amplitude = 50; //if snapping is on, force amplitude
        target = (lastRot - a) + ia;
      }
      if (angle < 0){ //negative direction        
        amplitude = -50;
        target = lastRot - a;
      } 
    } else { //cancel the rotation
      target = rotation;
    }    
    elapsed = Date.now() - timestamp; //time passed since mouse was released
    delta = -amplitude * Math.exp(-elapsed / timeConstant); //the greater the time from mouse release, the smaller this value
    if (delta > 0.5 || delta < -0.5) { //while delta is decreasing...         
      rotate(target - delta - offset); 
      snapFrame = requestAnimationFrame(snapTo); //keep rotation
    } else {                
      rotate(target - offset); //when enough time passes (based on timeConstant), make one final rotation and stop
    }     
  }
函数snapTo(){
var,delta;
增量=(增量类型=='number')?数学地板(增量):4;
var ia=360/增量;//增量角度-捕捉点应“每隔ia度”出现
如果(Math.abs(角度%ia)>0){//如果用户转动超过1个增量
var a=lastRot%ia;//检查距离
如果(角度>0){//正方向
振幅=50;//如果启用捕捉,则强制振幅
目标=(lastRot-a)+ia;
}
如果(角度<0){//负方向
振幅=-50;
target=lastRot-a;
} 
}否则{//取消旋转
目标=旋转;
}    
经过=日期。现在()-timestamp;//鼠标释放后经过的时间
delta=-amplitude*Math.exp(-appeased/timeConstant);//鼠标释放的时间越长,该值越小
如果(δ>0.5 | |δ<-0.5){//,而δ在减小。。。
旋转(目标-增量-偏移);
snapFrame=requestAnimationFrame(snapTo);//保持旋转
}否则{
旋转(目标-偏移);//当经过足够的时间(基于时间常数)时,进行最后一次旋转并停止
}     
}
我做错了什么?

*le叹气 好吧,我得自己想办法。如果有人想做这类事情,这里有一种方法:

function snapTo() {      
    var elapsed, ease, diff;    
    increments = (typeof increments === 'number') ? Math.floor(increments) : 4;    
    var ia = 360 / increments; //increment angle - this is how large each increment will be
    var a = last % ia; //check the distance from point of mouse release to the previous increment    
    if (movement>0) {
      elapsed = Date.now() - timestamp; //time passed since mouse was released
      ease = 1 - Math.exp((-3*elapsed)/timeConstant); //your easing function formula goes here
      if(a > ia/2) { //if halfway through the increment...
        target = (last - a) + ia; //target next increment
      } 
      else { //else revert to previous increment to the point of mouse release
        target = last - a;
      } 
      diff = target - last; //difference between target and rotation at time of mouse release
      if(ease < 0.95){ //this depends on your easing formula
        rotate(last+diff * ease);
        requestAnimationFrame(snapTo); //don't forget to RAF
      } else { //and for your final frame...
        rotate(last+diff); //make it snappy :P
      }
      console.log(last); //traces of debugging were found in this derelict question...
    }
  }
函数snapTo(){
变量、易用性、差异性;
增量=(增量类型=='number')?数学地板(增量):4;
var ia=360/增量;//增量角度-这是每个增量的大小
var a=last%ia;//检查从鼠标释放点到上一个增量的距离
如果(移动>0){
经过=日期。现在()-timestamp;//鼠标释放后经过的时间
ease=1-Math.exp(-3*appeased)/timeConstant);//您的easing函数公式如下
如果(a>ia/2){//如果增量已过一半。。。
target=(last-a)+ia;//目标下一个增量
} 
else{//else恢复到鼠标释放点之前的增量
目标=最后一个-a;
} 
diff=target-last;//释放鼠标时目标和旋转之间的差异
如果(ease<0.95){//这取决于您的ease公式
旋转(最后+差异*轻松);
requestAnimationFrame(snapTo);//别忘了RAF
}否则{//对于最后一帧。。。
旋转(上一个+diff);//使其快速:P
}
console.log(last);//在这个被忽略的问题中找到了调试的痕迹。。。
}
}
所以在这里

  • appead
    是鼠标释放后经过的时间
  • 增量
    是用户提供的参数:将有多少捕捉点
  • ia
    是以度为单位计算的增量:360/
    增量
  • last
    是记录在图中的
    mouseup
    事件-“当前旋转”上的角度。它包括偏移量(在我的代码中,它只是发布点旋转的“快照”,然后在符号中也会反转,因为在DOM中坐标系是y翻转的,我不喜欢使用它)
  • a
    最后一个
    比上一个最近的增量点大多少
  • diff
    是图表上的“目标”-最终旋转和
    last
  • ease
    只是根据您的easing函数更改的值,您可以根据该值继续调用RAF或完成动画
  • timeConstant
    是动画所需时间的毫秒数。你可以有或没有,这取决于你的放松公式
一般来说,这是一个很好的阅读资源:

对于开发缓和公式也是非常好的

哦,还有:如果有人想知道,似乎不可能将任何类型的非时间相关参数传递给RAF回调函数。如果我这样做的话,似乎会把它弄坏。因此,唯一的解决方案是在代码的其他地方定义
增量

任何人有更好的解决办法,我全神贯注