Can you skew an image with Raphael?

795 views
Skip to first unread message

Adam

unread,
May 24, 2010, 9:59:01 PM5/24/10
to Raphaël
I'm looking to animate an image skew in a html page, just wondering if
Raphael is a good choice.

Cheers
Adam

Sebastian Gurin

unread,
May 26, 2010, 9:00:23 AM5/26/10
to raph...@googlegroups.com
Raphaeljs doesn't support skew. Nevertheless, If you only want to skew an image you can still use the raphaeljs plugin that I'm pasting at the tail of this mail that gives support for matrix transformation. Nevertheless, be carefull: once you applied a matrix() operation to a raphaeljs element, other raphaeljs operations like translate won't work on that element as spected. (That's the main reason why raphaeljs doesn't support matrix operation)

The plugin has already implemented skewing (shear) horizontal and vertical operation

an example:

var rec2 = paper.image("../../resources/test/images/image.jpg", 360, 360, 130, 130);
rec2.shear(1.3, true);

var rec3 = paper.image("../../resources/test/images/image.jpg", 360, 360, 130, 130);
rec3.shear(1.3, false);


good look
the plugin:


/* matrix transformation plugin
*
* using matrix filter in vml (http://msdn.microsoft.com/en-us/library/ms533014(VS.85).aspx)
*
* and transform (http://www.w3.org/TR/SVG/coords.html#TransformAttribute) in svg
* check http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined
*
* note: when a matrix transformation is applied, the element coordinate system change
* according to that matrix. So we override translate method to behave correctly
*
* @author: sgurin
*/
(function () {
Raphael.Matrix=function(m11, m12, m21, m22, dx, dy) {
this.m = [
[m11 || 1, m12 || 0, 0],
[m21 || 0, m22 || 1, 0],
[dx || 0, dy || 0, 1]
];
};
if (Raphael.vml) {
Raphael.Matrix.prototype.toString = function () {
return "progid:DXImageTransform.Microsoft.Matrix(M11=" + this.m[0][0] +
", M12=" + this.m[0][1] + ", M21=" + this.m[1][0] + ", M22=" + this.m[1][1] +
", Dx=" + this.m[2][0] + ", Dy=" + this.m[2][1] + ", sizingmethod='auto expand', filtertype='bilinear')";
};
Raphael.el.matrix = function (xx, xy, yx, yy, dx, dy) {
if(xx==null) {
this.Group.style.filter = "";
}
else {
tMatrix = new Raphael.Matrix(xx, xy, yx, yy, dx, dy);
this.Group.style.filter = tMatrix.toString();
}
return this;
};
} else {
Raphael.Matrix.prototype.toString = function () {
return "matrix(" + this.m[0][0] +
", " + this.m[1][0] + ", " + this.m[0][1] + ", " + this.m[1][1] +
", " + this.m[2][0] + ", " + this.m[2][1] + ")";
};
Raphael.el.matrix = function (xx, xy, yx, yy, dx, dy) {
if(xx==null) {
this.transformations[Raphael.el.matrix._TransfIdx]="";
}
else {
this.matrix(null);
this.transformations[Raphael.el.matrix._TransfIdx] = new Raphael.Matrix(xx, xy, yx, yy, dx, dy);
}
this.node.setAttribute("transform", this.transformations.join(" "));

this.M = xx==null?null:[xx, xy, yx, yy, dx, dy];

return this;

};
Raphael.el.matrix._TransfIdx=8;
};

//matrix derived operations:
Raphael.el.shear=function(s, horizontal) {
var x =this.getBBox().x, y=this.getBBox().y;
if(horizontal) {
this.matrix(
1.0, s,
0.0, 1.0,
0.0, 0.0
);
if(!Raphael.vml)
this.translate(y*s*(-1),0);
}
else {
this.matrix(
1.0, 0.0,
s, 1.0,
0.0, 0.0
);
if(!Raphael.vml)
this.translate(0, x*s*(-1));
}
return this;
};

/**
* reflects the element about a line that goes through the center of the image
* and has an angle slope
*
* for reflecting, first we translate the element so its center equals the origin,
* then apply reflection (so its position doesn't change) and then
*
* @param angle must be in angle (pi) not radians, valid values are PI/2, PI/3, etc
*
* http://planetmath.org/encyclopedia/DerivationOf2DReflectionMatrix.html
* */
Raphael.el.reflect=function(angle) {
//la transladamos para que quede centrada en el origen, aplicamos transformación y la retrasladamos a su lugar de origen.
var b_ = this.getBBox(), b={x: b_.x, y: b_.y, width: b_.width, height: b_.height};
this.translate((b.x+b.width/2)*(-1), (b.y+b.height/2)*(-1));
var m = Math.tan(angle), A = 1/(m*m+1);
this.matrix(
(1-m*m)*A, 2*m*A,
2*m*A, (m*m-1)*A,
0,0);
this.translate_matrix(b.x+b.width/2, b.y+b.height/2);
return this;
};
/**
* rotates the element theta degrees over the point (x,y)
*/
Raphael.el.rotateOver=function(theta, x, y) {
var r00=Math.cos(theta), r01=Math.sin(theta),
r10=Math.sin(theta)*(-1), r11=Math.cos(theta);
return this.matrix(
r00, r01,
r10, r11,
x - r00*x - r01*y, y - r10*x - r11*y);
}
})();

