PageRenderTime 50ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/turbine/plugins/transform.php

https://github.com/sevir/Creamy
PHP | 275 lines | 199 code | 17 blank | 59 comment | 84 complexity | b3e338d5cc514099df25541c71f1fffe MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of Turbine
  4. * http://github.com/SirPepe/Turbine
  5. *
  6. * Copyright Peter Kröner
  7. * Licensed under GNU LGPL 3, see license.txt or http://www.gnu.org/licenses/
  8. */
  9. /**
  10. * Easy and extended transform
  11. * Adds vendor-specific versions of transform
  12. *
  13. * Usage: Use any currently known transform-property wihtout vendor-prefixes,
  14. * BUT NOT YET! transform-origin.
  15. * For IE you need to define width and height dimensions and use the same units (px/em)
  16. * for dimensions and translation
  17. * Example 1: width: 100px; height: 100px; transform: translate(2px, 2px);
  18. * Example 1: width: 20em; height: 20em; transform: translate(1em, 2em);
  19. * Example 3: width: 100px; height: 100px; transform: translate(2px, 2px) rotate(90deg);
  20. * Example 4:width: 100px; height: 100px; transform: skew(15deg,25deg);
  21. * Status: Beta
  22. * Version: 1.0
  23. *
  24. * @param mixed &$parsed
  25. * @return void
  26. */
  27. function transform(&$parsed){
  28. global $browser, $cssp;
  29. foreach($parsed as $block => $css){
  30. foreach($parsed[$block] as $selector => $styles){
  31. $width = 0;
  32. $height = 0;
  33. $width_unit = 'px';
  34. $height_unit = 'px';
  35. $rotate_x = 0;
  36. $rotate_y = 0;
  37. $translate_x = 0;
  38. $translate_y = 0;
  39. $translate_x_unit = 'px';
  40. $translate_y_unit = 'px';
  41. $scale_x = 1;
  42. $scale_y = 1;
  43. $rotate_before_translate = false;
  44. $scale_before_translate = false;
  45. if(isset($parsed[$block][$selector]['transform'])){
  46. // Creating good browser CSS
  47. $num_values = count($parsed[$block][$selector]['transform']);
  48. for($i = 0; $i < $num_values; $i++){
  49. $value = $parsed[$block][$selector]['transform'][$i];
  50. $newproperties = array(
  51. '-moz-transform' => array($value),
  52. '-o-transform' => array($value),
  53. '-webkit-transform' => array($value)
  54. );
  55. $cssp->insert_properties($newproperties, $block, $selector, null, 'transform');
  56. }
  57. // Applying the matrix-filter for IE
  58. // If we have width & height defined, then replicate transforms with the help of IE's matrix-filter
  59. if(isset($parsed[$block][$selector]['width'][0]) && isset($parsed[$block][$selector]['height'][0])){
  60. $values = explode(' ',implode(' ',$parsed[$block][$selector]['transform']));
  61. $num_values = count($values);
  62. for($i = 0; $i < $num_values; $i++){
  63. $value = $values[$i];
  64. // If we are dealing with a matrix-transformation
  65. if(preg_match('/matrix\(\D*([0-9\-]+)\s([0-9\-]+)\s([0-9\-]+)\s([0-9\-]+)\s([0-9\-]+)\s([0-9\-]+)\D*\)/i',$value,$matches) == 1){
  66. $matrix_a = $matches[1];
  67. $matrix_b = $matches[2];
  68. $matrix_c = $matches[3];
  69. $matrix_d = $matches[4];
  70. }
  71. else{
  72. // If we are dealing with a rotation
  73. if(preg_match('/rotate\(\D*([0-9\-\.]+)(deg|rad|grad)\D*\)/i',$value,$matches) == 1){
  74. $rotate_x = $matches[1];
  75. $rotate_x_unit = $matches[2];
  76. $rotate_y = $matches[1];
  77. $rotate_y_unit = $matches[2];
  78. }
  79. // If we are dealing with a scaling on the X-axis
  80. if(preg_match('/scaleX\(\D*([0-9\.]+)\D*\)/i',$value,$matches) == 1){
  81. $scale_x = $matches[1];
  82. }
  83. // If we are dealing with a scaling on the Y-axis
  84. if(preg_match('/scaleY\(\D*([0-9\.]+)\D*\)/i',$value,$matches) == 1){
  85. $scale_y = $matches[1];
  86. }
  87. // If we are dealing with a scaling on both axis
  88. if(preg_match('/scale\(\D*([0-9\.]+)\D*\)/i',$value,$matches) == 1){
  89. $scale_x = $matches[1];
  90. $scale_y = $matches[1];
  91. }
  92. // If we are dealing with a skew-transform on the X-axis
  93. if(preg_match('/skewX*\(\D*([0-9\-\.]+)(deg|rad|grad)\D*\)/i',$value,$matches) == 1){
  94. $rotate_x = $matches[1] * -1;
  95. $rotate_x_unit = $matches[2];
  96. }
  97. // If we are dealing with a skew-transform on the Y-axis
  98. if(preg_match('/skewY\(\D*([0-9\-\.]+)(deg|rad|grad)\D*\)/i',$value,$matches) == 1){
  99. $rotate_y = $matches[1] * -1;
  100. $rotate_y_unit = $matches[4];
  101. }
  102. // If we are dealing with a skew-transform on the both axis
  103. if(preg_match('/skew\(\D*([0-9\-\.]+)(deg|rad|grad)\D*,\D*([0-9\-\.]+)(deg|rad|grad)\D*\)/i',$value,$matches) == 1){
  104. $rotate_x = $matches[1] * -1;
  105. $rotate_x_unit = $matches[2];
  106. $rotate_y = $matches[3] * -1;
  107. $rotate_y_unit = $matches[4];
  108. }
  109. // If we are dealing with a translation
  110. if(preg_match('/translate\(\D*([0-9\.\-]+)([a-z%]*),\s*([0-9\.\-]+)([a-z%]*)\D*\)/i',$value,$matches) == 1){
  111. $translate_x = $matches[1];
  112. if($matches[2] != '') $translate_x_unit = $matches[2];
  113. if($matches[3] != '') $translate_y = $matches[3];
  114. if($matches[4] != '') $translate_y_unit = $matches[4];
  115. if($rotate_x != 0 || $rotate_y != 0) $rotate_before_translate = true;
  116. if($scale_x != 1 || $scale_y != 1) $scale_before_translate = true;
  117. }
  118. }
  119. }
  120. // Convert translation, rotation, scale and skew into matrix values
  121. if($rotate_x_unit == 'deg') $radian_x = deg2rad(floatval($rotate_x));
  122. if($rotate_x_unit == 'rad') $radian_x = floatval($rotate_x);
  123. if($rotate_x_unit == 'grad') $radian_x = deg2rad((floatval($rotate_x) / 400) * 360);
  124. if($rotate_y_unit == 'deg') $radian_y = deg2rad(floatval($rotate_y));
  125. if($rotate_y_unit == 'rad') $radian_y = floatval($rotate_y);
  126. if($rotate_y_unit == 'grad') $radian_y = deg2rad((floatval($rotate_y) / 400) * 360);
  127. $matrix_a = floatval(number_format(cos($radian_x),8,'.',''));
  128. $matrix_b = -1 * floatval(number_format(sin($radian_x),8,'.',''));
  129. $matrix_c = floatval(number_format(sin($radian_y),8,'.',''));
  130. $matrix_d = floatval(number_format(cos($radian_y),8,'.',''));
  131. $filter = 'progid:DXImageTransform.Microsoft.Matrix(Dx=1.0,Dy=1.0,M11='.($matrix_a * floatval($scale_x)).',M12='.($matrix_b * floatval($scale_x)).',M21='.($matrix_c * floatval($scale_y)).',M22='.($matrix_d * floatval($scale_y)).',sizingMethod=\'auto expand\')';
  132. // Adjust transforms for IEs, needs to come in first
  133. $newproperties = array();
  134. // If position-property is not set, or static set it
  135. if(!isset($parsed[$block][$selector]['position']) || $parsed[$block][$selector]['position'][0] == 'static'){
  136. $newproperties['position'] = array('relative');
  137. $cssp->insert_properties($newproperties, $block, $selector, null, 'transform');
  138. CSSP::comment($parsed[$block][$selector], 'position', 'Added by transform plugin');
  139. }
  140. //Include behavior to compensate for IEs auto expand feature
  141. $htc_path = rtrim(dirname($_SERVER['SCRIPT_NAME']),'/').'/plugins/transform/transform.htc';
  142. $parsed[$block][$selector]['behavior'] = array('url('.$htc_path.')');
  143. CSSP::comment($parsed[$block][$selector], 'behavior', 'Added by transform plugin');
  144. //Legacy IE-compliance
  145. if(floatval($browser->engine_version) < 8){
  146. //If filter-property not yet set
  147. if(!isset($parsed[$block][$selector]['filter'])){
  148. $parsed[$block][$selector]['filter'] = array($filter);
  149. }
  150. //If filter-property already set
  151. else{
  152. //Needs its filter-value to be put in first place!
  153. array_unshift($parsed[$block][$selector]['filter'],$filter);
  154. }
  155. CSSP::comment($parsed[$block][$selector], 'filter', 'Added by transform plugin');
  156. }
  157. else {
  158. //IE8-compliance (note: value inside apostrophes!)
  159. //If -ms-filter-property not yet set
  160. if(!isset($parsed[$block][$selector]['-ms-filter'])){
  161. $parsed[$block][$selector]['-ms-filter'] = array($filter);
  162. }
  163. //If -ms-filter-property already set
  164. else{
  165. //Needs its filter-value to be put in first place!
  166. array_unshift($parsed[$block][$selector]['-ms-filter'],$filter);
  167. }
  168. CSSP::comment($parsed[$block][$selector], '-ms-filter', 'Added by transform plugin');
  169. }
  170. //Set hasLayout
  171. $parsed[$block][$selector]['zoom'] = array('1');
  172. CSSP::comment($parsed[$block][$selector], 'zoom', 'Added by transform plugin');
  173. $newproperties = array();
  174. // Adjust translation to scaling
  175. if($scale_before_translate)
  176. {
  177. $translate_x = $translate_x * floatval($scale_x);
  178. $translate_y = $translate_y * floatval($scale_y);
  179. }
  180. // Adjust translation to rotation
  181. if($rotate_before_translate)
  182. {
  183. $translate_x = ($translate_x * cos($radian_x)) + ($translate_y * sin($radian_y));
  184. $translate_y = ($translate_x * sin($radian_x)) + ($translate_y * cos($radian_y));
  185. }
  186. if($translate_x_unit == 'px') $translate_x = round($translate_x);
  187. if($translate_y_unit == 'px') $translate_y = round($translate_y);
  188. // If position-property is not set, or not set to absolute
  189. if($parsed[$block][$selector]['position'][0] != 'absolute'){
  190. // Translation on x-axis
  191. if($translate_x > 0 && !isset($parsed[$block][$selector]['left']))
  192. {
  193. $newproperties['left'] = array($translate_x.$translate_x_unit);
  194. CSSP::comment($parsed[$block][$selector], 'left', 'Added by transform plugin');
  195. }
  196. elseif($translate_x < 0 && !isset($parsed[$block][$selector]['right']))
  197. {
  198. $newproperties['right'] = array(abs($translate_x).$translate_x_unit);
  199. CSSP::comment($parsed[$block][$selector], 'right', 'Added by transform plugin');
  200. }
  201. elseif($translate_x != 0 && !isset($parsed[$block][$selector]['margin-left']) && !isset($parsed[$block][$selector]['margin-right']))
  202. {
  203. $newproperties['margin-left'] = array($translate_x.$translate_x_unit);
  204. CSSP::comment($parsed[$block][$selector], 'margin-left', 'Added by transform plugin');
  205. $newproperties['margin-right'] = array((-1 * $translate_x).$translate_x_unit);
  206. CSSP::comment($parsed[$block][$selector], 'margin-right', 'Added by transform plugin');
  207. }
  208. // Translation on y-axis
  209. if($translate_y > 0 && !isset($parsed[$block][$selector]['top']))
  210. {
  211. $newproperties['top'] = array($translate_y.$translate_y_unit);
  212. CSSP::comment($parsed[$block][$selector], 'top', 'Added by transform plugin');
  213. }
  214. elseif($translate_y < 0 && !isset($parsed[$block][$selector]['bottom']))
  215. {
  216. $newproperties['bottom'] = array(abs($translate_y).$translate_y_unit);
  217. CSSP::comment($parsed[$block][$selector], 'bottom', 'Added by transform plugin');
  218. }
  219. elseif($translate_y != 0 && !isset($parsed[$block][$selector]['margin-left']) && !isset($parsed[$block][$selector]['margin-right']))
  220. {
  221. $newproperties['margin-top'] = array($translate_y.$translate_y_unit);
  222. CSSP::comment($parsed[$block][$selector], 'margin-top', 'Added by transform plugin');
  223. $newproperties['margin-bottom'] = array((-1 * $translate_y).$translate_y_unit);
  224. CSSP::comment($parsed[$block][$selector], 'margin-bottom', 'Added by transform plugin');
  225. }
  226. }
  227. // If position-property is set to absolute
  228. else
  229. {
  230. if($translate_x != 0 && !isset($parsed[$block][$selector]['margin-left']) && !isset($parsed[$block][$selector]['margin-right']))
  231. {
  232. $newproperties['margin-left'] = array($translate_x.$translate_x_unit);
  233. CSSP::comment($parsed[$block][$selector], 'margin-left', 'Added by transform plugin');
  234. $newproperties['margin-right'] = array((-1 * $translate_x).$translate_x_unit);
  235. CSSP::comment($parsed[$block][$selector], 'margin-right', 'Added by transform plugin');
  236. }
  237. if($translate_y != 0 && !isset($parsed[$block][$selector]['margin-left']) && !isset($parsed[$block][$selector]['margin-right']))
  238. {
  239. $newproperties['margin-top'] = array($translate_y.$translate_y_unit);
  240. CSSP::comment($parsed[$block][$selector], 'margin-top', 'Added by transform plugin');
  241. $newproperties['margin-bottom'] = array((-1 * $translate_y).$translate_y_unit);
  242. CSSP::comment($parsed[$block][$selector], 'margin-bottom', 'Added by transform plugin');
  243. }
  244. }
  245. $cssp->insert_properties($newproperties, $block, $selector, 'transform', null);
  246. }
  247. else{
  248. $cssp->report_error('The transform plugin requires a width and a height on the element "'.$parsed[$block][$selector].'" to make transforms work in Internet Explorer.');
  249. }
  250. }
  251. }
  252. }
  253. }
  254. /**
  255. * Register the plugin, MUST BE THE LAST ONE!
  256. */
  257. $cssp->register_plugin('before_glue', -999999, 'transform');
  258. ?>