Javascript 当div';s移动/拖动
我花了6个小时试图找到我问题的答案,但没有任何运气 我的网站上有一些可以拖动的div。当我拖动它们的时候,我想要一个真实的效果,比如有一个气压,它们被推了一点,所以当它们被拖动时,它们会摆动一点 在这里可以看到一个效果应该如何工作的示例图像:(不知道效果叫什么) 我用谷歌搜索了很多不同组合的单词“Javascript、加速度、惯性、摆动、物理、旋转、移动、气压、摩擦、悬挂”,但没有找到任何帮助 不过,我在这个JSFiddle[1](下面的链接)上发现了类似的效果。我还遇到了Google Gravity[2](下面的链接),当你拖动一个元素并将鼠标移到一边时,它具有我想要达到的效果 [1]我找到的JSFiddle:www.JSFiddle.net/gVCWE/150/ [2]谷歌重力:www.mrdoob.com/projects/chromeexperiments/Google-Gravity/ 我尝试在这里自己创造效果:Javascript 当div';s移动/拖动,javascript,physics,drag,mousemove,Javascript,Physics,Drag,Mousemove,我花了6个小时试图找到我问题的答案,但没有任何运气 我的网站上有一些可以拖动的div。当我拖动它们的时候,我想要一个真实的效果,比如有一个气压,它们被推了一点,所以当它们被拖动时,它们会摆动一点 在这里可以看到一个效果应该如何工作的示例图像:(不知道效果叫什么) 我用谷歌搜索了很多不同组合的单词“Javascript、加速度、惯性、摆动、物理、旋转、移动、气压、摩擦、悬挂”,但没有找到任何帮助 不过,我在这个JSFiddle[1](下面的链接)上发现了类似的效果。我还遇到了Google Grav
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次鼠标移动之间的跨度将很大,因此长方体旋转也会很大。当鼠标缓慢移动时,跨度将变小,长方体旋转将不像以前那样大
// init box2d
worldAABB = new b2AABB();
worldAABB.minVertex.Set(-200, -200);
worldAABB.maxVertex.Set(window.innerWidth + 200, window.innerHeight + 200);
world = new b2World(worldAABB, new b2Vec2(0, 0), true);
// Get box2d elements
elements = getElementsByClass("box2d");
for (var i = 0; i < elements.length; i++) {
properties[i] = getElementProperties(elements[i]);
}
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
element.style.position = 'absolute';
element.style.left = properties[i][0] + 'px';
element.style.top = properties[i][1] + 'px';
element.style.width = properties[i][2] + 'px';
element.addEventListener('mousedown', onElementMouseDown, false);
element.addEventListener('mouseup', onElementMouseUp, false);
element.addEventListener('click', onElementClick, false);
bodies[i] = createBox(world, properties[i][0] + (properties[i][2] >> 1), properties[i][1] + (properties[i][3] >> 1), properties[i][2] / 2, properties[i][3] / 2, false);
// Clean position dependencies
while (element.offsetParent) {
element = element.offsetParent;
element.style.position = 'static';
}
}
//init box2d
worldAABB=新b2AABB();
worldAABB.minVertex.Set(-200,-200);
worldAABB.maxVertex.Set(window.innerWidth+200,window.innerHeight+200);
世界=新b2World(worldAABB,新b2Vec2(0,0),真);
//获取box2d元素
elements=getElementsByClass(“box2d”);
对于(var i=0;i>1),属性[i][1]+(属性[i][3]>>1),属性[i][2]/2,属性[i][3]/2,false);
//清除位置依赖项
while(元素offsetParent){
element=element.offsetParent;
element.style.position='static';
}
}
这段代码只是为了帮助您找到重要的代码。仔细学习GoogleGravity的代码,了解如何使用Box2djs创建您想要的效果
如果您决定使用物理引擎,您可能更喜欢使用Box2Djs,因为它会更新并存储在单个js文件中
要实现自己的现实主义效果
是很困难的,需要的不仅仅是简单地使用正弦或余弦。也许有某种视觉上相似的效果,但是,再次强调,如果没有良好的物理模拟,现实主义效果很难实现
-麻省理工学院开放式课程在没有任何真实模拟的情况下,我做了一些可定制的事情,以最后两步的速度来设置div的角度
this.drag = function (elem, e) {
//
//ROTATION
//
//If there's an end animation I kill it.
endAnimation.stop();
//Saving the mouse position
history.push(e);
//When we have positions to compare
if(history.length > 1){
if (history.length > 2) {
history.shift();
}
var dX = history[0].clientX - history[1].clientX; // Delta
var tAngle = Math.ceil(angle * -dX); // Angle to reach
var rotation = 'rotate('+ tAngle +'deg)';
$(elem).css({WebkitTransform: rotation});
$(elem).css({'-moz-transform': rotation});
$(elem).css({transform: rotation});
}
}
使用该选项,可以更改角度变量以增大或减小角度
我还使用另一种方法在下降时增加了一些惯性
您可以在这里看到结果对于记录,气压并不是盒子底部看起来“向后推”的原因;这是因为惯性——盒子的底部想要保持静止,而顶部想要移动,所以底部被甩在后面,因为它抵制运动。尝试使用正弦函数“减缓”你的速度,并将其缩放到小于(-90,90)(比如(-50,50)的范围。我尝试了一下,它看起来更好。