我花了过去 6 个小时试图找到我的问题的答案,但没有任何运气。
我的网站上有一些可拖动的 div。当我拖动它们时,我想要一个逼真的效果,就像有一个气压并且它们被推了一下,所以当它们被拖动时它们会摆动一点。
效果应该如何工作的示例图像,可以在这里看到:惯性加速效果(不知道效果叫什么)
我已经在许多不同的组合中搜索了这些词“Javascript,加速度,惯性,摆动,物理,旋转,移动,气压,摩擦,悬挂”,但没有找到任何可以帮助我的东西。
不过,我在这个 JSFiddle[1](下面的链接)上发现了一种类似的效果。当您拖动元素并将鼠标移到一边时,我还遇到了 Google Gravity[2](下面的链接),它具有我想要实现的效果。
[ 1 ] JSFiddle 我发现:www.jsfiddle.net/gVCWE/150/
[2]谷歌重力:www.mrdoob.com/projects/chromeexperiments/google-gravity/
我试图在这里自己创造效果:
var fn = {
activeElm : null,
pos : {},
transPos : {},
startPos : null,
moveSteps : new Array(15),
init : function(){
var self = this;
document.addEventListener('mousedown', function(e){self.handleStart.call(self, e);});
document.addEventListener('mousemove', function(e){self.handleMove.call(self, e);});
document.addEventListener('mouseup', function(e){self.handleStop.call(self, e);});
},
handleStart : function(e){
if(fn.hasClass('dragme', e.target)){
fn.activeElm = e.target;
e.preventDefault();
fn.startPos = {x : e.pageX, y : e.pageY};
var lastPos = {x : fn.activeElm.getAttribute('data-posX'), y : fn.activeElm.getAttribute('data-posY')};
if(lastPos['x'] && lastPos['y']){
fn.transPos = {x : parseFloat(lastPos['x']), y : parseFloat(lastPos['y'])};
}else{
fn.transPos = {x : 0, y : 0};
}
fn.pos = {x : fn.transPos['x'], y : fn.transPos['y']};
fn.loop();
}
},
handleMove : function(e){
if(!fn.activeElm)
return;
fn.pos = {x : fn.transPos['x'] + e.pageX - fn.startPos['x'], y : fn.transPos['y'] + e.pageY - fn.startPos['y']};
},
handleStop : function(e){
if(!fn.activeElm)
return;
fn.activeElm.setAttribute('data-posX', fn.pos['x']);
fn.activeElm.setAttribute('data-posY', fn.pos['y']);
fn.activeElm = null;
},
addStep : function(move){
var arr = fn.moveSteps;
arr = arr.slice(1, arr.length);
arr.push(move);
fn.moveSteps = arr;
},
loop : function(){
if(!fn.activeElm)
return false;
fn.requestAnimFrame(fn.loop);
fn.addStep(fn.pos['x']);
fn.animate();
},
animate : function(){
var arr = fn.moveSteps;
var rotaSpeed = arr[arr.length-1] - arr[0];
// The Math.min- and max are there, so we can be sure the angle won't rotate more than 90° and -90°
var rotation = 'rotate(' + Math.max(Math.min(90, rotaSpeed), -90) + 'deg)';
if(!fn.activeElm)
return;
var obj = fn.activeElm.parentNode.style;
obj.webkitTransform = obj.MozTransform = obj.msTransform = obj.OTransform = obj.transform = 'translate(' + fn.pos['x'] + 'px, ' + fn.pos['y'] + 'px) ' + rotation;
},
requestAnimFrame : function(callback){
return window.requestAnimationFrame && window.requestAnimationFrame(callback) ||
window.webkitRequestAnimationFrame && window.webkitRequestAnimationFrame(callback) ||
window.mozRequestAnimationFrame && window.mozRequestAnimationFrame(callback) ||
window.oRequestAnimationFrame && window.mozRequestAnimationFrame(callback) ||
window.msRequestAnimationFrame && window.msRequestAnimationFrame(callback) ||
window.setTimeout(callback, 1000 / 60);
},
hasClass : function(classname, obj){
return new RegExp(' ' + classname + ' ').test(' ' + obj.className + ' ');
}
}
fn.init();
- 我做什么:我计算在最后 15 次鼠标移动期间鼠标移动了多少,然后将旋转度设置为该值。所以当鼠标快速移动时,15 次鼠标移动之间的跨度会很大,因此框的旋转也会很大。当鼠标缓慢移动时,跨度会变小,框旋转不会像以前那么大。
但结果看起来并不真实,尤其是当您快速移动鼠标时。我认为随着 div 的移动,需要使用函数 Math.sin 来使旋转更真实地“轻松”。我不知道如何计算这个物理学,所以如果有人有想法、来源、例子、公式,或者只是知道效果的名称,那就太好了。
//此致