【问题标题】:Set css rotation to point an element towards a point设置 css 旋转以将元素指向一个点
【发布时间】:2014-09-25 08:39:57
【问题描述】:

我正在尝试使用 css 3 变换旋转功能将 div 旋转到一个点。

到此为止:jsfiddle link

$(document).ready(function(){
    var scw,sch,scx,scy;
    calcCenter();
    $(window).resize(function() {         
        calcCenter();
    });
    function calcCenter(){
      sch = $(window).height(); 
      scw = $(window).width(); 
      scx = scw/2;
      scy = sch/2;
        $(".circle").remove();
      var circle = $("<span></span>").addClass('circle').text('.');
      circle.css('top',scy-50+"px");
      circle.css('left',scx-50+"px");
    $(document.body).append(circle);
    }
    function calcAngle(p1,p2){

        var angle = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
        return angle;
    }



    $(document).click(function(e){  
        var box = $("<span></span>").addClass('box');
        var x = e.pageX,y=e.pageY; 
        box.css('top',y+"px");
        box.css('left',x+"px"); 

        $(document.body).append(box);
        var angle = calcAngle({x:x,y:y},{x:scx,y:scy});

        box.css('-webkit-transform','rotate('+(90+angle)*-1+'deg)');        

        box.draggable({
                drag: function(e) {
                        var box = $(this);
                        var x = e.pageX,y=e.pageY; 
                        box.css('top',y+"px");
                        box.css('left',x+"px");
                        var angle = calcAngle({x:x,y:y},{x:scx,y:scy});

                        box.css('-webkit-transform','rotate('+(90+angle)*-1+'deg)');


                        }
                      });
    });

    var sunAngle = 1;
    setInterval(function(){
        var sun = $("span.circle")[0];
        $(sun).css('-webkit-transform','rotate('+sunAngle+'deg)');
        sunAngle = (sunAngle+1) %360;           
    },100);
});

我在 Google 上搜索了“lookat”函数,发现只有类似于 lookat 矩阵的东西。

【问题讨论】:

  • 对于初学者来说,叶子的默认方向是西南方向令人困惑。尽管如此,我会尝试修正你的数学。顺便说一句,小提琴不错。

标签: jquery css css-transforms


【解决方案1】:

首先,您的圆心计算不正确。你的圆圈是 120px 宽和高,但是你通过将它的顶部和左侧设置为 scy - 50 来“居中”它,你应该使用 scy - 60(120px 的一半是 60px)。或者更好的是,还可以动态计算半圆的宽度和高度并将其减去,以防您改变主意并再次将其设置为不同的大小。

我只是静态地做的:

circle.css('top',scy-60+"px");
circle.css('left',scx-60+"px");

其次,您要计算.box 元素需要围绕其中心旋转的角度,但您使用它的顶部和左侧位置来执行此操作。这是不正确的。

同样,动态会更好,但现在让我们做静态:

var angle = calcAngle({x:x + 32,y:y + 32},{x:scx,y:scy});

那么我不确定你在用atan2() * 180 / Math.PI 做什么,因为atan2 返回弧度并且你想要度数,我仔细检查了如何在两者之间进行计算。事实证明它并不像你想象的那么简单。 See this answer.

所以我添加了一个函数:

function radToDegree(rad) {
    return (rad > 0 ? rad : (2*Math.PI + rad)) * 360 / (2*Math.PI)
}

并在返回角度之前实现:

function calcAngle(p1,p2){      
    var angle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
    return radToDegree(angle);
}

现在,度数从顶部开始,这意味着如果角度为 0 度,它将指向上方,而由于您的计算设置方式,您需要它指向右侧。所以你在最终的旋转计算中添加了+ 90

如果你的观点是向上的,那会很好,但事实并非如此。它从左下角开始,又是 135 度。把它们加起来,你会得到 225 度的差异。所以:

box.css('-webkit-transform','rotate('+(angle+225)+'deg)');  

瞧,你的脚本有效:http://jsfiddle.net/7ae3kxam/42/

编辑:现在也适用于拖动

【讨论】:

  • 在初始添加时效果很好,但拖动并没有 - 在 drag 方法中主要解决了这个问题 - jsfiddle.net/7ae3kxam/40 它只是在 270 度时做了奇怪的事情
  • 为了开始你的下一步可能是什么,一些尝试在窗口调整大小时旋转它们jsfiddle.net/7ae3kxam/41 ...我现在应该开始做一些工作了。
  • 糟糕,谢谢 Rhumborl。更新了用于拖动的小提琴。
猜你喜欢
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
  • 2014-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多