【问题标题】:Rotate sprite javascript旋转精灵javascript
【发布时间】:2010-10-03 22:45:13
【问题描述】:

我有一个精灵动画,一个使用 3D 应用程序渲染的小炮。我正好有 360 帧的 360 度转弯。每张图片的像素大小为 100x100。

所以基本上我想要做的是当我点击页面中的任何地方时,大炮的枪管需要旋转以指向鼠标光标,这听起来可能很简单,但我真的不能让它很好地工作,也许是因为我缺乏数学技能:P

我目前拥有的是这样的

/* This is my div with the cannon background image (360 images stitched into one) each  "image area" is 100x100px */

obj.cannon = $('#cannon');

/* Get the X/Y of the cannon loc in the dom */
var cannonX = $(obj.cannon).offset().left;
var cannonY = $(obj.cannon).offset().top;

/* Get radians using atan2 */
var radians = Math.atan2(e.pageY-cannonY, e.pageX-cannonX);

/* Convert to degrees */
var degrees = radians * (180/Math.PI);

这就是我所在的位置,我的意思是因为图像宽度是 100 像素,我需要将背景位置移动 100 像素才能将大炮向右移动 1 度,因为总共 360 幅图像 * 100 像素 = 36000 像素。所以拼接后的精灵大概是 36000px 宽。

所以

根据图像精灵的当前 backgroundPosition 在此处插入奇怪的计算,并根据鼠标光标单击的位置应用新的 backgroundPosition,然后使用某种 setTimeout(animateIt, speed);将背景位置“动画化”到新位置。

function animateIt(){
  if(newpos!=targetpos) { //Use < > here if we need to add or remove
      newpos+=100; //Until we arrive at the new backgroundPosition
      $(obj.cannon).css({backgroundPosition: newpos+'px' });
      setTimeout(animateIt, speed);
  }
}

我在这里是否完全正确,我是否正确地考虑了这一点?我觉得很愚蠢,这应该是一件简单的事情,但现在我的大脑崩溃了,我想=P。我的问题是我不知道如何正确到达“新目标背景位置”然后对其进行动画处理 ++ 或 -- 基于当前背景位置:/

【问题讨论】:

  • 使用一个图像和基于 HTML5 的图像旋转方法怎么样? raphaeljs.com/image-rotation.html .. 还是渲染出来的图片真的不一样?
  • 对大炮的看法真的改变了吗?你有精灵的链接吗?就像 Fosco 所说的 raphael 可以做到这一点,或者你甚至可以使用 CSS 转换来旋转图像本身(虽然不是在 IE 中)。
  • 恐怕这是不可能的,因为这门大炮是透视的,排序等距视图,它实际上是一个真正的 3D 对象,当精灵旋转时它不能直接从上面看到等等......因此简单的 css 旋转将不起作用...

标签: javascript jquery rotation sprite css-sprites


【解决方案1】:

嗯,这是一个包含 10 张图像的简化工作示例。

我现在将发布代码和 jsFiddle,稍后我可能会回来深入介绍它。但基本上你只需正确排序图像,然后使用(Segments - Math.floor(degree / (360 / segments))) 选择片段。您可能需要调整您的0 度数。例如,我让我的0 等于90 的正常值。

注意屏幕坐标x和y向右和向下增加。这使得atan 的度数在 x 和 y 向右和向上增加的坐标系中顺时针而不是通常的逆时针工作。

我添加了一些显示度数和图像段的文本输出。

jQuery 很好地处理了 x 和 y 位置的标准化。请注意您的 CSS 设置是跨浏览器的。

Working jsFiddle example


这是我们的图片:


这是我们的 HTML:

<div id="main"><div id="img"></div></div>
<div id="info">
    <span></span><br/>
    <span></span>
</div>


CSS:

div#main {
    width:500px;
    height:500px;
    border:2px #000 solid; }
div#img {
    width:94px;
    height:119px;
    overflow:hidden;
    top:50%;
    left:50%;
    margin-left:-45px;
    margin-top:-60px;
    position:relative; 
    background-image:url('http://imgur.com/3UPki.png');
    background-position:0;}
div#info {
    position: absolute;
    bottom:0;
    left:0; }


Javascript / jQuery:

$(function() {
    var position = $("div#img").position(), 
        mouseX, mouseY, imgX, imgY, degree;
    imgX = position.left;
    imgY = position.top;
    $("#main").mousemove(function(e) {
          // degree is arctan y over x (soh,cah,toa)
        degree = Math.atan2((e.pageY - imgY),(e.pageX - imgX))*(180 / Math.PI);
        degree = (degree - 90) % 360;
          // jQuery normalizes pageX and pageY
          // transfrom from -180 to 180 ==> 0 to 360
        if (degree < 0) degree = 180 + (180 - (Math.abs(degree)));        
        rotate(degree);
        $("span:first").html("Segment: " + (9 - Math.floor(degree / 36)));
        $("span:last").html("Degree: " + Math.floor(degree));          
    }); 

    function rotate(degree) {
        var off = 9 - Math.floor(degree / 36);
        $("div#img").css("background-position",-off*94);
    }    
}); ​

Working jsFiddle example

【讨论】:

  • 我注意到一些奇怪的行为,当你接近每个 90/180/270 度时效果很好,但 45 度意味着不太准确,但是炮管没有直接指向指针当在这些 90/180/270 值时,炮管总是准确地指向指针,知道为什么吗?我想我必须补偿这里的一些神秘行为嗯;P
【解决方案2】:

请记住,您从 atan 获得的度数将从零度开始向右,然后从那里顺时针方向(-90 向上,90 向下)。

图片的每个位置都应对应一个特定的角度。一旦你测量了度数(看起来你的那部分是正确的),使用某种类型的映射将你的度数转换为正确的图像偏移量。我不知道你的图像是什么样的,所以我无能为力。假设您的图像开始指向右侧,并从那里顺时针旋转,度数将直接对应于正确图像的偏移量。 (我建议你这样安排你的框架以方便...)

【讨论】:

  • 好的,像这样安排一个新的渲染/精灵,让我们看看结果如何,谢谢;-)
  • 如果答案有帮助,我们将不胜感激:)
  • 当然!只是等着看这是否可行,我认为您建议的整个映射正是我遇到的问题,但这肯定会有所帮助:]
  • JoshD - 你从哪里得到这个? atan 永远不会返回 270(根据我之前的评论,它只会 -pi/2 到 pi/2 弧度,即 -180 到 180 度。
  • 是的,我注意到了,但是.. 我希望它以负数返回,直到 -360,就像我设置它的方式 =P 而不是 -180 然后 +180
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多