├── LICENSE.md ├── README.md ├── jquery.transformTo.js.coffee └── jquery.transformTo.js /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 David Verhasselt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jquery.transformTo 2 | 3 | This library adds a handy method to jQuery elements that allows you to declaratively specify what dimensions and positions you'd like the element to have. The library then calculates the necessary translation and scaling required, and applies them using CSS transforms. During animations, these transforms are much more performant compared to editing the `left`, `top`, `width` or `height` CSS attributes. 4 | 5 | ## How To 6 | 7 | Here's some examples. Currently we support the `x`, `y`, `width` and `height` properties: 8 | ```javascript 9 | $("#block").transformTo({x: 50, y: 50}); 10 | $("#block").transformTo({x: "300px"}); 11 | $("#block").transformTo({width: "200px"}); 12 | $("#block").transformTo({height: "100px"}); 13 | 14 | // Let's dive into one 15 | $("#first").width(); //= 100 16 | $("#first").position(); //= {top: 200, left: 200} 17 | 18 | $("#first").transformTo({width: "400px", x: "100px"}); 19 | // This will set scaleX to 4.0 to get 400px width. 20 | // Setting scaleX to 4 also influences the position of the box, making it 21 | // start 150px more to the left. 22 | // Since we started at x = 200px, that means it's now visually at x = 50px, 23 | // and we need to set translateX(12.5px) (50px/scaleX) to get the final x to 24 | // be 100px. 25 | ``` 26 | 27 | # See Also 28 | 29 | * For more info about performance in animations: http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/ 30 | -------------------------------------------------------------------------------- /jquery.transformTo.js.coffee: -------------------------------------------------------------------------------- 1 | $ = jQuery 2 | $.fn.extend 3 | 4 | # Uses scale and translate transforms to shape element 5 | # instead of width/height and top/left 6 | # $('#el').transformTo x: 150px, y: 100px 7 | # $('#el').transformTo width: 300px, height: 500px 8 | # Check how regular jquery getters are influenced by transforms: 9 | # http://jsfiddle.net/8j6AF/22/ 10 | 11 | transformTo: (options) -> 12 | # Default settings 13 | settings = 14 | scaleX: 1.0 15 | scaleY: 1.0 16 | x: 0 17 | y: 0 18 | 19 | # Merge default settings with options. 20 | settings = $.extend settings, options 21 | 22 | # Remove "px" from values 23 | for key, value of settings 24 | settings[key] = value.replace("px","") if value instanceof String 25 | 26 | @each -> 27 | $this = $(this) 28 | $width = $this.width() 29 | $height = $this.height() 30 | currentLeft = if isNaN($this.css('left')) then 0 else $this.css('left') 31 | currentTop = if isNaN($this.css('top')) then 0 else $this.css('top') 32 | 33 | currently = $this.data('transformTo') || {} 34 | transforms = {scaleX: 1, scaleY: 1} 35 | 36 | # set scale 37 | if settings.width 38 | transforms.scaleX = settings.width / $width 39 | 40 | if settings.height 41 | transforms.scaleY = settings.height / $height 42 | 43 | # set translate 44 | if settings.x || (transforms.scaleX != 1) 45 | scaleExtraLeft = ($width/2)*(1-transforms.scaleX) 46 | transforms.translateX = (settings.x - (currentLeft + scaleExtraLeft))/transforms.scaleX 47 | 48 | if settings.y || (transforms.scaleY != 1) 49 | scaleExtraTop = ($height/2)*(1-transforms.scaleY) 50 | transforms.translateY = (settings.y - (currentTop + scaleExtraTop))/transforms.scaleY 51 | 52 | # save transforms 53 | $this.data('transformTo', transforms) 54 | 55 | # generate transform string 56 | transformValue = "" 57 | transformValue += "scaleX(#{transforms.scaleX}) " if transforms.scaleX? && transforms.scaleX != 1 58 | transformValue += "scaleY(#{transforms.scaleY}) " if transforms.scaleY? && transforms.scaleY != 1 59 | transformValue += "translateX(#{transforms.translateX}px) " if transforms.translateX? 60 | transformValue += "translateY(#{transforms.translateY}px) " if transforms.translateY? 61 | 62 | # generate CSS object 63 | css = {} 64 | for name in ["-webkit-transform", "-moz-transform", "-ms-transform", "-o-transform", "transform"] 65 | css[name] = transformValue 66 | 67 | # apply transform 68 | $this.css(css) 69 | -------------------------------------------------------------------------------- /jquery.transformTo.js: -------------------------------------------------------------------------------- 1 | var $; 2 | 3 | $ = jQuery; 4 | 5 | $.fn.extend({ 6 | transformTo: function(options) { 7 | var key, settings, value; 8 | settings = { 9 | scaleX: 1.0, 10 | scaleY: 1.0, 11 | x: 0, 12 | y: 0 13 | }; 14 | settings = $.extend(settings, options); 15 | for (key in settings) { 16 | value = settings[key]; 17 | if (value instanceof String) { 18 | settings[key] = value.replace("px", ""); 19 | } 20 | } 21 | return this.each(function() { 22 | var $height, $this, $width, css, currentLeft, currentTop, currently, name, scaleExtraLeft, scaleExtraTop, transformValue, transforms, _i, _len, _ref; 23 | $this = $(this); 24 | $width = $this.width(); 25 | $height = $this.height(); 26 | currentLeft = isNaN($this.css('left')) ? 0 : $this.css('left'); 27 | currentTop = isNaN($this.css('top')) ? 0 : $this.css('top'); 28 | currently = $this.data('transformTo') || {}; 29 | transforms = { 30 | scaleX: 1, 31 | scaleY: 1 32 | }; 33 | if (settings.width) { 34 | transforms.scaleX = settings.width / $width; 35 | } 36 | if (settings.height) { 37 | transforms.scaleY = settings.height / $height; 38 | } 39 | if (settings.x || (transforms.scaleX !== 1)) { 40 | scaleExtraLeft = ($width / 2) * (1 - transforms.scaleX); 41 | transforms.translateX = (settings.x - (currentLeft + scaleExtraLeft)) / transforms.scaleX; 42 | } 43 | if (settings.y || (transforms.scaleY !== 1)) { 44 | scaleExtraTop = ($height / 2) * (1 - transforms.scaleY); 45 | transforms.translateY = (settings.y - (currentTop + scaleExtraTop)) / transforms.scaleY; 46 | } 47 | $this.data('transformTo', transforms); 48 | transformValue = ""; 49 | if ((transforms.scaleX != null) && transforms.scaleX !== 1) { 50 | transformValue += "scaleX(" + transforms.scaleX + ") "; 51 | } 52 | if ((transforms.scaleY != null) && transforms.scaleY !== 1) { 53 | transformValue += "scaleY(" + transforms.scaleY + ") "; 54 | } 55 | if (transforms.translateX != null) { 56 | transformValue += "translateX(" + transforms.translateX + "px) "; 57 | } 58 | if (transforms.translateY != null) { 59 | transformValue += "translateY(" + transforms.translateY + "px) "; 60 | } 61 | css = {}; 62 | _ref = ["-webkit-transform", "-moz-transform", "-ms-transform", "-o-transform", "transform"]; 63 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { 64 | name = _ref[_i]; 65 | css[name] = transformValue; 66 | } 67 | return $this.css(css); 68 | }); 69 | } 70 | }); 71 | --------------------------------------------------------------------------------