[Tut] Image Editor: Move Scale Skew Rotate and Spin with CSS Transform - Printable Version +- Sick Gaming (https://www.sickgaming.net) +-- Forum: Programming (https://www.sickgaming.net/forum-76.html) +--- Forum: PHP Development (https://www.sickgaming.net/forum-82.html) +--- Thread: [Tut] Image Editor: Move Scale Skew Rotate and Spin with CSS Transform (/thread-97118.html) |
[Tut] Image Editor: Move Scale Skew Rotate and Spin with CSS Transform - xSicKxBot - 09-08-2020 Image Editor: Move Scale Skew Rotate and Spin with CSS Transform <div style="margin: 5px 5% 10px 5%;"><img src="https://www.sickgaming.net/blog/wp-content/uploads/2020/07/image-editor-move-scale-skew-rotate-and-spin-with-css-transform.jpg" width="400" height="310" title="" alt="" /></div><div><p>Last modified on July 22nd, 2020.</p> <p>Are you interested in creating an image editor tool? If so, this article will help you to get started with it.</p> <p>An image editor will have a range of tools. It can be very basic with only tools like resize, rotate and crop. Or it can be super extensive like a Photoshop.</p> <p>Rotate is a basic and essential tool that is part of any image editor. Let us start with something easy and basic like rotate then add some more essential tools.</p> <p>I will be using CSS transform property as the core and add JavaScript to enrich the tool.</p> <p>This can become a basic starter toolkit that can be expanded to a full fledged image editor in the future.</p> <p>Following is a preview of the things to come.</p> <h2>What is inside?</h2> <ol> <li><a href="https://phppot.com/css/image-editor-move-scale-skew-rotate-and-spin-with-css-transform/#how-to-edit-an-image">How to edit an image?</a></li> <li><a href="https://phppot.com/css/image-editor-move-scale-skew-rotate-and-spin-with-css-transform/#a-quick-glance-on-css-transform-and-image-editing">A quick glance on CSS transform and image editing</a></li> <li><a href="https://phppot.com/css/image-editor-move-scale-skew-rotate-and-spin-with-css-transform/#examples-and-demo-on-image-editing">Examples and demo on image editing</a></li> <li><a href="https://phppot.com/css/image-editor-move-scale-skew-rotate-and-spin-with-css-transform/#conditions-and-exceptions-on-applying-transform-property">Conditions and exceptions on applying transform property</a></li> <li><a href="https://phppot.com/css/image-editor-move-scale-skew-rotate-and-spin-with-css-transform/#importance-of-respecting-system-preferences">Importance of respecting system preferences</a></li> </ol> <h2 id="how-to-edit-an-image">How to edit an image?</h2> <p>Do not underestimate the power of CSS. Gone or those days, where CSS just applies decoration on top of HTML and beautifies the document. CSS3 and beyond, with the combined support of HTML5, advancements in the browser support has change CSS to a powerful UI tool.</p> <p>It complements well with the JavaScript. When we combine it together, we can create wonders. The divide between thin-client and thick-client has vanished. The CSS is a very good beginner’s tool to start with simple image editor features.</p> <p>When you work on image editing capabilities with CSS, you must consider browser compatibility. Some browsers will not render as you code. So, we have to be carefully choosing the properties.</p> <p>I have used CSS <code>keyframes</code>rules to set the core properties.</p> <p>In an older article, we have see several <a href="https://phppot.com/jquery/jquery-background-image-animation/">animation effects with CSS and Javascript</a>.</p> <p>In this article, you can find the example code of the below items with a demo.</p> <ul> <li>Rotation and spin</li> <li>Skew</li> <li>Scale</li> <li>Translation</li> </ul> <h2 id="a-quick-glance-on-css-transform-and-image-editing">A quick glance on CSS transform and image editing</h2> <p>CSS <em>transform</em> property can be used to do basic image editing. It supports functions like rotation, skew, scale and translate.</p> <p>The key functions are <em>rotate()</em>, <em>skew()</em>, <em>scale(), translate()</em>.</p> <p>The transform functions have classification based on the axis of animation. For example <em>rotateX()</em>, <em>rotateY()</em> and more. This can be used for image animation.</p> <p>We can apply the transform functions in a combination way for a single UI element’s selector. When we use many transform function, the animation effects happen in a right to left order.</p> <h2 id="examples-and-demo-on-image-editing">Examples and demo on image editing</h2> <h3><strong>Scaling an image</strong></h3> <p>The scaling is a transform function that allows us to scale up or down the element’s dimension. The scaling transform output varies based on the function used and its parameters.</p> <p>The <em>scale()</em> function can have single or dual parameters. With a single parameter, it applies uniform scaling in both x, y-axis. When we supply separate values for the x, y-axis, then the scaling range will vary.</p> <p>With three params the <em>scale3d()</em> function allows scaling in x,y,z axis.</p> <p>We can also <a href="https://phppot.com/php/zoom-for-product-images-in-php-shopping-cart/">apply scaling</a> with respect to single axis by using scaleX(), <em>scaleY() </em>or<em> scaleZ().</em></p> <p>The above demo has a slider to scale up and down an image.</p> <p>Below code has the UI elements to apply scaling transform on an image element. It has a pallet with an image element and animation tools.</p> <p class="code-heading">image-scale/index.php</p> <pre class="prettyprint lang-php"><!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="../assets/css/phppot-style.css" type="text/css" rel="stylesheet" /> <link href="./assets/css/style.css" type="text/css" rel="stylesheet" /> <link href="../vendor/jquery/ui/jquery-ui.min.css" type="text/css" rel="stylesheet" /> <script src='../vendor/jquery/jquery-3.3.1.js' type='text/javascript'></script> <script src='../vendor/jquery/ui/jquery-ui.min.js' type='text/javascript'></script> </head> <body> <div class="phppot-container"> <div class="container"> <div class="image-demo-box"> <div id="slider"> <div id="scale-handle" class="ui-slider-handle"></div> </div> <img src='../sweet.jpg' id='image' /> </div> </div> </div> <script src='./assets/js/scale.js'></script> </body> </html> </pre> <p>This jQuery script initiates UI slider by setting the min max ranges. The slider handle will show the scaling factor.</p> <p>On dragging the slider, the script applies scaling transform on the image element. The slider’s step property defines the scaling multiples.</p> <p>On dragging the slider handle, the script will populate the scaling factor in the handle.</p> <p class="code-heading">image-scale/assets/js/scale.js</p> <pre class="prettyprint lang-php">$(document).ready(function() { var scaleX = 2; var handle = $("#scale-handle"); $("#slider").slider({ min : 1, max : 2.5, value: scaleX, step: 0.1, create : function() { handle.text(scaleX+"x"); scale(scaleX); }, slide : function(event, ui) { scaleX = ui.value; handle.text(scaleX + "x"); scale(scaleX); } }); }); function scale(scaleX) { $('#image').css('transform', 'scale(' + scaleX + ')'); } </pre> <h3><strong>Translating image element</strong></h3> <p>Like other transform functionality, the <em>translate()</em> function performs 2D, 3D translation.</p> <p>The <em>translate()</em> function with one or two params results in 2D translation. The two params are to move the image in the x, y-axis of a 2D plane. With single param, the <em>translate()</em> will happen in a horizontal direction.</p> <p>The <em>translateX()</em> and <em>translateY()</em> are for implementing translation in a particular direction.</p> <p>The <em>translate3d() </em>with x, y, z factors allows creating 3D animation.</p> <p>In this demo, there are two sliders in horizontal and vertical directions. On dragging the handle of these sliders, it moves the image on the 2D plane shown above.</p> <p>This HTML shows the template elements to set the image-translate demo.</p> <p class="code-heading">image-translate/index.php</p> <pre class="prettyprint lang-php"><!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="../assets/css/phppot-style.css" type="text/css" rel="stylesheet" /> <link href="./assets/css/style.css" type="text/css" rel="stylesheet" /> <link href="../vendor/jquery/ui/jquery-ui.min.css" type="text/css" rel="stylesheet" /> <script src='../vendor/jquery/jquery-3.3.1.js' type='text/javascript'></script> <script src='../vendor/jquery/ui/jquery-ui.min.js' type='text/javascript'></script> </head> <body> <div class="phppot-container"> <div class="container"> <div class="image-demo-box"> <div id="slider"> <div id="translate-x" class="ui-slider-handle"></div> </div> <div id="v-slider"> <div id="translate-y" class="ui-slider-handle"></div> </div> <img src='../sweet.jpg' id='image' /> </div> </div> </div> <script src='./assets/js/translate.js'></script> </body> </html> </pre> <p>This script sets the horizontal and vertical translation slider properties. The horizontal slider has the range between o -160. And, the vertical translation ranges between 0 to 50.</p> <p class="code-heading">image-translate/assets/js/translate.js</p> <pre class="prettyprint lang-php">$(document).ready(function() { var translateX; var handle = $("#translate-x"); $("#slider").slider({ range : "min", min : 0, max : 160, create : function() { handle.text($(this).slider("value") + " px"); }, slide : function(event, ui) { translateX = ui.value; handle.text(translateX + " px"); translate(translateX); } }); var translateY; var vhandle = $("#translate-y"); $("#v-slider").slider({ range : "min", min : 0, max : 50, orientation : "vertical", create : function() { vhandle.text($(this).slider("value") + " px"); }, slide : function(event, ui) { translateY = ui.value; vhandle.text(translateY + " px"); translatey(translateY); } }); }); function translate(translateX) { $('#image').css('transform', 'translateX(' + translateX + 'px)'); } function translatey(translateY) { $('#image').css('transform', 'translateY(' + translateY + 'px)'); } </pre> <h3>Tools for rotating an image</h3> <p>Ah yes, we have reached the rotate tool. This is a core feature in any image editor. <a href="https://phppot.com/jquery/jquery-image-rotate/">Rotation spins the image</a> or other UI elements based on the angle specified.</p> <p>With a negative degree, the animation will happen in counter-clockwise rotation.</p> <p>Like scale and translate, rotate function also has classification based on the axis. Those are,</p> <ul> <li>rotate(angle)</li> <li>rotate3d(x, y, z, angle)</li> <li>rotateX(angle)</li> <li>rotateY(angle)</li> <li>rotateZ(angle)</li> </ul> <p>The <em>rotate3d() </em>function needs the angle and the x, y, z co-ordinates of the rotation axis.</p> <p>A <em>spin</em> will make the image rotate from 0 to 360 degrees. You can stop spinning or refresh the image orientation back to its original.</p> <p class="code-heading">image-rorate/index.php</p> <pre class="prettyprint lang-php"><!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="../assets/css/phppot-style.css" type="text/css" rel="stylesheet" /> <link href="./assets/css/style.css" type="text/css" rel="stylesheet" /> <link href="../vendor/jquery/ui/jquery-ui.min.css" type="text/css" rel="stylesheet" /> <script src='../vendor/jquery/jquery-3.3.1.js' type='text/javascript'></script> <script src='../vendor/jquery/ui/jquery-ui.min.js' type='text/javascript'></script> </head> <body> <div class="phppot-container"> <div class="container"> <input type='text' id='txtInputAngle' class="degree" value="10" /> <input type='button' id='btnRotate' value='Rotate' /> <input type='button' id='btnSpin' value='Spin' data-state='off' /> <input type='button' id='btnRefresh' value='Refresh' /> <div class="image-demo-box"> <div id="slider"> <div id="rotation-angle" class="ui-slider-handle"></div> </div> <img src='../sweet.jpg' id='image' /> </div> </div> </div> <script src='./assets/js/rotate.js'></script> </body> </html> </pre> <p>I have used CSS <em>keyframes </em>to allow continuous spinning. Below CSS shows the styles used for the image rotation demo.</p> <p class="code-heading">image-rorate/assets/css/style.css</p> <pre class="prettyprint lang-php">.image-demo-box { border: #CCC 1px solid; text-align: center; margin: 15px 0px; } input[type=button] { width: 65px; margin-right: 8px; outline: none; background: #f6f5f6; } input.degree { width: 50px; } #image { margin: 50px auto; border: #f6f5f6 10px solid; width: 200px; } .rotate { animation: rotation 8s infinite linear; } div#slider { border-bottom: 1px solid #c5c5c5; } #slider .ui-slider-range { background: #c5c5c5; } #rotation-angle { width: 50px; padding: 3px 5px 1px 5px; font-size: 0.8em; text-align: center; border-radius: 2px; outline: none; } .ui-slider-handle.ui-corner-all.ui-state-default { border: 1px solid #c5c5c5; background: #f6f6f6; font-weight: normal; color: #454545; } @keyframes rotation { from { transform: rotate(0deg); } to { transform: rotate(359deg); } } </pre> <p>When you click the rotation tool, a jQuery script rotates the image based on the specified angle.</p> <p>It changes the images’ transform property using jQuery <em>$.css() </em>function.</p> <p>The rotation slider ranges from 0 to 360 degrees. I have added the rotation script below. It shows how to turn on a jQuery UI slider to rotate an image element.</p> <p class="code-heading">image-rorate/assets/js/rotate.js</p> <pre class="prettyprint lang-php">$(document).ready(function() { var rotationAngle; var handle = $("#rotation-angle"); $("#slider").slider({ range : "min", min : 0, max : 360, create : function() { handle.text($(this).slider("value") + " deg"); }, slide : function(event, ui) { $('#image').removeClass('rotate'); rotationAngle = ui.value; handle.text(rotationAngle + " deg"); rotate(rotationAngle); } }); $('#btnSpin').on('click', function() { if ($(this).data('state') == 'off') { spin($(this)); } else { stopSpin($(this)); } }); $('#btnRotate').on('click', function() { $('#image').removeClass('rotate'); rotationAngle = $('#txtInputAngle').val(); rotate(rotationAngle); }); $('#btnRefresh').on('click', function() { $('#image').removeClass('rotate'); rotate(0); }); }); function spin(buttonElement) { $('#image').addClass('rotate'); $("#image").css("animation-play-state", "running"); $(buttonElement).data('state', 'on'); $(buttonElement).val('Stop'); } function stopSpin(buttonElement) { $("#image").css("animation-play-state", "paused"); $(buttonElement).data('state', 'off'); $(buttonElement).val('Spin'); } function rotate(rotationAngle) { if ($('#btnSpin').data('state') == 'on') { stopSpin($('#btnSpin')); } $('#image').css('transform', 'rotate(' + rotationAngle + 'deg)'); } </pre> <h3><strong>Apply skew transform</strong></h3> <p>By changing each point of the element in a fixed direction will skew the element. This change will tilt or skews the elements layout based on the specified angle.</p> <p>The skew transform functions <em>skewX()</em>,<em> skewY()</em>, <em>skewZ()</em> tilting element boxes along with the X, Y, Z axis.</p> <p class="code-heading">image-skew/index.php</p> <pre class="prettyprint lang-php"><!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="../assets/css/phppot-style.css" type="text/css" rel="stylesheet" /> <link href="./assets/css/style.css" type="text/css" rel="stylesheet" /> <link href="../vendor/jquery/ui/jquery-ui.min.css" type="text/css" rel="stylesheet" /> <script src='../vendor/jquery/jquery-3.3.1.js' type='text/javascript'></script> <script src='../vendor/jquery/ui/jquery-ui.min.js' type='text/javascript'></script> </head> <body> <div class="phppot-container"> <div class="container"> <div class="image-demo-box"> <div id="slider"> <div id="skew-angle" class="ui-slider-handle"></div> </div> <img src='../sweet.jpg' id='image' /> </div> </div> </div> <script src='./assets/js/skew.js'></script> </body> </html> </pre> <p class="code-heading">image-skew/assets/js/skew.js</p> <pre class="prettyprint lang-php">$(document).ready(function() { var skewAngle; var handle = $("#skew-angle"); $("#slider").slider({ range : "min", min : 0, max : 40, create : function() { handle.text($(this).slider("value") + " deg"); }, slide : function(event, ui) { skewAngle = ui.value; handle.text(skewAngle + " deg"); skew(skewAngle); } }); }); function skew(skewAngle) { $('#image').css('transform', 'skew(' + skewAngle + 'deg)'); } </pre> <h2 id="conditions-and-exceptions-on-applying-transform-property">Conditions and exceptions on applying transform property</h2> <p>The CSS transform property will not work with some UI elements.</p> <p>For example, table column element <col>, table column group element <col-group>, and more. Those are non-transformable elements.</p> <p><strong>What are transformable elements?</strong></p> <p>Most of the UI elements enclosed with the CSS box model are transformable. The following image shows the HTML element layout enclosed by a CSS box model.</p> <p><img loading="lazy" class="alignnone size-full wp-image-11413" src="https://phppot.com/wp-content/uploads/2020/02/css-box-model.jpg" alt="CSS Box Model" width="400" height="310" srcset="https://phppot.com/wp-content/uploads/2020/02/css-box-model.jpg 400w, https://phppot.com/wp-content/uploads/2020/02/css-box-model-300x233.jpg 300w" sizes="(max-width: 400px) 100vw, 400px"></p> <p>Also, renderable graphical elements, clipPath elements are also known as a transformable element.</p> <h2 id="importance-of-respecting-system-preferences">Importance of respecting system preferences</h2> <p>The system preferences will affect the motion of elements. If your system preferences is set to reduce animation is on, it will omit the animation effect of the above demo.</p> <p>To respect this settings we have to add a CSS media rule to set the<br /><em>prefers-reduced-motion</em>. The possible values are <em>no-preferences and reduce.</em></p> <p>This media rule with <em>reduce</em> option provides a CSS block to suppress animation.</p> <pre class="prettyprint lang-php">@media (prefers-reduced-motion: reduce) { .rotate { transform: none; } } </pre> <p>In the above examples, I have used the media rule to respect the user’s system preferences. You can test this with the demo by enabling the <em>reduced-motion</em>.</p> <p><img class="wp-image-11407" src="https://phppot.com/wp-content/uploads/2020/02/system-preferences-to-reduce-animation-550x413.jpg" alt="System Preferences to Reduce Animation" srcset="https://phppot.com/wp-content/uploads/2020/02/system-preferences-to-reduce-animation-550x413.jpg 550w, https://phppot.com/wp-content/uploads/2020/02/system-preferences-to-reduce-animation-300x226.jpg 300w, https://phppot.com/wp-content/uploads/2020/02/system-preferences-to-reduce-animation.jpg 600w" sizes="(max-width: 550px) 100vw, 550px"></p> <h2>Conclusion</h2> <p>We have seen the CSS transform based image editing. This is just a beginning only. This can serve as a bootstrap for building a full fledged image editor.</p> <p>With CSS <em>transform</em>, we have added JavaScript and enriched the tool. We have also added various motion effects.</p> <p>I have added most of the template files and the jQuery scripts above. But you can find the complete bundle with the downloadable source code here below.</p> <p><a class="download" href="https://phppot.com/downloads/image-animation-with-css-transform.zip">Download</a></p> <p> <!-- #comments --> </p> <div class="related-articles"> <h2>Popular Articles</h2> </p></div> <p> <a href="https://phppot.com/css/image-editor-move-scale-skew-rotate-and-spin-with-css-transform/#top" class="top">↑ Back to Top</a> </p> </div> https://www.sickgaming.net/blog/2020/07/22/image-editor-move-scale-skew-rotate-and-spin-with-css-transform/ |