> --
> You received this message because you are subscribed to the Google Groups "Raphaël" group.
> To post to this group, send an email to raph...@googlegroups.com.
> To unsubscribe from this group, send email to raphaeljs+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/raphaeljs?hl=en-GB.
>


--
Sebastian Gurin <sgu...@softpoint.org>

Adam

unread,
May 26, 2010, 4:48:32 PM5/26/10
to Raphaël
Wiked Sebastian, thanks a lot for that...can't wait to try it out!

Cheers
Adam

On May 26, 11:00 pm, Sebastian Gurin <sgu...@softpoint.org> wrote:
> Raphaeljs doesn't support skew. Nevertheless, If you only want to skew an image you can still use the raphaeljs plugin that I'm pasting at the tail of this mail that gives support for matrix transformation. Nevertheless, be carefull: once you applied a matrix() operation to a raphaeljs element, other raphaeljs operations like translate won't work on that element as spected. (That's the main reason why raphaeljs doesn't support matrix operation)
>
> The plugin has already implemented skewing (shear) horizontal and vertical operation
>
> an example:
>
> var rec2 = paper.image("../../resources/test/images/image.jpg", 360, 360, 130, 130);
> rec2.shear(1.3, true);
>
> var rec3 = paper.image("../../resources/test/images/image.jpg", 360, 360, 130, 130);
> rec3.shear(1.3, false);
>
> good look
> the plugin:
>
> /* matrix transformation plugin
>  *
>  * using matrix filter in vml (http://msdn.microsoft.com/en-us/library/ms533014(VS.85).aspx)
>  *
>  * and transform (http://www.w3.org/TR/SVG/coords.html#TransformAttribute) in svg

>  * checkhttp://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined

>      *http://planetmath.org/encyclopedia/DerivationOf2DReflectionMatrix.html


>      * */
>     Raphael.el.reflect=function(angle) {
>         //la transladamos para que quede centrada en el origen, aplicamos transformación y la retrasladamos a su lugar de origen.
>         var b_ = this.getBBox(), b={x: b_.x, y: b_.y, width: b_.width, height: b_.height};
>         this.translate((b.x+b.width/2)*(-1), (b.y+b.height/2)*(-1));
>         var m = Math.tan(angle), A = 1/(m*m+1);
>         this.matrix(
>                         (1-m*m)*A,              2*m*A,
>                         2*m*A,                  (m*m-1)*A,
>                         0,0);
>         this.translate_matrix(b.x+b.width/2, b.y+b.height/2);
>         return this;
>     };  
>     /**
>      * rotates the element theta degrees over the point (x,y)
>      */
>     Raphael.el.rotateOver=function(theta, x, y) {
>         var r00=Math.cos(theta), r01=Math.sin(theta),
>                         r10=Math.sin(theta)*(-1), r11=Math.cos(theta);
>         return this.matrix(
>                         r00,                    r01,
>                         r10,                    r11,
>                         x - r00*x - r01*y, y - r10*x - r11*y);  
>     }
>
> })();
>
> On Mon, 24 May 2010 18:59:01 -0700 (PDT)
>

> Adam <adam.jenk...@objecttraining.com.au> wrote:
> > I'm looking to animate an image skew in a html page, just wondering if
> > Raphael is a good choice.
>
> > Cheers
> > Adam
>
> > --
> > You received this message because you are subscribed to the Google Groups "Raphaël" group.
> > To post to this group, send an email to raph...@googlegroups.com.
> > To unsubscribe from this group, send email to raphaeljs+...@googlegroups.com.

> > For more options, visit this group athttp://groups.google.com/group/raphaeljs?hl=en-GB.
>
> --
> Sebastian Gurin <sgu...@softpoint.org>

Adam

