如何制造“飞行碎片”?与jQuery的效果?

发布于 2024-12-14 04:38:24 字数 978 浏览 0 评论 0原文

我正在制作一些动画并使用 jQuery 库。

资源的方法之一是 fly(),这意味着如果父元素刚刚爆炸,就会飞离父元素。它应该看起来像飞行的碎片,即它应该向上飞走,然后屈服于重力并落下。 示例

到目前为止,这是我的方法...

var parent = this.element.parent(),
    direction = this.element.position().left < parent.width() / 2 ? '-' : '+';

this.element.animate({
    left: direction + '=300',
    top: '-=200'
}, duration);

这显然看起来根本不像飞行碎片,因为它只是向上移动。 direction 变量决定元素的飞行方向。由于每个元素相对于其父元素定位,因此左侧的元素会向左移动,反之亦然。

我不想实现一个成熟的物理引擎,例如 Box2D。

我知道我的代码本质上应该做什么,我相信是......

  1. 将元素向上(负顶部)并按照设置的方向(负或正),一些值衰减以模拟由于风阻等导致的水平运动损失和由于重力导致的垂直运动损失。
  2. 在某个阶段,重力将变得比爆炸产生的元素向上的力更强,在这种情况下,元素将需要下落

我真的不知道如何解决这个问题。我希望我可以利用 jQuery 的 animate(),但我不知道如何合并衰减价值。

创造这种效果的最佳方法是什么?

I am working on some animation and am using the jQuery library.

One of the assets' method is fly(), which means to fly away from the parent element had that parent just exploded. It should look like flying debris, i.e. it should fly up and away and then succumb to gravity and fall. Example.

Here is my method so far...

var parent = this.element.parent(),
    direction = this.element.position().left < parent.width() / 2 ? '-' : '+';

this.element.animate({
    left: direction + '=300',
    top: '-=200'
}, duration);

This obviously doesn't look at all like flying debris, as it just moves up and away. The direction variable determines which way the element should fly. Because each element is relatively positioned to its parent, elements on the left hand side move to the left and vice versa.

I'd don't want to implement a full fledged physics engine such as Box2D.

I know what my code should essentially do, which I believe is...

  1. Fly the elment up (negative top) and in the direction set (negative or positive left), with some value decaying to simulate loss of horizontal movement due to wind resistance etc and loss of vertical movement due to gravity.
  2. The force of gravity will have grown stronger at some stage than the upward force of the element from the explosion, in which case the element will need to fall.

I don't really know how to approach this problem. I was hoping I could leverage jQuery's animate(), but I don't know to incorporate a decaying value.

What would be the best way to create this effect?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

﹎☆浅夏丿初晴 2024-12-21 04:38:24

(我会将其作为答案发布,因为这就是它的实际情况。)

您是否只需要一个美观的碎片动画,或者是否必须精确计算?我发现使用随机值实际上可以使其变得现实。请参阅http://jsfiddle.net/minitech/fSaGk

(I will post this as an answer since that’s what it actually is.)

Do you just need a debris animation for eye candy, or does it have to be precisely calculated? I found that using random values can actually make it realistic. See http://jsfiddle.net/minitech/fSaGk

一个人练习一个人 2024-12-21 04:38:24

您可能需要使用 animate() 调用的 easing 属性,并利用 jQuery 缓动插件 以获得比 jQuery 默认提供的标准线性缓动更微妙的效果。

另一个技巧是链接animate() 的调用以获得您想要的多阶段效果。

这是一个真的(我的意思是真的)快速模型 这有点给你一个想法。

它的核心:

debris.animate({
    left: direction + '=150',
    easing: 'linear',
}, {
    queue: false,
    duration: duration
})
.animate({
    top: '-=100',
    easing: 'easeOutQuint',
}, {
    queue: true,
    duration: vduration
})
.animate({
    top: '+=100',
    easing: 'easeInQuint',
}, {
    queue: true,
    duration: vduration
});

