jQuery元素自由旋转。在IE中纠正变换原点和翻译

时间:2011-02-24 13:58:31

标签: javascript internet-explorer matrix rotation transformation

我正在开发一个jQuery插件,使用鼠标旋转块级元素。现在它在非IE浏览器中按预期工作,但在Internet Explorer中旋转时会出现奇怪的行为。

Demo托管在testerski.antaranian.me,旋转插件脚本是

    $.fn.roll = function(angle){
    var $this = this,
        ie = !jQuery.support.leadingWhitespace;
    if (ie) {
        var cosAngle = parseFloat(parseFloat(Math.cos(angle.rad())).toFixed(8)),
            sinAngle = parseFloat(parseFloat(Math.sin(angle.rad())).toFixed(8)),
            tx = 0, ty = 0,
            matrixFilter = '(M11=' + cosAngle + ', ' 
                    + 'M12=' + -sinAngle + ', '
                    + 'M21=' + sinAngle + ', '
                    + 'M22=' + cosAngle + ','
                    + 'sizingMethod=\'auto expand\')',
            filter = 'progid:DXImageTransform.Microsoft.Matrix' + matrixFilter,
            css = {
                '-ms-filter': filter,
                'filter': filter                        
              };
            debug.log(filter);  
        var matrix = $M([
                  [cosAngle, -sinAngle, tx],
                  [sinAngle, cosAngle, ty],
                  [0, 0, 1]
                ]);  
        debug.log(matrix);
        $this.transformOrigin(matrix);
        $this.fixIeBoundaryBug(matrix);

    } else {
        var css = {
                '-webkit-transform': 'rotate(' + angle + 'deg)',
                '-moz-transform': 'rotate(' + angle + 'deg)',
                '-o-transform': 'rotate(' + angle + 'deg)'
              };
    }   
    $this.css(css);
    return this;            
  };

我用Google搜索并发现这两个与此主题相关的页面

Grady's guideZoltan's guide

因为我需要一些与线性代数相关的会计,但对我来说很难,所以如果有人有更简单的教程,或者知道直接的解决方案,请告诉我。

任何帮助将不胜感激, Antaranian。

3 个答案:

答案 0 :(得分:3)

不幸的是,IE的变换滤波器没有“变换原点”的概念。 '自动展开'sizingMethod将使变换后的对象占用尽可能少的空间,并且需要改变它的定位。

在cssSandpaper中,我放了另一个< div>在变换后的对象周围标记并调整它的margin-left和margin-top。如果您转到the cssSandpaper website并查看代码,您将看到确切的公式(在cssSandpaper.js中搜索“setMatrixFilter”)。您可以将其硬编码到库中,也可以使用cssSandpaper本身(使用cssSandpaper.setTransform()方法)。即使它可能会为您的代码添加几KB,我建议这样做以防万一我将来改进处理转换的方式。

无论如何,祝你好运!

Ž。

答案 1 :(得分:0)

实际上我已根据自己的需要对其进行了编码,如果有其他人感兴趣,这里是代码。

$.fn.ieRotate = function(alfa){
    var self = this,
        cosAlfa = Math.cos(alfa),
        sinAlfa = Math.sin(alfa),
        matrix = '(M11=' + cosAlfa + ', ' 
                + 'M12=' + -sinAlfa + ', '
                + 'M21=' + sinAlfa + ', '
                + 'M22=' + cosAlfa + ','
                + 'sizingMethod=\'auto expand\')',
        // constructing the final filter string
        filter = 'progid:DXImageTransform.Microsoft.Matrix' + matrix;    
    self.each(function(el){
        var $this = $(el),
            size = $this.data('size'),
            pos = $this.data('pos');
        $this.css({
            '-ms-filter': filter,
            'filter': filter,
            // for IE9
            'transform': 'rotate(' + angle + 'deg)'
          });
        // calculate the difference between element's expeced and the actual centers
        var dLeft = ($this.width() - size.width) / 2,
            dTop = ($this.height() - size.height) / 2;
        $this.css({
            top: pos.top -dTop,
            left: pos.left - dLeft 
          });   
    });
    return self;    
};

用法:

// caching the image object to a variable
$image = $('img#my-image');
// saving images non-rotated position and size data
$image.data('pos', {
        top:    $image.position().top,
        left:   $image.position().left
    }).data('size', {
        height: $image.height(),
        width:  $image.width()
    });
// rotate image 1.2 radians
$image.ieRotate(1.2);

感谢@Zoltan Hawryluk,他的代码在开发过程中帮助了我。

答案 2 :(得分:0)

IE的定位也可以通过分析计算 - see here