unread,
May 26, 2010, 5:06:45 PM5/26/10
to Raphaël
ok...now that's really cool....well done Sebastian!

On May 26, 11:00 pm, Sebastian Gurin <sgu...@softpoint.org> wrote:

> Raphaeljs doesn't support skew. Nevertheless, If you only want to skew an image you can still use the raphaeljs plugin that I'm pasting at the tail of this mail that gives support for matrix transformation. Nevertheless, be carefull: once you applied a matrix() operation to a raphaeljs element, other raphaeljs operations like translate won't work on that element as spected. (That's the main reason why raphaeljs doesn't support matrix operation)
>
> The plugin has already implemented skewing (shear) horizontal and vertical operation
>
> an example:
>
> var rec2 = paper.image("../../resources/test/images/image.jpg", 360, 360, 130, 130);
> rec2.shear(1.3, true);
>
> var rec3 = paper.image("../../resources/test/images/image.jpg", 360, 360, 130, 130);
> rec3.shear(1.3, false);
>
> good look
> the plugin:
>
> /* matrix transformation plugin
>  *
>  * using matrix filter in vml (http://msdn.microsoft.com/en-us/library/ms533014(VS.85).aspx)
>  *
>  * and transform (http://www.w3.org/TR/SVG/coords.html#TransformAttribute) in svg

>  * checkhttp://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined

>      *http://planetmath.org/encyclopedia/DerivationOf2DReflectionMatrix.html


>      * */
>     Raphael.el.reflect=function(angle) {
>         //la transladamos para que quede centrada en el origen, aplicamos transformación y la retrasladamos a su lugar de origen.
>         var b_ = this.getBBox(), b={x: b_.x, y: b_.y, width: b_.width, height: b_.height};
>         this.translate((b.x+b.width/2)*(-1), (b.y+b.height/2)*(-1));
>         var m = Math.tan(angle), A = 1/(m*m+1);
>         this.matrix(
>                         (1-m*m)*A,              2*m*A,
>                         2*m*A,                  (m*m-1)*A,
>                         0,0);
>         this.translate_matrix(b.x+b.width/2, b.y+b.height/2);
>         return this;
>     };  
>     /**
>      * rotates the element theta degrees over the point (x,y)
>      */
>     Raphael.el.rotateOver=function(theta, x, y) {
>         var r00=Math.cos(theta), r01=Math.sin(theta),
>                         r10=Math.sin(theta)*(-1), r11=Math.cos(theta);
>         return this.matrix(
>                         r00,                    r01,
>                         r10,                    r11,
>                         x - r00*x - r01*y, y - r10*x - r11*y);  
>     }
>
> })();
>
> On Mon, 24 May 2010 18:59:01 -0700 (PDT)
>

> Adam <adam.jenk...@objecttraining.com.au> wrote:
> > I'm looking to animate an image skew in a html page, just wondering if
> > Raphael is a good choice.
>
> > Cheers
> > Adam
>
> > --
> > You received this message because you are subscribed to the Google Groups "Raphaël" group.
> > To post to this group, send an email to raph...@googlegroups.com.
> > To unsubscribe from this group, send email to raphaeljs+...@googlegroups.com.

> > For more options, visit this group athttp://groups.google.com/group/raphaeljs?hl=en-GB.
>
> --
> Sebastian Gurin <sgu...@softpoint.org>

Adam

unread,
May 26, 2010, 5:13:14 PM5/26/10
to Raphaël
quick question, I don't suppose you have any thoughts on keystoning,
i.e. longer on one side than the other??

On May 26, 11:00 pm, Sebastian Gurin <sgu...@softpoint.org> wrote:

