{"id":7005,"date":"2015-07-16T00:29:05","date_gmt":"2015-07-16T04:29:05","guid":{"rendered":"http:\/\/www.useragentman.com\/blog\/?p=7005"},"modified":"2015-07-26T12:50:32","modified_gmt":"2015-07-26T16:50:32","slug":"augment-photos-with-css3-matrix3d-transforms","status":"publish","type":"post","link":"http:\/\/www.useragentman.com\/blog\/2015\/07\/16\/augment-photos-with-css3-matrix3d-transforms\/","title":{"rendered":"Augment Photos With CSS3 matrix3d() Transforms"},"content":{"rendered":"\r\n<div class=\"full-bleed-container\">\r\n<div id=\"grid\" class=\"full-bleed\">\r\n  <div id=\"o2\" class=\"block full-bleed-transformed-object\">\r\n    <div id=\"time\">22:00 \r\n    <span id=\"secs\">00<\/span><\/div>\r\n    <div id=\"date\">Jul 24,2015<\/div>\r\n  <\/div>\r\n<\/div>\r\n<\/div>\r\n<p>The image above has dynamic HTML content super-imposed on top of a photo, styled using CSS 3D transforms to give the appearance that it is part of the picture.  If you are familiar with 3D transforms, you can imagine it would be very difficult to figure out what combination of <code>translate3d()<\/code>, <code>scale3d()<\/code> <code>rotate3d()<\/code> functions will produce the pixel perfect effect needed.  I knew it was possible to get exactly the shape needed using <code>matrix3d()<\/code>, but that it would be a chore to calculate the numbers to do this by hand.  For example, for the above example, we need the following CSS to style the digital watch face.<\/p>\n<blockquote class=\"code\">\n<pre>\r\ntransform: matrix3d(0.515078, -0.199333, 0, 0.00021, \r\n                    0.502268, 0.802615, 0, 0.00008, \r\n                    0, 0, 1, 0, 438, 240, 0, 1);\r\n\r\ntransform-origin: 0 0 0;\r\n<\/pre>\n<\/blockquote>\n<p>Unfortunately, those numbers aren&#8217;t the (x,y) coordinates for each of the corners of the transformed box that contains the date and time.  They are the <a href=\"http:\/\/franklinta.com\/author\/fta2012gmail-com\/\">values of a 4&#215;4 matrix used in computer graphics to produce 3d effects<\/a>.<\/p>\n<p>If you have no idea how matrix arithmetic works and you don&#8217;t have a degree in math, you may think you are out of luck here.  However, I created a tool, <a href=\"\/matrix\/\">The Matrix Construction Set<\/a>, to allow you to do this with a nice point and click GUI using HTML5 Drag and Drop.  Take a look at this video to see how easy it can be:<\/p>\n<blockquote class=\"instagram-media\" data-instgrm-version=\"4\" style=\" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px auto; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(50% - 2px); width:calc(50% - 2px);\">\n<div style=\"padding:8px;\">\n<div style=\" background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;\">\n<div style=\" background:url(data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAGFBMVEUiIiI9PT0eHh4gIB4hIBkcHBwcHBwcHBydr+JQAAAACHRSTlMABA4YHyQsM5jtaMwAAADfSURBVDjL7ZVBEgMhCAQBAf\/\/42xcNbpAqakcM0ftUmFAAIBE81IqBJdS3lS6zs3bIpB9WED3YYXFPmHRfT8sgyrCP1x8uEUxLMzNWElFOYCV6mHWWwMzdPEKHlhLw7NWJqkHc4uIZphavDzA2JPzUDsBZziNae2S6owH8xPmX8G7zzgKEOPUoYHvGz1TBCxMkd3kwNVbU0gKHkx+iZILf77IofhrY1nYFnB\/lQPb79drWOyJVa\/DAvg9B\/rLB4cC+Nqgdz\/TvBbBnr6GBReqn\/nRmDgaQEej7WhonozjF+Y2I\/fZou\/qAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;\"><\/div>\n<\/div>\n<p style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;\"><a href=\"https:\/\/instagram.com\/p\/443duJhWqp\/\" style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;\" target=\"_top\">A video posted by Zoltan &#34;Du Lac&#34; Hawryluk (@zoltandulac)<\/a> on <time style=\" font-family:Arial,sans-serif; font-size:14px; line-height:17px;\" datetime=\"2015-07-08T20:27:13+00:00\">Jul 8, 2015 at 1:27pm PDT<\/time><\/p>\n<\/div>\n<\/blockquote>\n<p><a href=\"\/matrix\/\" class=\"exampleLink\">Generate your own matrix3d() demos with The Matrix Construction Set<\/a><\/p>\n<p>The pink object represents the original HTML object without a transform applied, the purple one is the object transformed.  You can transform the object using the red crosshairs on the corner of the purple object.  As you do so, you will see the CSS above the grid change, giving you the correct <code>matrix3d()<\/code>.  Click on the <strong>Show Advanced Features<\/strong> in the top nav and you&#8217;ll be able to edit the HTML and CSS of the transformed objects so you insert your own images, fonts and text.  When you are done, you can bookmark the page so you can share your proof-of-concept-creations with other developers and designers.  Here are a few examples of some stuff I have created with the tool <strong>(you can see the original, untransformed HTML by unchecking the Hide UI link in the tools main nav):<\/strong><\/p>\n<table class=\"dataTable\">\n<thead>\n<tr>\n<th>Retro TV<\/th>\n<th>Constuctivist Building<\/th>\n<th>Animated Album Cover<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<td>\n<a target=\"_blank\" href=\"https:\/\/www.useragentman.com\/matrix\/#E4UwziAuBCCumQPYDsBMBeASuKACAYosALYBkAFgJYAmIAqgJLqTCwikBmwixADAB7oAjL07c+AT2GikA4QHYZiXlKEAWVADoAnAA41AZnkBWMTyFTjANiE7t9-fLVDUI7aSRDBQ3fI+ILdGMhUy4eVEETdyQI9Cs1NX9UVVRoxANBK1d-A0tdLXsHNScXN1JqdIARZlZ2MHJEAHcANRBkCuAABVAOSn5wGrZSGiF0AGVYACNiSkhcAGFyAENkAHNwYeoMbAg5whIKSGIAG3mUSDbIdAAeAAcAPgAVKjBcSlfjygA3EFwL-jmlGQuCWuEmx0QAGMANa4EDHEDES5-ZZzZavSYgNp-YArMAcIhI6i4WBgIGrFG-YhLFh9AzUAAUAEpcBxYMhIZBKChNAAoXnXSbAe6C4W857vN6vFDHCQg3C0YiITS4XCVRC4ZCIOaYkHHJYkEDUfnXAD0D1IkLAYDOyAudvQACpcABvXmq1WTRD8AC0ZIAXuSAFxe4C0YA+r38XkAX35puddA5PCRdreHFwEkQsFwjRWcyQuEQP2AwBov0g5F+tA4S1gxzmYEgEgRr0dpt5AGIAq73R7JksYatuOzqEHOxxIZCANyx-nd1C9j1gwfQ4fZ9rjqccOe8hO4d3OsaQ0DY+pLW6-cugsLEQ+4cgIW5B02mxrvzSNECTMkXSGIWhIHgIhKCWY4wE0f9iFNf9aBg614LAP1lkvCDbnIW4D1wdsuwCAAaBcl37Vd11HINYGAY4GUfSBn1fIlQIMTRVkodCJEgnhTQYpZTQ4AApIQQHmaAACtiAAWUQABRL5YFNFi2OYygOBZTteHU2dl3-CFgHHDh9M0j0CTtP1KH9EAgyBKsy0gQzVUaGhKyDNR1Nufg7IfEBKFWR9nNc9y+09Ihwx9XFqEoUkg2MXgAFJcFNXBdBijzixAYAOAhRogy+d5KHBEBd27IQQxAAlQAIxBUBKsrfjdLTzkuIMACImo825EF-blkCDJYf0QY54BADykGfJKPK9BAeCDMbAtwMsfMgIMfVQZLZoRDhFuW1blwHIcR03Ky0tmcbgrS0KlnCyKVvi3Bopiwqe1uCrF0wuqPXazqUB6vqBouDzjMgH1axmWVmrOCjKDS3AADkQEaJq8Ka8GyzShGlS1MBbkHIbZoB0zzL8tyPM+ZAQB9KtvN8oRhsQZ9ITAyEGTu3AfVwHxeDcplhpAAEfTA7zushS40o8hzqCckRYo86lgBY7reDZjnozjXkOLtJYgSht7VSx6hwrWIMRDc3d93mMYxlZIhKVwYcaGwjtO1t4ltZXPaNzHCiqMoal1jAU1IC+TQRNuVYWQVhWJ30zVEFCkBLxpE6wzSoMtVJjyKYWw2rH8tqOtmLqg1AfUuR+FKSwypogyoPW2ljTYDHGKYZjmAAJR5xIAGRBdoFnNzY1HQeYViF45NmMdBIQhCBNisCep5AIA\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/retro-tv.jpg\" alt=\"retro-tv\" width=\"240\" height=\"167\" class=\"alignnone size-full wp-image-7009\" \/><\/a><\/p>\n<p>This <a href=\"http:\/\/giphy.com\/gifs\/the-matrix-fJ1eCBjmMoEvu\">Matrix Animated GIF<\/a> is placed as a background image in a DOM element.  Along with the <code>matrix3d()<\/code> used to give the illusion it is in the screen, I used <a href=\"http:\/\/www.websitecodetutorials.com\/code\/css\/css-shapes.php\">a variation of the border-radius trick<\/a> to make HTML block the shape of a retro TV screen.<\/p>\n<\/td>\n<td>\n<a target=\"_blank\" href=\"https:\/\/www.useragentman.com\/matrix\/#E4UwziAuBCCumQPYDsBMBeASuKACAYosALYBkAFgJYAmIAqgJLqTCwikBmwixADAB7oAjL07c+AT2GikA9ABYAzItKyp80Vx5CpANl6pViIYNSLdRnegDsysT1SD5uw0kfoArAE4LbqYq8jRUFrWyCpW0NqREUAEWZWdjByRAB3ADUQZGjgAAVQDkp+cAS2UhohdABlWAAjYkpIXABhcgBDZABzcHLqDGwIJsISCkhiABtmlEgsyHQAHgAHAD4AdRBcZLbFjcRYYFx5sEWO3ABjcbawMABSRWoAIlrYSnHqSi6wB+Xn1-fPgDc8wA9McOstDmDkOdLtc7o9IOQQKA2hwZsBvojkSBUeiQVCIUcTtCLldbvcHliJABaLY7TFIiSbdo7fHEwlQmFk+EPWBfZZ8tnggBQIJWpDO1ymyBmMvQAAFKMRFkQmg9JWBgRxppraiBaldQZAJONwEioAA6DUPAHC4UAKlwAG9hbVEPxaZQAF4fToALlwbuAtGA1Ld-FtAF87RaVR8mi7gY6DWcANadbiwbLUs6IcZEAOgagA3D24HC6N2pO4OjIXPEYizXCUDi4CR7XCpDpNJC4RAAN2RwBoGyxuFoHDasHGTTAxtNYFL5YAxMZncLcIG2mmM3tsgHlxwOGcT2co3bV6h15uU+nM-vcCwOmDQDLz8LqxvHVUzqAssztg2Ec2lwLRiC-XByAQRY-WBYFUgQi1Un1MBGhAXNaEgeAiEoNpxjAK0eGBDCQGI64yLAWkWXAWNyEWXAvxXYwABpcEva9QOmalJwacYJADB5oH1K4ADkQDYG0N04mVqWQyhOiggM3TeW1N1zfNgADVIqBmW0Zn4SAqLaaJUgDRRFn4XBzMs3hA0uNNVPOPMC07HSQEcqTUhoREAw0XgLMcpF5MU3A-ICu1K1XIRcEWVj2Pol1N3GD4QGpIKFMgANeAtLxHOINpgE6D4AxEcLN30wy8Pk5AAwAKz5SAWwkW1tRk1CvRAAMAA5rHCirqSfZAwG1EgA1gRYdmAM4rnc4VyAkRYkSGgMpyQd9CJlNoUoORKYuM-5-VwUqIwrKtHWaKoqk4g4xwzGgl2FZc7uoDjqwAeWHIrkDw0DxEg6CwFgrVkrOC1U2AYFFkhxZFCqWqAHEHpvbc7z3agxuAcYAAoHiVNpul1F43l9C1asWToHgASk3WzbO0tDcGQRBqVAHY2kgRzb13LNqE9DqSoMeQLNwaxdC6srAyIEMAyZ5BZs3dKQqEfR-JOzcVVQxqUELEBLkawdHIHZEOHzUzIJoWhkFtU7hQtX5ic+ddWsM9rOqO1APHCysLSxFE0WRJ2uNdgXepO72qSMnZA7a703aEY71r5aOXdjgNUCUCX3mOS5+ObZBkrlsN8wcqSpOpYhEC9AbgGfEbiADMBptNLHUAtRRWKESnHNk-VU0aava6IevNibkAW7bjuu7L5nBuGoeG9H8f26Oqfyproa64XvCx9b5fO48zdy8rgeN6H6kcK+gXhd4bvkNqPvDNnuvz8+4qjtV3Ab+nk+55IF-5LfsdT+jkn5nwvoAj+X9KxSV6IoaodQGhNAABIABUACyAAZXAHQXoXSqL0eQ6BmgdDOLrXoHh0AXEQBAXouhKH5ggEAA\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/building.jpg\" alt=\"building\" width=\"240\" height=\"167\" class=\"alignnone size-full wp-image-7007\" \/><\/a><\/p>\n<p>It is now possible to float text on top of 3D objects, like <a href=\"http:\/\/graphic-engine.swarthmore.edu\/titles-on-the-fringe\/\">JJ Abrams did on the TV show <em>Fringe<\/em><\/a>.  The result is a look reminiscent of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Constructivism_%28art%29\">Constructivist Art Movement<\/a> (Photo Credit: <a href=\"https:\/\/www.flickr.com\/photos\/hernanpc\/15357044580\/\">Hern\u00e1n Pi\u00f1era<\/a>)<\/p>\n<\/td>\n<td>\n<a target=\"_blank\" href=\"https:\/\/www.useragentman.com\/matrix\/#E4UwziAuBCCumQPYDsBMBeASuKACAYosALYBkAFgJYAmIAqgJLqTCwikBmwixADAB7penbnwCeQ0kgHpUAFimJeEgKwBOETwCMErSoAcirYNRajEgGxyFXHqkH65ZpPfQWAzCsWoJ704vdBDy8kdwknM2pEdwARZlZ2MHJEAHcANRBkKOAABVAOSn5weLZSGi10AGVYACNiSkhcAGFyAENkAHNwMuoMbAhGwhIKSGIAGyaUSEzIdAAeAAcAPgBRVsbIchBceuRIAEI5gHpl0gBjMDBJvZn0AAFKYgWiRoAiC7AjjinPmpAa1qfMCQMRjcBbKAAOg+rwA3AAoeFHABUuDoyDOPGIM1wlA4uDEiFguBS7Q2iFwiAAbiBgMAaNtNttaBxWrAxo1gaDwLhkUdEfCAMSIVC4ADe8NwuABZwA1h1uLAsgBaTFjIgALlwLHaYAWrVAewRUrVmpJVGmCIAvojhVoADS4YWiiVS-XUaiUTpa3jG3DfPbKsCUABeIC1qF4vAW-D9AcgytZ9TGYi1r2g-0BADkQGw4ZL-VNlSkQJQOuRIFqaogxtRrYjITV1XLcAtxQWwQhaUH9WcvR0fZDePoQMQ-e7Pd7cL6C8QDR0vT6-WMvSBlVsyxWtVo-SkLWu9a0zuHcMhUsBWgs-criIgQ8qdcgwN8SFrH2AxusQAANAAU0f4ABKa8SxqWUGgfC8nxfYg3ygj8vz-ADgILZVEEg3UYLg3VP2mJCYxQqV3yw7V4Nwn9-wI69b3vdpHnWSgUC1MQQDGMZcBUMBcBAQE1yJSAQP+cCEzoudIEY5BmNY9jOO43i0Pga90NEhimIJaSOK4niIAUgSCxU8S1JYtjNLknT+Oou9lQMiTlQaWlVOQVUiT2LUvQKZB7MEsCIJslA7OmC9DKczElUrXFkA8rzUOUzyxNs+ygts0LXIiqLLX0uLHIChzgucsK3Mir1optJFUSaSpKkLYBtS2XAFRoXl+UFBrqHbKUZXlRUsi1WBgDGX9XnorpPmMsZIQAKwWDpXkA3AwDObgTN4adzXs090NABYeL0t1EGDYKtVAXDKBpP1qVpDh1RSLUqA9TJdxoTZt3cdwtBjP0N3LcL9CjD74VKu4bys2UQDELhWmxLixvbXgAFJ22B+9iKIWDSJwxDfy0KNkIRYshIglHX3Rp9yL-bG-qAvH0KJtH3zJrGcao+Faew0nMYp3GAcRCmEYlJGMOg1G2YQvDf2VPRKZQ-GfITVmSdFiiJZUKXqcF59hYVhnldVln4JI+nMZ1rmbUBmXhOVUHwYvKH1JMiV4cRmj1YNsiOaZqn4XNwn9c1w2xc55m0Jdv23YDj2UPl-2KMDz3St5p2rKjsOlclrnvbl33iejv9jaDmms7plPc7T5nk4xsW87j7n4SB9CrYh22YYdvmved8v2fD3WM5D7Pi8Z7uC8w0OK5jiOEQ7xXyfHmuE-59vC5F7XS89nvJ+XlX06HoW+9HkvN7LxetaNleUNNxE7gbm2eWb+FHfnpOj5zgf09Ai31-dwfe6LveX8P4fd6dzHrreOUZW4Cw-pXU+eM34+wAT-IB+8v6QNTgfT2KCkEm25j0dwVRaj1EaAACQACoAFkAAyuB2htQqpUHoch0BNHaMeMYPQVDoDOOqCAPQLAcK4SAIAA\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/eat-the-mint.jpg\" alt=\"eat-the-mint\" width=\"240\" height=\"167\" class=\"alignnone size-full wp-image-7008\" \/><\/a><\/p>\n<p>While we are talking about Constructivism, here is a animated version of a potential album cover of my band, <a href=\"http:\/\/conflictingplaid.com\/myTemplate.cgi\/index.html\">Conflicting Plaid<\/a> spoofing <em><a href=\"http:\/\/www.andrewgrahamdixon.com\/archive\/readArticle\/547\">Knigi<\/a> by <a href=\"https:\/\/en.wikipedia.org\/wiki\/Alexander_Rodchenko\">Alexander Rodchenko<\/a>.<\/p>\n<\/td>\n<\/tbody>\n<\/table>\n<h2>Difference Between <code>matrix()<\/code> and <code>matrix3d()<\/code><\/h2>\n<p>Note that the Matrix Construction Set has been around for a while for doing 2D <code>matrix()<\/code>transforms. Over the years, <a href=\"http:\/\/bfred.it\/\">Federico Brigante<\/a>, <a href=\"https:\/\/github.com\/gdelmas\">Gerard Delm\u00e0s<\/a> and others have requested a 3D version since the <strong>2D matrix() function only allows you to manipulate three corners<\/strong> of a rectangle, while <strong>3D ones allow manipulation of all four.<\/strong>  <\/p>\n<p>The one drawback is with <code>matrix3d()<\/code> (and 3D transforms in general) is that a bitmap of the original, un-transformed object is transformed, including fonts.  2D transforms will transform typography&#8217;s vector data, resulting in crisper results:<\/p>\n<table class=\"dataTable\">\n<thead>\n<tr>\n<th>2D transform using <code>matrix()<\/code><\/th>\n<th>3D transform using <code>matrix3d()<\/code><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/2d-example.jpg\" alt=\"2D Transform with Typography\" width=\"384\" height=\"452\" class=\"alignnone size-full wp-image-7047\" srcset=\"http:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/2d-example.jpg 384w, http:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/2d-example-254x300.jpg 254w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/>\n<\/td>\n<td>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/3d-example.jpg\" alt=\"3D Transform with Typography\" width=\"384\" height=\"452\" class=\"alignnone size-full wp-image-7048\" srcset=\"http:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/3d-example.jpg 384w, http:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/3d-example-254x300.jpg 254w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/>\n<\/td>\n<\/tbody>\n<\/table>\n<p>This can be worked around by making the original object (and typography) larger and then transforming it to a smaller object.  Here is the same example as above with the <code>width<\/code>, <code>height<\/code> and <code>font-size<\/code> increased by 300%:<\/p>\n<table class=\"dataTable\">\n<thead>\n<tr>\n<th>3D transform on smaller object<\/th>\n<th>3D transform on larger object<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/3d-example.jpg\" alt=\"3D Transform with Typography\" width=\"384\" height=\"452\" class=\"alignnone size-full wp-image-7048\" srcset=\"http:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/3d-example.jpg 384w, http:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/3d-example-254x300.jpg 254w\" sizes=\"auto, (max-width: 384px) 100vw, 384px\" \/>\n<\/td>\n<td><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/3d-large-text-example.jpg\" alt=\"3D Transform with Larger Typography\" width=\"384\" height=\"452\" class=\"alignnone size-full wp-image-7049\" \/>\n<\/td>\n<\/tbody>\n<\/table>\n<h2>Fallbacks<\/h2>\n<p>Note also that <a href=\"http:\/\/caniuse.com\/#search=3d+transform\"><strong>IE9 and Opera Mini do not support 3D transforms<\/strong><\/a> (however, IE9 <em>does support 2D transforms<\/em> using <code>-ms-transform<\/code>).  In order to handle these browsers correctly, you should either ensure that the original untransformed object is positioned someplace that makes sense without the transform applied (this can be done in the tool by dragging the red object around, which adjusts the object&#8217;s <code>transform-origin<\/code>).  You can also use <a href=\"modernizr.com\">Modernizr<\/a> to give alternate styles to browsers that don&#8217;t support 3D transforms if you want to get fancy.<\/p>\n<p>I know some of my readers might have expected a polyfill for older IE, since I&#8217;ve done some previous work supporting 2D transforms <a href=\"https:\/\/www.useragentman.com\/blog\/2010\/03\/09\/cross-browser-css-transforms-even-in-ie\/\">with<\/a> and <a href=\"https:\/\/www.useragentman.com\/IETransformsTranslator\/\">without Javascript<\/a>.  There isn&#8217;t one that I know of, and I don&#8217;t think it can be done accurately, if at all.<\/p>\n<h2>Other Caveats<\/h2>\n<ol>\n<li>The Matrix Construction Set currently only works on Desktop web browsers, due to mobile browsers lacking support of <a href=\"https:\/\/www.useragentman.com\/blog\/2010\/01\/10\/cross-browser-html5-drag-and-drop\/\">the HTML5 Drag and Drop API<\/a>.  There is a <a href=\"https:\/\/github.com\/timruffles\/ios-html5-drag-drop-shim\">polyfill that translates drag and drop events to touch events<\/a>, but unfortunately <a href=\"https:\/\/github.com\/timruffles\/ios-html5-drag-drop-shim\/issues\/27\">it doesn&#8217;t yet support offsetX\/Y and layerX\/Y<\/a>, which are needed for the pixel-precision this tool needs.  I may take a stab at adding this feature in the polyfill and updating the Matrix Construction Set with it in a future release.<\/li>\n<li>The Matrix Construction Set is not supported in IE10, even though it does support 3D transforms.  The code it produces, however, will work in IE10 and above.<\/li>\n<li>The tool only allows to insert a small subset of HTML in the transformed object, due to the dangers of XSS attacks by allowing arbitrary HTML.  The list of HTML tags supported can be seen in the <a href=\"\/matrix\/js\/sanitize.js\/sanitize\/config\/matrix.js\">Sanatize.js recipe that I use<\/a> to restrict the HTML devs can use in the tool.  If you want the tool to support more, please feel free to <a href=\"https:\/\/github.com\/zoltan-dulac\/Matrix-Construction-Set\">grab the source of the Matrix Construction Set<\/a> to add the support you wish on your own web server.<\/li>\n<\/ol>\n<h2>Further Reading<\/h2>\n<ul>\n<li>If you are really interested in knowing how <code>matrix3d()<\/code> works, <a href=\"http:\/\/franklinta.com\/author\/fta2012gmail-com\/\">Franklin Ta<\/a>&#8216;s article <a href=\"http:\/\/franklinta.com\/2014\/09\/08\/computing-css-matrix3d-transforms\/\">Computing CSS matrix3d transforms<\/a> is a great place to start.<\/li>\n<li>I have previously written an article, <a href=\"https:\/\/www.useragentman.com\/blog\/2011\/01\/07\/css3-matrix-transform-for-the-mathematically-challenged\/\">The CSS3 matrix() Transform for the Mathematically Challenged<\/a>, that explains how the math of 2D transforms work.<\/li>\n<\/ul>\n<h2>Shout Outs<\/h2>\n<p>Although this tool was built using libraries I have created over the years (<a href=\"https:\/\/www.useragentman.com\/blog\/config-js-%E2%80%93-a-javascript-cofiguration-library\/\">config<\/a>, <a href=\"https:\/\/www.useragentman.com\/blog\/2010\/06\/20\/visibleif-html5-custom-data-attributes-with-javascript-make-dynamic-interactive-forms\/\">visibleIf<\/a> and <a href=\"https:\/\/www.useragentman.com\/blog\/2010\/01\/10\/cross-browser-html5-drag-and-drop\/\">DragDropHelpers<\/a>), it would not be as cool as it is without the following free and open source projects:<\/p>\n\r\n<ul>\r\n  <li>The <a href=\"https:\/\/github.com\/GoogleChrome\">Google Chrome<\/a> team's \r\n  <a href=\"https:\/\/github.com\/GoogleChrome\/dialog-polyfill\">dialog polyfill<\/a>, for allowing non-Blink browsers to use HTML5 dialogs.<\/li>\r\n  <li><a href=\"http:\/\/pieroxy.net\/blog\/\">Pieroxy<\/a>'s <a href=\"http:\/\/pieroxy.net\/blog\/pages\/lz-string\/index.html\">lz-string<\/a>, to compress HTML and CSS data inside the hash of the tool's URL.<\/li>\r\n  <li><a href=\"http:\/\/www.lebenplusplus.de\/\">Gabriel Birke<\/a>'s <a href=\"https:\/\/github.com\/gbirke\/Sanitize.js\/blob\/master\/README.md\">sanatize.js<\/a> to ensure that the HTML stored by lz-string is not vulnerable to XSS attacks.<\/li>\r\n  <li><a href=\"http:\/\/jcoglan.com\/\">James Coglan<\/a>'s <a href=\"http:\/\/sylvester.jcoglan.com\/\">sylverster<\/a> to calculate the matrix arithmatic needed to calculate the CSS matrix() and matrix3d() numbers.<\/li>\r\n  <li><a href=\"http:\/\/modernizr.com\/\">modernizr<\/a> to detect 3D transform (and other cutting edge front-end tech) support. (I am using <a href=\"http:\/\/v3.modernizr.com\/download\/\">version 3<\/a>, which is currently in beta)<\/li>\r\n  <li>The <a href=\"http:\/\/www.fontspace.com\/gyusan\/matrix\">Matrix Font<\/a> by <a href=\"http:\/\/www.fontspace.com\/gyusan\/\">Gyusan<\/a> is used in the header of the Matrix Construction Set.<\/li>\r\n<\/ul>\r\n<p><a class=\"exampleLink\" href=\"https:\/\/github.com\/zoltan-dulac\/Matrix-Construction-Set\">Download your own copy of the Matrix Construction Set<\/a><\/p>\n<p><a class=\"exampleLink\" href=\"\/matrix\/\">Try out the Matrix Construction Set online now<\/a><\/p>\n<p><script async defer src=\"\/\/platform.instagram.com\/en_US\/embeds.js\"><\/script><\/p>\n<p><!-- THIS IS THE BOTTOM --><br \/>\n<script src=\"\/js\/fullbleed.js\"><\/script><br \/>\n<script src=\"\/examples\/matrix-watch\/js\/clock.js\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2015\/07\/teaser.jpg\" alt=\"teaser\" width=\"250\" height=\"205\" class=\"alignnone size-full wp-image-7078\" \/> It&#8217;s possible to <strong>super-impose dynamic HTML content on top of a photos<\/strong> using 3D transforms to give the appearance that it is part of the picture. However, using a combination of <code>translate3d()<\/code>, <code>scale3d()<\/code> and  <code>rotate3d()<\/code> functions to do this is difficult. This article discusses how to use the <code>matrix3d()<\/code> CSS transform with the <strong>Matrix Construction Set<\/strong> to get pixel-perfect 3D transforms easily and <strong>without any knowledge of matrix arithmetic.<\/strong>  It also discusses the <strong>differences between <code>matrix()<\/code> and <code>matrix3d()<\/code><\/strong>, as well as <strong>what fallbacks to use<\/strong> for browsers that don&#8217;t support transforms.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[171,9,38,59,173,41,170,172,1],"tags":[218,42,221,43,223,226,222],"class_list":["post-7005","post","type-post","status-publish","format-standard","hentry","category-3d","category-css","category-css3","category-matrix","category-matrix3d","category-transform","category-transform3d","category-transform3d-css3","category-uncategorized","tag-css","tag-css-transform","tag-css3","tag-css3-transform","tag-matrix","tag-matrix3d","tag-transform"],"_links":{"self":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/7005","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/comments?post=7005"}],"version-history":[{"count":72,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/7005\/revisions"}],"predecessor-version":[{"id":7081,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/7005\/revisions\/7081"}],"wp:attachment":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/media?parent=7005"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/categories?post=7005"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/tags?post=7005"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}