From 646203f038fcddbc15c35e891d3bbd7aa1d8be1f Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 23 Apr 2014 19:47:30 +0200 Subject: [PATCH 1/7] revert from flexbox for pdf centering, use js for PDF setup --- css/print/pdf.css | 58 ++++++++++-------------------------- css/reveal.css | 2 ++ js/reveal.js | 75 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 86 insertions(+), 49 deletions(-) diff --git a/css/print/pdf.css b/css/print/pdf.css index bf90b3d3..559b05d7 100644 --- a/css/print/pdf.css +++ b/css/print/pdf.css @@ -17,8 +17,6 @@ body { font-size: 18pt; - width: 297mm; - height: 229mm; margin: 0 auto !important; border: 0; padding: 0; @@ -105,8 +103,6 @@ ul, ol, div, p { overflow: visible; display: block; - text-align: center; - -webkit-perspective: none; -moz-perspective: none; -ms-perspective: none; @@ -118,21 +114,15 @@ ul, ol, div, p { perspective-origin: 50% 50%; } .reveal .slides section { - page-break-after: always !important; visibility: visible !important; position: relative !important; - width: 100% !important; - height: 229mm !important; - min-height: 229mm !important; display: block !important; - overflow: hidden !important; + position: relative !important; - left: 0 !important; - top: 0 !important; margin: 0 !important; - padding: 2cm 2cm 0 2cm !important; + padding: 0 !important; box-sizing: border-box !important; opacity: 1 !important; @@ -154,30 +144,6 @@ ul, ol, div, p { height: auto !important; min-height: auto !important; } -.reveal .absolute-element { - margin-left: 2.2cm; - margin-top: 1.8cm; -} -.reveal section .fragment { - opacity: 1 !important; - visibility: visible !important; - - -webkit-transform: none !important; - -moz-transform: none !important; - -ms-transform: none !important; - transform: none !important; -} -.reveal section .slide-background { - position: absolute; - top: 0; - left: 0; - width: 100%; - z-index: 0; -} -.reveal section>* { - position: relative; - z-index: 1; -} .reveal img { box-shadow: none; } @@ -189,11 +155,17 @@ ul, ol, div, p { font-size: 16pt !important; } -.reveal.center .slides section:not(.stack) { - display: flex !important; - flex-direction: column; - align-items: center; - justify-content: center; - padding-top: 2em !important; - padding-bottom: 2em !important; +/* Slide backgrounds are placed inside of their slide when exporting to PDF */ +.reveal section .slide-background { + position: absolute; + top: 0; + left: 0; + width: 100%; + z-index: 0; } +/* All elements should be above the slide-background */ +.reveal section>* { + position: relative; + z-index: 1; +} + diff --git a/css/reveal.css b/css/reveal.css index 806d0649..7c3f5a1b 100644 --- a/css/reveal.css +++ b/css/reveal.css @@ -1328,6 +1328,8 @@ body { position: absolute; width: 100%; height: 100%; + top: 0; + left: 0; -webkit-perspective: 600px; -moz-perspective: 600px; diff --git a/js/reveal.js b/js/reveal.js index 7a032d0c..982b951c 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -333,6 +333,11 @@ var Reveal = (function(){ // Update all backgrounds updateBackground( true ); + // Special setup and config is required when printing to PDF + if( isPrintingPDF() ) { + setupPDF(); + } + // Notify listeners that the presentation is ready but use a 1ms // timeout to ensure it's not fired synchronously after #initialize() setTimeout( function() { @@ -401,6 +406,66 @@ var Reveal = (function(){ } + /** + * Configures the presentation for printing to a static + * PDF. + */ + function setupPDF() { + + // Dimensions of the content + var pageWidth = 1122, + pageHeight = 867; + + var slideWidth = 960, + slideHeight = 700; + + document.body.classList.add( 'print-pdf' ); + document.body.style.width = pageWidth + 'px'; + document.body.style.height = pageHeight + 'px'; + + // Slide and slide background layout + toArray( document.querySelectorAll( SLIDES_SELECTOR ) ).forEach( function( slide ) { + + // Vertical stacks are not centred since their section + // children will be + if( slide.classList.contains( 'stack' ) ) { + slide.style.top = 0; + } + else { + var left = ( pageWidth - slideWidth ) / 2; + var top = ( pageHeight - slideHeight ) / 2; + + if( config.center || slide.classList.contains( 'center' ) ) { + top = Math.max( ( pageHeight - getAbsoluteHeight( slide ) ) / 2, 0 ); + } + + slide.style.left = left + 'px'; + slide.style.top = top + 'px'; + slide.style.width = slideWidth + 'px'; + slide.style.height = slideHeight + 'px'; + + if( slide.scrollHeight > slideHeight ) { + slide.style.overflow = 'hidden'; + } + + var background = slide.querySelector( '.slide-background' ); + if( background ) { + background.style.width = pageWidth + 'px'; + background.style.height = pageHeight + 'px'; + background.style.top = -top + 'px'; + background.style.left = -left + 'px'; + } + } + + } ); + + // Show all fragments + toArray( document.querySelectorAll( SLIDES_SELECTOR + ' .fragment' ) ).forEach( function( fragment ) { + fragment.classList.add( 'visible' ); + } ); + + } + /** * Creates an HTML element and returns a reference to it. * If the element already exists the existing instance will @@ -428,9 +493,7 @@ var Reveal = (function(){ */ function createBackgrounds() { - if( isPrintingPDF() ) { - document.body.classList.add( 'print-pdf' ); - } + var printMode = isPrintingPDF(); // Clear prior backgrounds dom.background.innerHTML = ''; @@ -441,7 +504,7 @@ var Reveal = (function(){ var backgroundStack; - if( isPrintingPDF() ) { + if( printMode ) { backgroundStack = createBackground( slideh, slideh ); } else { @@ -451,7 +514,7 @@ var Reveal = (function(){ // Iterate over all vertical slides toArray( slideh.querySelectorAll( 'section' ) ).forEach( function( slidev ) { - if( isPrintingPDF() ) { + if( printMode ) { createBackground( slidev, slidev ); } else { @@ -887,7 +950,7 @@ var Reveal = (function(){ if( typeof child.offsetTop === 'number' && child.style ) { // Count # of abs children - if( child.style.position === 'absolute' ) { + if( window.getComputedStyle( child ).position === 'absolute' ) { absoluteChildren += 1; } From a49a78c454ab88120af37b0cc44df75cd0c31601 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Wed, 23 Apr 2014 21:18:13 +0200 Subject: [PATCH 2/7] remove needless condition --- js/reveal.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/js/reveal.js b/js/reveal.js index 982b951c..3ca9d6f3 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -412,10 +412,11 @@ var Reveal = (function(){ */ function setupPDF() { - // Dimensions of the content + // Dimensions of the PDF pages var pageWidth = 1122, pageHeight = 867; + // Dimensions of slides within the pages var slideWidth = 960, slideHeight = 700; @@ -428,12 +429,9 @@ var Reveal = (function(){ // Vertical stacks are not centred since their section // children will be - if( slide.classList.contains( 'stack' ) ) { - slide.style.top = 0; - } - else { - var left = ( pageWidth - slideWidth ) / 2; - var top = ( pageHeight - slideHeight ) / 2; + if( slide.classList.contains( 'stack' ) === false ) { + var left = ( pageWidth - slideWidth ) / 2, + top = ( pageHeight - slideHeight ) / 2; if( config.center || slide.classList.contains( 'center' ) ) { top = Math.max( ( pageHeight - getAbsoluteHeight( slide ) ) / 2, 0 ); From 3adaed2a1ee1bb3306cb30aa86b90819d1c03af6 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Sat, 26 Apr 2014 08:26:20 +0200 Subject: [PATCH 3/7] allow tall slides to spread over pages in pdf export --- js/reveal.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/js/reveal.js b/js/reveal.js index 3ca9d6f3..00c3aa04 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -430,22 +430,30 @@ var Reveal = (function(){ // Vertical stacks are not centred since their section // children will be if( slide.classList.contains( 'stack' ) === false ) { + // Center the slide inside of the page, giving the slide some margin var left = ( pageWidth - slideWidth ) / 2, top = ( pageHeight - slideHeight ) / 2; - if( config.center || slide.classList.contains( 'center' ) ) { - top = Math.max( ( pageHeight - getAbsoluteHeight( slide ) ) / 2, 0 ); + var contentHeight = getAbsoluteHeight( slide ); + var numberOfPages = Math.ceil( contentHeight / slideHeight ); + + // Top align when we're taller than a single page + if( numberOfPages > 1 ) { + top = 0; + } + // Center the slide vertically + else if( config.center || slide.classList.contains( 'center' ) ) { + top = Math.max( ( pageHeight - contentHeight ) / 2, 0 ); } + // Position the slide inside of the page slide.style.left = left + 'px'; slide.style.top = top + 'px'; slide.style.width = slideWidth + 'px'; - slide.style.height = slideHeight + 'px'; - - if( slide.scrollHeight > slideHeight ) { - slide.style.overflow = 'hidden'; - } + slide.style.height = ( slideHeight * numberOfPages ) + 'px'; + // TODO Backgrounds need to be multiplied when the slide + // stretches over multiple pages var background = slide.querySelector( '.slide-background' ); if( background ) { background.style.width = pageWidth + 'px'; From 059cca6fa4925de7e31c4f600b7954d9215fe878 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Sat, 26 Apr 2014 08:51:33 +0200 Subject: [PATCH 4/7] abide by configured slide width when exporting to pdf --- js/reveal.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/js/reveal.js b/js/reveal.js index 00c3aa04..b91ca988 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -412,13 +412,18 @@ var Reveal = (function(){ */ function setupPDF() { + // The aspect ratio of pages when saving to PDF in Chrome, + // we need to abide by this ratio when determining the pixel + // size of our pages + var pageAspectRatio = 1.295; + // Dimensions of the PDF pages - var pageWidth = 1122, - pageHeight = 867; + var pageWidth = config.width * 1.3, + pageHeight = Math.round( pageWidth / pageAspectRatio ); // Dimensions of slides within the pages - var slideWidth = 960, - slideHeight = 700; + var slideWidth = config.width, + slideHeight = config.height; document.body.classList.add( 'print-pdf' ); document.body.style.width = pageWidth + 'px'; From 2f90e9198d2387ca0e7eeca082e710759c02c57a Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Sat, 26 Apr 2014 09:34:58 +0200 Subject: [PATCH 5/7] some more flexibility for pdf export sizes --- js/reveal.js | 78 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 30 deletions(-) diff --git a/js/reveal.js b/js/reveal.js index b91ca988..523709cd 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -417,13 +417,15 @@ var Reveal = (function(){ // size of our pages var pageAspectRatio = 1.295; + var slideSize = getComputedSlideSize( window.innerWidth, window.innerHeight ); + // Dimensions of the PDF pages - var pageWidth = config.width * 1.3, + var pageWidth = Math.round( slideSize.width * ( 1 + config.margin ) ), pageHeight = Math.round( pageWidth / pageAspectRatio ); // Dimensions of slides within the pages - var slideWidth = config.width, - slideHeight = config.height; + var slideWidth = slideSize.width, + slideHeight = slideSize.height; document.body.classList.add( 'print-pdf' ); document.body.style.width = pageWidth + 'px'; @@ -440,7 +442,7 @@ var Reveal = (function(){ top = ( pageHeight - slideHeight ) / 2; var contentHeight = getAbsoluteHeight( slide ); - var numberOfPages = Math.ceil( contentHeight / slideHeight ); + var numberOfPages = Math.ceil( contentHeight / pageHeight ); // Top align when we're taller than a single page if( numberOfPages > 1 ) { @@ -462,7 +464,7 @@ var Reveal = (function(){ var background = slide.querySelector( '.slide-background' ); if( background ) { background.style.width = pageWidth + 'px'; - background.style.height = pageHeight + 'px'; + background.style.height = ( pageHeight * numberOfPages ) + 'px'; background.style.top = -top + 'px'; background.style.left = -left + 'px'; } @@ -1198,37 +1200,18 @@ var Reveal = (function(){ if( dom.wrapper && !isPrintingPDF() ) { - // Available space to scale within - var availableWidth = dom.wrapper.offsetWidth, - availableHeight = dom.wrapper.offsetHeight; + var size = getComputedSlideSize(); - // Reduce available space by margin - availableWidth -= ( availableHeight * config.margin ); - availableHeight -= ( availableHeight * config.margin ); - - // Dimensions of the content - var slideWidth = config.width, - slideHeight = config.height, - slidePadding = 20; // TODO Dig this out of DOM + var slidePadding = 20; // TODO Dig this out of DOM // Layout the contents of the slides layoutSlideContents( config.width, config.height, slidePadding ); - // Slide width may be a percentage of available width - if( typeof slideWidth === 'string' && /%$/.test( slideWidth ) ) { - slideWidth = parseInt( slideWidth, 10 ) / 100 * availableWidth; - } - - // Slide height may be a percentage of available height - if( typeof slideHeight === 'string' && /%$/.test( slideHeight ) ) { - slideHeight = parseInt( slideHeight, 10 ) / 100 * availableHeight; - } - - dom.slides.style.width = slideWidth + 'px'; - dom.slides.style.height = slideHeight + 'px'; + dom.slides.style.width = size.width + 'px'; + dom.slides.style.height = size.height + 'px'; // Determine scale of content to fit within available space - scale = Math.min( availableWidth / slideWidth, availableHeight / slideHeight ); + scale = Math.min( size.presentationWidth / size.width, size.presentationHeight / size.height ); // Respect max/min scale settings scale = Math.max( scale, config.minScale ); @@ -1265,7 +1248,7 @@ var Reveal = (function(){ slide.style.top = 0; } else { - slide.style.top = Math.max( ( ( slideHeight - getAbsoluteHeight( slide ) ) / 2 ) - slidePadding, 0 ) + 'px'; + slide.style.top = Math.max( ( ( size.height - getAbsoluteHeight( slide ) ) / 2 ) - slidePadding, 0 ) + 'px'; } } else { @@ -1313,6 +1296,41 @@ var Reveal = (function(){ } + /** + * Calculates the computed pixel size of our slides. These + * values are based on the width and height configuration + * options. + */ + function getComputedSlideSize( presentationWidth, presentationHeight ) { + + var size = { + // Slide size + width: config.width, + height: config.height, + + // Presentation size + presentationWidth: presentationWidth || dom.wrapper.offsetWidth, + presentationHeight: presentationHeight || dom.wrapper.offsetHeight + }; + + // Reduce available space by margin + size.presentationWidth -= ( size.presentationHeight * config.margin ); + size.presentationHeight -= ( size.presentationHeight * config.margin ); + + // Slide width may be a percentage of available width + if( typeof size.width === 'string' && /%$/.test( size.width ) ) { + size.width = parseInt( size.width, 10 ) / 100 * size.presentationWidth; + } + + // Slide height may be a percentage of available height + if( typeof size.height === 'string' && /%$/.test( size.height ) ) { + size.height = parseInt( size.height, 10 ) / 100 * size.presentationHeight; + } + + return size; + + } + /** * Stores the vertical index of a stack so that the same * vertical slide can be selected when navigating to and From 704022d948b11fd8a03b09c8c82f15b9073aa2ec Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Sat, 26 Apr 2014 10:22:18 +0200 Subject: [PATCH 6/7] simplify pdf layout --- js/reveal.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/js/reveal.js b/js/reveal.js index 523709cd..0ede8dec 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -444,12 +444,8 @@ var Reveal = (function(){ var contentHeight = getAbsoluteHeight( slide ); var numberOfPages = Math.ceil( contentHeight / pageHeight ); - // Top align when we're taller than a single page - if( numberOfPages > 1 ) { - top = 0; - } - // Center the slide vertically - else if( config.center || slide.classList.contains( 'center' ) ) { + // Center slides vertically + if( numberOfPages === 1 && config.center || slide.classList.contains( 'center' ) ) { top = Math.max( ( pageHeight - contentHeight ) / 2, 0 ); } @@ -457,7 +453,6 @@ var Reveal = (function(){ slide.style.left = left + 'px'; slide.style.top = top + 'px'; slide.style.width = slideWidth + 'px'; - slide.style.height = ( slideHeight * numberOfPages ) + 'px'; // TODO Backgrounds need to be multiplied when the slide // stretches over multiple pages From b797bbb61b2b07242e82812bf2f94e5af1371569 Mon Sep 17 00:00:00 2001 From: Hakim El Hattab Date: Sat, 26 Apr 2014 11:02:54 +0200 Subject: [PATCH 7/7] readme update, kill event listeners when printing pdf --- README.md | 2 +- js/reveal.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 823bd93b..31bb441d 100644 --- a/README.md +++ b/README.md @@ -585,7 +585,7 @@ Limitations: Presentations can be exported to PDF via a special print stylesheet. This feature requires that you use [Google Chrome](http://google.com/chrome). Here's an example of an exported presentation that's been uploaded to SlideShare: http://www.slideshare.net/hakimel/revealjs-13872948. -1. Open your presentation with [css/print/pdf.css](https://github.com/hakimel/reveal.js/blob/master/css/print/pdf.css) included on the page. The default index HTML lets you add *print-pdf* anywhere in the query to include the stylesheet, for example: [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf). +1. Open your presentation with `print-pdf` included anywhere in the query string. This triggers the default index HTML to load the PDF print stylesheet ([css/print/pdf.css](https://github.com/hakimel/reveal.js/blob/master/css/print/pdf.css)). You can test this with [lab.hakim.se/reveal-js?print-pdf](http://lab.hakim.se/reveal-js?print-pdf). 2. Open the in-browser print dialog (CMD+P). 3. Change the **Destination** setting to **Save as PDF**. 4. Change the **Layout** to **Landscape**. diff --git a/js/reveal.js b/js/reveal.js index 0ede8dec..55a10a29 100644 --- a/js/reveal.js +++ b/js/reveal.js @@ -335,6 +335,7 @@ var Reveal = (function(){ // Special setup and config is required when printing to PDF if( isPrintingPDF() ) { + removeEventListeners(); setupPDF(); }