> Raphaeljs doesn't support skew. Nevertheless, If you only want to skew an image you can still use the raphaeljs plugin that I'm pasting at the tail of this mail that gives support for matrix transformation. Nevertheless, be carefull: once you applied a matrix() operation to a raphaeljs element, other raphaeljs operations like translate won't work on that element as spected. (That's the main reason why raphaeljs doesn't support matrix operation)
>
> The plugin has already implemented skewing (shear) horizontal and vertical operation
>
> an example:
>
> var rec2 = paper.image("../../resources/test/images/image.jpg", 360, 360, 130, 130);
> rec2.shear(1.3, true);
>
> var rec3 = paper.image("../../resources/test/images/image.jpg", 360, 360, 130, 130);
> rec3.shear(1.3, false);
>
> good look
> the plugin:
>
> /* matrix transformation plugin
>  *
>  * using matrix filter in vml (http://msdn.microsoft.com/en-us/library/ms533014(VS.85).aspx)
>  *
>  * and transform (http://www.w3.org/TR/SVG/coords.html#TransformAttribute) in svg

>  * checkhttp://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined

>      *http://planetmath.org/encyclopedia/DerivationOf2DReflectionMatrix.html


>      * */
>     Raphael.el.reflect=function(angle) {
>         //la transladamos para que quede centrada en el origen, aplicamos transformación y la retrasladamos a su lugar de origen.
>         var b_ = this.getBBox(), b={x: b_.x, y: b_.y, width: b_.width, height: b_.height};
>         this.translate((b.x+b.width/2)*(-1), (b.y+b.height/2)*(-1));
>         var m = Math.tan(angle), A = 1/(m*m+1);
>         this.matrix(
>                         (1-m*m)*A,              2*m*A,
>                         2*m*A,                  (m*m-1)*A,
>                         0,0);
>         this.translate_matrix(b.x+b.width/2, b.y+b.height/2);
>         return this;
>     };  
>     /**
>      * rotates the element theta degrees over the point (x,y)
>      */
>     Raphael.el.rotateOver=function(theta, x, y) {
>         var r00=Math.cos(theta), r01=Math.sin(theta),
>                         r10=Math.sin(theta)*(-1), r11=Math.cos(theta);
>         return this.matrix(
>                         r00,                    r01,
>                         r10,                    r11,
>                         x - r00*x - r01*y, y - r10*x - r11*y);  
>     }
>
> })();
>
> On Mon, 24 May 2010 18:59:01 -0700 (PDT)
>

> Adam <adam.jenk...@objecttraining.com.au> wrote:
> > I'm looking to animate an image skew in a html page, just wondering if
> > Raphael is a good choice.
>
> > Cheers
> > Adam
>
> > --
> > You received this message because you are subscribed to the Google Groups "Raphaël" group.
> > To post to this group, send an email to raph...@googlegroups.com.
> > To unsubscribe from this group, send email to raphaeljs+...@googlegroups.com.

> > For more options, visit this group athttp://groups.google.com/group/raphaeljs?hl=en-GB.
>
> --
> Sebastian Gurin <sgu...@softpoint.org>

Adam

unread,
May 26, 2010, 8:01:18 PM5/26/10
to Raphaël
just did a bit more research -- I guess I'm referring to parallel
projection (I think)....which is probably beyond current capabilities
in a browser??

Adam

unread,
May 26, 2010, 8:06:40 PM5/26/10
to Raphaël
or maybe perspective projection I mean?? newbie to raw graphics
program :)

Just want to project an image onto a couple of 3d-ish wall like
plates....:)

On May 27, 7:13 am, Adam <adam.jenk...@objecttraining.com.au> wrote:

Sebastian Gurin

unread,
May 26, 2010, 7:17:20 PM5/26/10
to raph...@googlegroups.com
On Wed, 26 May 2010 14:13:14 -0700 (PDT)
Adam <adam.j...@objecttraining.com.au> wrote:

> quick question, I don't suppose you have any thoughts on keystoning,
> i.e. longer on one side than the other??
>

Adam, a couple of points:

1) I really don't know if what you want can be done with a matrix transformation. take a look at the shear operation and play with the matrix parameters. Read about matrix tranformations.

2) I discontinue using the plugin since it doesn't adapt to raphaeljs.

3) the plugin works both in IE (vml) and the rest of the world (svg)

4) the skew operation is based on matrix transformation

5) svg supports skewX and skewY (thttp://www.w3.org/TR/SVG11/coords.html) that are much more reliable that my plugin but won't work on ie.

good look

--
Sebastian Gurin <sgu...@softpoint.org>

Adam

unread,
May 26, 2010, 9:44:21 PM5/26/10
to Raphaël
Thanks sebastion...and thanks for the skewX/skewY links, I'll have a
read

On May 27, 9:17 am, Sebastian Gurin <sgu...@softpoint.org> wrote:
> On Wed, 26 May 2010 14:13:14 -0700 (PDT)
>

Laurens Schuitemaker

unread,
Aug 6, 2015, 12:23:41 PM8/6/15
to Raphaël
Hello,

I found this post, and I was wondering whether it's possible to 'skew' only one side of the image, with Raphael JS?
As can be seen in the attachment. (the right rectangle and the 'marshall' text)

Thanks in advance!

Laurens

Op dinsdag 25 mei 2010 03:59:01 UTC+2 schreef Adam:
unnamed.png
test.jpg
Reply all
Reply to author
Forward
0 new messages