关键元素是:

  • 左右动画是线性 - 这不是您正在寻找的衰减,但对于这个模型来说已经足够了
  • 左右动画明确地 未排队,因此链中的下一个animate()立即开始
  • 上下动画由两个排队组成(这是默认设置,但我已经为了清楚起见无论如何指定它)动画,每个定时在左右动画的一半时,
  • 来理解

我使用了 Easing 插件中的 easeOutQuint 缓动函数来实现重力效果 - 它远非完美,但您可以通过足够的排队和链接 <像这样的 code>animate() 调用,您应该能够得到一个非常漂亮的衰减 x 以及一个漂亮的受重力启发的 y...

You're probably going to need to use the easing property of the animate() call, and leverage the jQuery Easing Plugin to get an effect somewhat more subtle than the standard linear easing offered by default in jQuery.

The other trick is to chain the calls to animate() to get that multiple-stage effect you're after.

Here's a really (and I mean really) quick mockup that kinda- sorta gives you an idea.

The guts of it:

debris.animate({
    left: direction + '=150',
    easing: 'linear',
}, {
    queue: false,
    duration: duration
})
.animate({
    top: '-=100',
    easing: 'easeOutQuint',
}, {
    queue: true,
    duration: vduration
})
.animate({
    top: '+=100',
    easing: 'easeInQuint',
}, {
    queue: true,
    duration: vduration
});

The key elements are:

  • The left-right animation is linear - this is not the decay you're looking for but it's sufficient for this mockup
  • The left-right animation is explicitly not queued, so the next animate() in the chain starts immediately
  • The up-down animation consists of two queued (it's the default but I've specified it anyway for clarity) animations, each timed at half of the left-right animation
  • I've used the easeOutQuint easing function from the Easing Plugin to do the gravitational effect - it's nowhere near perfect but you get the idea

With sufficient queueing and chaining of animate() calls like this you should be able to get a pretty nice decaying x together with a good-looking gravity-inspired y...

千笙结 2024-12-21 04:38:24

我最终广泛修改了 minitech 的代码......

var element = $('div'),
    parent = element.parent(),
    position = element.position(),
    offset = element.offset(),
    directionOver180 = false,
    flyAnimation;

$('body').css('overflow', 'hidden');

var angle = (Math.random() * 180) + (directionOver180 ? 180 : 0),
    angleCalc = angle * Math.PI / 180,
    velocityX = Math.cos(angleCalc),
    velocityY = Math.sin(angleCalc),
    currentX = offset.left,
    currentY = offset.top,
    gravity = -20;

flyAnimation = setInterval(function() {

    currentX += velocityX * 5 * (directionOver180 ? -1 : 1);
    currentY += velocityY * 3 + ++gravity;

    velocityX += 0.02;
    velocityY += 0.1 * Math.random();

    element.css({
        left: currentX,
        top: currentY
    });

    if (currentY + element.height() > $(window).height()) {
        $('body').css('overflow', 'visible');
        clearInterval(flyAnimation);
        element.remove();
    }

}, 20);

jsFiddle.

I ended up modifying minitech's code extensively...

var element = $('div'),
    parent = element.parent(),
    position = element.position(),
    offset = element.offset(),
    directionOver180 = false,
    flyAnimation;

$('body').css('overflow', 'hidden');

var angle = (Math.random() * 180) + (directionOver180 ? 180 : 0),
    angleCalc = angle * Math.PI / 180,
    velocityX = Math.cos(angleCalc),
    velocityY = Math.sin(angleCalc),
    currentX = offset.left,
    currentY = offset.top,
    gravity = -20;

flyAnimation = setInterval(function() {

    currentX += velocityX * 5 * (directionOver180 ? -1 : 1);
    currentY += velocityY * 3 + ++gravity;

    velocityX += 0.02;
    velocityY += 0.1 * Math.random();

    element.css({
        left: currentX,
        top: currentY
    });

    if (currentY + element.height() > $(window).height()) {
        $('body').css('overflow', 'visible');
        clearInterval(flyAnimation);
        element.remove();
    }

}, 20);

jsFiddle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文