Presentations

The Jetpack by WordPress.com Presentations class.

Defined (1)

The class is defined in the following location(s).

/modules/shortcodes/presentations.php  
  1. class Presentations { 
  2.  
  3. private $presentation_settings; 
  4. private $presentation_initialized; 
  5. private $scripts_and_style_included; 
  6.  
  7. /** 
  8. * Constructor 
  9. */ 
  10. function __construct() { 
  11. // Bail without 3.0. 
  12. if ( ! function_exists( '__return_false' ) ) 
  13. return; 
  14.  
  15. $this->presentation_initialized = false; 
  16. $this->scripts_and_style_included = false; 
  17.  
  18. // Registers shortcodes 
  19. add_action( 'wp_head', array( &$this, 'add_scripts' ), 1 ); 
  20.  
  21. add_shortcode( 'presentation', array( &$this, 'presentation_shortcode' ) ); 
  22. add_shortcode( 'slide', array( &$this, 'slide_shortcode' ) ); 
  23.  
  24. function add_scripts() { 
  25. $this->scripts_and_style_included = false; 
  26.  
  27. if ( empty( $GLOBALS['posts'] ) || !is_array( $GLOBALS['posts'] ) ) { 
  28. return; 
  29.  
  30. foreach ( $GLOBALS['posts'] as $p ) { 
  31. if ( has_shortcode( $p->post_content, 'presentation' ) ) { 
  32. $this->scripts_and_style_included = true; 
  33. break; 
  34.  
  35. if ( ! $this->scripts_and_style_included ) 
  36. return; 
  37.  
  38. $plugin = plugin_dir_url( __FILE__ ); 
  39. // Add CSS 
  40. wp_enqueue_style('presentations', $plugin . 'css/style.css'); 
  41. // Add JavaScript 
  42. wp_enqueue_script('jquery'); 
  43. wp_enqueue_script('jmpress',  
  44. $plugin . 'js/jmpress.min.js',  
  45. array('jquery'),  
  46. '0.4.5',  
  47. true); 
  48. wp_enqueue_script('presentations',  
  49. $plugin . 'js/main.js',  
  50. array('jquery', 'jmpress'),  
  51. false,  
  52. true); 
  53.  
  54. function presentation_shortcode( $atts, $content='' ) { 
  55. // Mark that we've found a valid [presentation] shortcode 
  56. $this->presentation_initialized = true; 
  57.  
  58. $atts = shortcode_atts( array( 
  59. 'duration' => '',  
  60. 'height' => '',  
  61. 'width' => '',  
  62. 'bgcolor' => '',  
  63. 'bgimg' => '',  
  64. 'autoplay' => '',  
  65.  
  66. // Settings 
  67. 'transition' => '',  
  68. 'scale' => '',  
  69. 'rotate' => '',  
  70. 'fade' => '',  
  71. 'fadebullets' => '',  
  72. ), $atts, 'presentation' ); 
  73.  
  74. $this->presentation_settings = array( 
  75. 'transition' => 'down',  
  76. 'scale' => 1,  
  77. 'rotate' => 0,  
  78. 'fade' => 'on',  
  79. 'fadebullets' => 0,  
  80. 'last' => array( 
  81. 'x' => 0,  
  82. 'y' => 0,  
  83. 'scale' => 1,  
  84. 'rotate' => 0,  
  85. ),  
  86. ); 
  87.  
  88. // Set the presentation-wide settings 
  89. if ( '' != trim( $atts['transition'] ) ) 
  90. $this->presentation_settings['transition'] = $atts['transition']; 
  91.  
  92. if ( '' != trim( $atts['scale'] ) ) 
  93. $this->presentation_settings['scale'] = floatval( $atts['scale'] ); 
  94.  
  95. if ( '' != trim( $atts['rotate'] ) ) 
  96. $this->presentation_settings['rotate'] = floatval( $atts['rotate'] ); 
  97.  
  98. if ( '' != trim( $atts['fade'] ) ) 
  99. $this->presentation_settings['fade'] = $atts['fade']; 
  100.  
  101. if ( '' != trim( $atts['fadebullets'] ) ) 
  102. $this->presentation_settings['fadebullets'] = $atts['fadebullets']; 
  103.  
  104. // Set any settings the slides don't care about 
  105. if ( '' != trim( $atts['duration'] ) ) 
  106. $duration = floatval( $atts['duration'] ) . 's'; 
  107. else 
  108. $duration = '1s'; 
  109.  
  110. // Autoplay durations are set in milliseconds 
  111. if ( '' != trim( $atts['autoplay'] ) ) 
  112. $autoplay = floatval( $atts['autoplay'] ) * 1000; 
  113. else 
  114. $autoplay = 0; // No autoplay 
  115.  
  116. // Set the presentation size as specified or with some nicely sized dimensions 
  117. if ( '' != trim( $atts['width'] ) ) 
  118. $this->presentation_settings['width'] = intval( $atts['width'] ); 
  119. else 
  120. $this->presentation_settings['width'] = 480; 
  121.  
  122. if ( '' != trim( $atts['height'] ) ) 
  123. $this->presentation_settings['height'] = intval( $atts['height'] ); 
  124. else 
  125. $this->presentation_settings['height'] = 370; 
  126.  
  127. // Hide the content by default in case the scripts fail 
  128. $style = 'display: none; width: ' . $this->presentation_settings['width'] . 'px; height: ' . $this->presentation_settings['height'] . 'px;'; 
  129.  
  130. // Check for background color XOR background image 
  131. // Use a white background if nothing specified 
  132. if ( preg_match( '/https?\:\/\/[^\'"\s]*/', $atts['bgimg'], $matches ) ) { 
  133. $style .= ' background-image: url("' . esc_url( $matches[0] ) . '");'; 
  134. } else if ( '' != trim( $atts['bgcolor'] ) ) { 
  135. $style .= ' background-color: ' . esc_attr( $atts['bgcolor'] ) . ';'; 
  136. } else { 
  137. $style .= ' background-color: #fff;'; 
  138.  
  139. // Not supported message style is inlined incase the style sheet doesn't get included 
  140. $out = "<section class='presentation-wrapper'>"; 
  141. $out.= "<p class='not-supported-msg' style='display: inherit; padding: 25%; text-align: center;'>"; 
  142. $out.= __( 'This slideshow could not be started. Try refreshing the page or viewing it in another browser.' , 'jetpack' ) . '</p>'; 
  143.  
  144. // Bail out unless the scripts were added 
  145. if ( $this->scripts_and_style_included ) { 
  146. $out.= sprintf( 
  147. '<div class="presentation" duration="%s" data-autoplay="%s" style="%s">',  
  148. esc_attr( $duration ),  
  149. esc_attr( $autoplay ),  
  150. esc_attr( $style ) 
  151. ); 
  152. $out.= "<div class='nav-arrow-left'></div>"; 
  153. $out.= "<div class='nav-arrow-right'></div>"; 
  154. $out.= "<div class='nav-fullscreen-button'></div>"; 
  155.  
  156. if ( $autoplay ) { 
  157. $out.= "<div class='autoplay-overlay' style='display: none'><p class='overlay-msg'>"; 
  158. $out.= __( 'Click to autoplay the presentation!' , 'jetpack' ); 
  159. $out.= "</p></div>"; 
  160.  
  161. $out.= do_shortcode( $content ); 
  162.  
  163. $out.= "</section>"; 
  164.  
  165. $this->presentation_initialized = false; 
  166. return $out; 
  167.  
  168. function slide_shortcode( $atts, $content = '' ) { 
  169. // Bail out unless wrapped by a [presentation] shortcode 
  170. if ( ! $this->presentation_initialized ) 
  171. return $content; 
  172.  
  173. $atts = shortcode_atts( array( 
  174. 'transition' => '',  
  175. 'scale' => '',  
  176. 'rotate' => '',  
  177. 'fade' => '',  
  178. 'fadebullets'=> '',  
  179. 'bgcolor' => '',  
  180. 'bgimg' => '',  
  181. ), $atts, 'slide' ); 
  182.  
  183. // Determine positioning based on transition 
  184. if ( '' == trim( $atts['transition'] ) ) 
  185. $atts['transition'] = $this->presentation_settings['transition']; 
  186.  
  187. // Setting the content scale 
  188. if ( '' == trim( $atts['scale'] ) ) 
  189. $atts['scale'] = $this->presentation_settings['scale']; 
  190.  
  191. if( '' == trim( $atts['scale'] ) ) 
  192. $scale = 1; 
  193. else 
  194. $scale = floatval( $atts['scale'] ); 
  195.  
  196. if ( $scale < 0 ) 
  197. $scale *= -1; 
  198.  
  199. // Setting the content rotation 
  200. if ( '' == trim( $atts['rotate'] ) ) 
  201. $atts['rotate'] = $this->presentation_settings['rotate']; 
  202.  
  203. if( '' == trim( $atts['rotate'] ) ) 
  204. $rotate = 0; 
  205. else 
  206. $rotate = floatval( $atts['rotate'] ); 
  207.  
  208. // Setting if the content should fade 
  209. if ( '' == trim( $atts['fade'] ) ) 
  210. $atts['fade'] = $this->presentation_settings['fade']; 
  211.  
  212. if ( 'on' == $atts['fade'] || 'true' == $atts['fade'] ) 
  213. $fade = 'fade'; 
  214. else 
  215. $fade = ''; 
  216.  
  217. // Setting if bullets should fade on step changes 
  218. if ( '' == trim( $atts['fadebullets'] ) ) 
  219. $atts['fadebullets'] = $this->presentation_settings['fadebullets']; 
  220.  
  221. if ( 'on' == $atts['fadebullets'] || 'true' == $atts['fadebullets'] ) 
  222. $fadebullets = 'fadebullets'; 
  223. else 
  224. $fadebullets = ''; 
  225.  
  226. $coords = $this->get_coords( array( 
  227. 'transition' => $atts['transition'],  
  228. 'scale' => $scale,  
  229. 'rotate' => $rotate,  
  230. )); 
  231.  
  232. $x = $coords['x']; 
  233. $y = $coords['y']; 
  234.  
  235. // Check for background color XOR background image 
  236. // Use a white background if nothing specified 
  237. if ( preg_match( '/https?\:\/\/[^\'"\s]*/', $atts['bgimg'], $matches ) ) { 
  238. $style = 'background-image: url("' . esc_url( $matches[0] ) . '");'; 
  239. } else if ( '' != trim( $atts['bgcolor'] ) ) { 
  240. $style = 'background-color: ' . esc_attr( $atts['bgcolor'] ) . ';'; 
  241. } else { 
  242. $style = ''; 
  243.  
  244. // Put everything together and let jmpress do the magic! 
  245. $out = sprintf( 
  246. '<div class="step %s %s" data-x="%s" data-y="%s" data-scale="%s" data-rotate="%s" style="%s">',  
  247. esc_attr( $fade ),  
  248. esc_attr( $fadebullets ),  
  249. esc_attr( $x ),  
  250. esc_attr( $y ),  
  251. esc_attr( $scale ),  
  252. esc_attr( $rotate ),  
  253. esc_attr( $style ) 
  254. ); 
  255.  
  256. $out.= "<div class='slide-content'>"; 
  257. $out.= do_shortcode( $content ); 
  258. $out.= "</div></div>"; 
  259. return $out; 
  260.  
  261. /** 
  262. * Determines the position of the next slide based on the position and scaling of the previous slide. 
  263. * @param array $args: an array with the following key-value pairs 
  264. * string $transition: the transition name, "up", "down", "left", or "right" 
  265. * float $scale: the scale of the next slide (used to determine the position of the slide after that) 
  266. * @return array with the 'x' and 'y' coordinates of the slide 
  267. */ 
  268. function get_coords( $args ) { 
  269. if ( 0 == $args['scale'] ) 
  270. $args['scale'] = 1; 
  271.  
  272. $width = $this->presentation_settings['width']; 
  273. $height = $this->presentation_settings['height']; 
  274. $last = $this->presentation_settings['last']; 
  275. $scale = $last['scale']; 
  276.  
  277. $next = array( 
  278. 'x' => $last['x'],  
  279. 'y' => $last['y'],  
  280. 'scale' => $args['scale'],  
  281. 'rotate' => $args['rotate'],  
  282. ); 
  283.  
  284. // All angles are measured from the vertical axis, so everything is backwards! 
  285. $diagAngle = atan2( $width, $height ); 
  286. $diagonal = sqrt( pow( $width, 2 ) + pow( $height, 2 ) ); 
  287.  
  288. // We offset the angles by the angle formed by the diagonal so that 
  289. // we can multiply the sines directly against the diagonal length 
  290. $theta = deg2rad( $last['rotate'] ) - $diagAngle; 
  291. $phi = deg2rad( $next['rotate'] ) - $diagAngle; 
  292.  
  293. // We start by displacing by the slide dimensions 
  294. $totalHorizDisp = $width * $scale; 
  295. $totalVertDisp = $height * $scale; 
  296.  
  297. // If the previous slide was rotated, we add the incremental offset from the rotation 
  298. // Namely the difference between the regular dimension (no rotation) and the component 
  299. // of the diagonal for that angle 
  300. $totalHorizDisp += ( ( ( abs( sin( $theta ) ) * $diagonal) - $width ) / 2) * $scale; 
  301. $totalVertDisp += ( ( ( abs( cos( $theta ) ) * $diagonal) - $height) / 2) * $scale; 
  302.  
  303. // Similarly, we check if the current slide has been rotated and add whatever additional 
  304. // offset has been added. This is so that two rotated corners don't clash with each other. 
  305. // Note: we are checking the raw angle relative to the vertical axis, NOT the diagonal angle. 
  306. if ( $next['rotate'] % 180 != 0 ) { 
  307. $totalHorizDisp += ( abs( ( sin( $phi ) * $diagonal ) - $width ) / 2) * $next['scale']; 
  308. $totalVertDisp += ( abs( ( cos( $phi ) * $diagonal ) - $height ) / 2) * $next['scale']; 
  309.  
  310. switch ( trim( $args['transition'] ) ) { 
  311. case 'none': 
  312. break; 
  313.  
  314. case 'left': 
  315. $next['x'] -= $totalHorizDisp; 
  316. break; 
  317.  
  318. case 'right': 
  319. $next['x'] += $totalHorizDisp; 
  320. break; 
  321.  
  322. case 'up': 
  323. $next['y'] -= $totalVertDisp; 
  324. break; 
  325.  
  326. case 'down': 
  327. default: 
  328. $next['y'] += $totalVertDisp; 
  329. break; 
  330.  
  331. $this->presentation_settings['last'] = $next; 
  332. return $next;