2016-11-02 9 views
3

Я новичок в Snap.svg, и я пытаюсь перекосить простой прямоугольник, но я не могу понять, как это сделать. Я уже искал в документах.Snap.svg: Как я могу перекосить элемент?

Это то, что я до сих пор:

/* stage */ 
    var s = Snap('#mysvg'); 
    s.clientRect = s.node.getBoundingClientRect(); 
    s.width = s.clientRect.width; 
    s.height = s.clientRect.height; 
    s.center = { 
     "left" : s.width/2, 
     "top" : s.height/2, 
    }; 

    /* rectangle */ 
    var rect = {}; 
    rect.width = 120; 
    rect.height = 230; 
    rect.borderRadius = 10; 
    rect = s.rect(s.center.left, s.center.top,rect.width,rect.height, rect.borderRadius); 

    rect.transformMatrix = new Snap.Matrix(); 
    rect.transformMatrix.scale(1,0.86062); 
    rect.transformMatrix.rotate(30); 
    // rect.transformMatrix.skew(30); 
    rect.transform(rect.transformMatrix); 

Похоже, что перекос не поддерживается в пределах матрицы преобразования ..

какие-либо идеи?

ответ

1

Snap.svg не имеет функции перекоса, включенной по умолчанию.

Вы можете добавить пользовательскую функцию перекоса в качестве плагина.

Эта функция будет искажаться от центра. Вы можете удалить код bbox, если он вам не нужен, он займет 0,0 в качестве центра).

jsfiddle

Snap.plugin(function(Snap, Element, Paper, global) { 

    Element.prototype.skew = function(angleX, angleY) { 

     var bbox = this.getBBox(); 

     var m = new Snap.Matrix(1, Snap.rad(angleY), Snap.rad(angleX), 1, 0, 0); 

     var dx = m.x(bbox.cx, bbox.cy) - bbox.cx; 
     var dy = m.y(bbox.cx, bbox.cy) - bbox.cy; 

     m.translate(-dx, -dy) 
     this.transform(m); 
    }; 
}); 

var s = Snap("#svg"); 

var block = s.rect(100, 100, 100, 100); 
block.skew(90,0); // try (0,90 for skewY) 
1

Из моего личного опыта с помощью оснастки для очень математически интенсивных анимации на нескольких элементах, в то время, где вопросы производительности, Фиксированный встроенные методах очень медленно и делать много операций со строками и петли. Лучше просто непосредственно манипулировать матрицей элемента DOM, а не матрицей элемента Snap. В идеале у вас будет храниться матрица где-то и объявляется один раз, но получение ее каждый раз, когда вы вносите изменения, тоже хорошо. Следующий код содержит перекошенные вещи, которые вы просите. Я нахожу вещи, чтобы быть намного быстрее и удобнее, когда делать вещи так:

Snap.plugin(function(Snap, Element, Paper, global) { 


    Element.prototype.getMatrix = function() { 
     return this.node.transform.baseVal.getItem(0).matrix; 
    }; 

    //angles in degrees 
    Element.prototype.skew = function(angleX, angleY) { 
     var m = this.getMatrix(); 
     m.b = Math.tan(angleY*Math.PI/180) 
     m.c = Math.tan(angleX*Math.PI/180) 
    }; 

    Element.prototype.translate = function(x, y) { 
     var m = this.getMatrix(); 
     m.e = x; 
     m.f = y; 
    }; 

    Element.prototype.scale = function(x, y) { 
     var m = this.getMatrix(); 
     m.a = x; 
     m.d = y; 
    }; 

    Element.prototype.rotate = function(degrees) { 
     var m = this.getMatrix(); 
     var a = degrees*Math.PI/180; 
     m.a = Math.cos(a); 
     m.b = Math.sin(a); 
     m.c = -Math.sin(a); 
     m.d = Math.cos(a); 
    }; 
}); 

Так, чтобы использовать этот код, предполагая «прямоугольник» это имя переменной для элемента оснастки вы создали, вы должны ввести:

//sets transform to x, y = 100, 100 
rect.translate(100, 100); 

// scales x to 1 and y to 0.5 
rect.scale(1, 0.5); 

//skews 30 degrees horizontally and 90 degrees vertically 
rect.skew(30, 90);