Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.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 当div';s移动/拖动_Javascript_Physics_Drag_Mousemove - Fatal编程技术网

Javascript 当div';s移动/拖动

Javascript 当div';s移动/拖动,javascript,physics,drag,mousemove,Javascript,Physics,Drag,Mousemove,我花了6个小时试图找到我问题的答案,但没有任何运气 我的网站上有一些可以拖动的div。当我拖动它们的时候,我想要一个真实的效果,比如有一个气压,它们被推了一点,所以当它们被拖动时,它们会摆动一点 在这里可以看到一个效果应该如何工作的示例图像:(不知道效果叫什么) 我用谷歌搜索了很多不同组合的单词“Javascript、加速度、惯性、摆动、物理、旋转、移动、气压、摩擦、悬挂”,但没有找到任何帮助 不过,我在这个JSFiddle[1](下面的链接)上发现了类似的效果。我还遇到了Google Grav

我花了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次鼠标移动之间的跨度将很大,因此长方体旋转也会很大。当鼠标缓慢移动时,跨度将变小,长方体旋转将不像以前那样大
但是结果看起来并不真实,尤其是当你快速移动鼠标时。我认为需要使用函数Math.sin,以便在div移动时,使旋转更加逼真。 我不知道如何计算这个物理量,所以如果有人有一个想法,来源,例子,公式,或者知道效应的名字,那就太好了

//向您要找的人问好

考虑使用物理引擎以更少的努力和更好的结果实现您想要的效果

请注意,它使用物理引擎Box2DFlash到JavaScript的端口。如果您查看页面的代码,就会发现如何正确设置Box2djs

使用Box2d,您可以设置世界和对象属性(如重力、摩擦力)以及其他物理属性

下面是Google Gravity中处理Box2d的代码示例:

// 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)的范围。我尝试了一下,它看起来更好。