add , adds wrapper element around background images/videos/iframes

edit
Hakim El Hattab 2018-04-27 15:53:02 +02:00
parent de41f6cf50
commit 4ba0d73345
5 changed files with 57 additions and 31 deletions

View File

@ -625,11 +625,12 @@ All CSS color formats are supported, like rgba() or hsl().
By default, background images are resized to cover the full page. Available options: By default, background images are resized to cover the full page. Available options:
| Attribute | Default | Description | | Attribute | Default | Description |
| :--------------------------- | :--------- | :---------- | | :------------------------------- | :--------- | :---------- |
| data-background-image | | URL of the image to show. GIFs restart when the slide opens. | | data-background-image | | URL of the image to show. GIFs restart when the slide opens. |
| data-background-size | cover | See [background-size](https://developer.mozilla.org/docs/Web/CSS/background-size) on MDN. | | data-background-size | cover | See [background-size](https://developer.mozilla.org/docs/Web/CSS/background-size) on MDN. |
| data-background-position | center | See [background-position](https://developer.mozilla.org/docs/Web/CSS/background-position) on MDN. | | data-background-position | center | See [background-position](https://developer.mozilla.org/docs/Web/CSS/background-position) on MDN. |
| data-background-repeat | no-repeat | See [background-repeat](https://developer.mozilla.org/docs/Web/CSS/background-repeat) on MDN. | | data-background-repeat | no-repeat | See [background-repeat](https://developer.mozilla.org/docs/Web/CSS/background-repeat) on MDN. |
| data-background-content-opacity | 1 | Opacity of the background image on a 0-1 scale. 0 is transparent and 1 is fully opaque. |
```html ```html
<section data-background-image="http://example.com/image.png"> <section data-background-image="http://example.com/image.png">
<h2>Image</h2> <h2>Image</h2>
@ -648,6 +649,7 @@ Automatically plays a full size video behind the slide.
| data-background-video-loop | false | Flags if the video should play repeatedly. | | data-background-video-loop | false | Flags if the video should play repeatedly. |
| data-background-video-muted | false | Flags if the audio should be muted. | | data-background-video-muted | false | Flags if the audio should be muted. |
| data-background-size | cover | Use `cover` for full screen and some cropping or `contain` for letterboxing. | | data-background-size | cover | Use `cover` for full screen and some cropping or `contain` for letterboxing. |
| data-background-content-opacity | 1 | Opacity of the background video on a 0-1 scale. 0 is transparent and 1 is fully opaque. |
```html ```html
<section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm" data-background-video-loop data-background-video-muted> <section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm" data-background-video-loop data-background-video-muted>

View File

@ -1015,10 +1015,15 @@ body {
visibility: hidden; visibility: hidden;
overflow: hidden; overflow: hidden;
background-color: transparent; background-color: transparent;
transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
.reveal .slide-background-content {
position: absolute;
width: 100%;
height: 100%;
background-position: 50% 50%; background-position: 50% 50%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover; }
transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
.reveal .slide-background.stack { .reveal .slide-background.stack {
display: block; } display: block; }

View File

@ -1091,11 +1091,18 @@ $controlsArrowAngleActive: 36deg;
overflow: hidden; overflow: hidden;
background-color: rgba( 0, 0, 0, 0 ); background-color: rgba( 0, 0, 0, 0 );
transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
}
.reveal .slide-background-content {
position: absolute;
width: 100%;
height: 100%;
background-position: 50% 50%; background-position: 50% 50%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;
transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
} }
.reveal .slide-background.stack { .reveal .slide-background.stack {

View File

@ -933,14 +933,18 @@
backgroundColor: slide.getAttribute( 'data-background-color' ), backgroundColor: slide.getAttribute( 'data-background-color' ),
backgroundRepeat: slide.getAttribute( 'data-background-repeat' ), backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
backgroundPosition: slide.getAttribute( 'data-background-position' ), backgroundPosition: slide.getAttribute( 'data-background-position' ),
backgroundTransition: slide.getAttribute( 'data-background-transition' ) backgroundTransition: slide.getAttribute( 'data-background-transition' ),
backgroundContentOpacity: slide.getAttribute( 'data-background-content-opacity' )
}; };
// Main slide background element
var element = document.createElement( 'div' ); var element = document.createElement( 'div' );
// Carry over custom classes from the slide to the background
element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' ); element.className = 'slide-background ' + slide.className.replace( /present|past|future/, '' );
// Inner background element that wraps images/videos/iframes
var contentElement = document.createElement( 'div' );
contentElement.className = 'slide-background-content';
if( data.background ) { if( data.background ) {
// Auto-wrap image urls in url(...) // Auto-wrap image urls in url(...)
if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) { if( /^(http|file|\/\/)/gi.test( data.background ) || /\.(svg|png|jpg|jpeg|gif|bmp)([?#\s]|$)/gi.test( data.background ) ) {
@ -963,17 +967,22 @@
data.backgroundColor + data.backgroundColor +
data.backgroundRepeat + data.backgroundRepeat +
data.backgroundPosition + data.backgroundPosition +
data.backgroundTransition ); data.backgroundTransition +
data.backgroundContentOpacity );
} }
// Additional and optional background properties // Additional and optional background properties
if( data.backgroundSize ) element.style.backgroundSize = data.backgroundSize;
if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize ); if( data.backgroundSize ) element.setAttribute( 'data-background-size', data.backgroundSize );
if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor; if( data.backgroundColor ) element.style.backgroundColor = data.backgroundColor;
if( data.backgroundRepeat ) element.style.backgroundRepeat = data.backgroundRepeat;
if( data.backgroundPosition ) element.style.backgroundPosition = data.backgroundPosition;
if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition ); if( data.backgroundTransition ) element.setAttribute( 'data-background-transition', data.backgroundTransition );
// Background image options are set on the content wrapper
if( data.backgroundSize ) contentElement.style.backgroundSize = data.backgroundSize;
if( data.backgroundRepeat ) contentElement.style.backgroundRepeat = data.backgroundRepeat;
if( data.backgroundPosition ) contentElement.style.backgroundPosition = data.backgroundPosition;
if( data.backgroundContentOpacity ) contentElement.style.opacity = data.backgroundContentOpacity;
element.appendChild( contentElement );
container.appendChild( element ); container.appendChild( element );
// If backgrounds are being recreated, clear old classes // If backgrounds are being recreated, clear old classes
@ -981,6 +990,7 @@
slide.classList.remove( 'has-light-background' ); slide.classList.remove( 'has-light-background' );
slide.slideBackgroundElement = element; slide.slideBackgroundElement = element;
slide.slideBackgroundContentElement = contentElement;
// If this slide has a background color, add a class that // If this slide has a background color, add a class that
// signals if it is light or dark. If the slide has no background // signals if it is light or dark. If the slide has no background
@ -3311,10 +3321,12 @@
// Show the corresponding background element // Show the corresponding background element
var background = getSlideBackground( slide ); var background = slide.slideBackgroundElement;
if( background ) { if( background ) {
background.style.display = 'block'; background.style.display = 'block';
var backgroundContent = slide.slideBackgroundContentElement;
// If the background contains media, load it // If the background contains media, load it
if( background.hasAttribute( 'data-loaded' ) === false ) { if( background.hasAttribute( 'data-loaded' ) === false ) {
background.setAttribute( 'data-loaded', 'true' ); background.setAttribute( 'data-loaded', 'true' );
@ -3327,7 +3339,7 @@
// Images // Images
if( backgroundImage ) { if( backgroundImage ) {
background.style.backgroundImage = 'url('+ encodeURI( backgroundImage ) +')'; backgroundContent.style.backgroundImage = 'url('+ encodeURI( backgroundImage ) +')';
} }
// Videos // Videos
else if ( backgroundVideo && !isSpeakerNotes() ) { else if ( backgroundVideo && !isSpeakerNotes() ) {
@ -3355,7 +3367,7 @@
video.innerHTML += '<source src="'+ source +'">'; video.innerHTML += '<source src="'+ source +'">';
} ); } );
background.appendChild( video ); backgroundContent.appendChild( video );
} }
// Iframes // Iframes
else if( backgroundIframe && options.excludeIframes !== true ) { else if( backgroundIframe && options.excludeIframes !== true ) {
@ -3378,7 +3390,7 @@
iframe.style.maxHeight = '100%'; iframe.style.maxHeight = '100%';
iframe.style.maxWidth = '100%'; iframe.style.maxWidth = '100%';
background.appendChild( iframe ); backgroundContent.appendChild( iframe );
} }
} }

View File

@ -130,8 +130,8 @@ Reveal.addEventListener( 'ready', function() {
QUnit.test( 'Reveal.getSlideBackground', function( assert ) { QUnit.test( 'Reveal.getSlideBackground', function( assert ) {
assert.equal( Reveal.getSlideBackground( 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:first-child' ), 'gets correct first background' ); assert.equal( Reveal.getSlideBackground( 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:first-child' ), 'gets correct first background' );
assert.equal( Reveal.getSlideBackground( 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2)' ), 'no v index returns stack' ); assert.equal( Reveal.getSlideBackground( 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2)' ), 'no v index returns stack' );
assert.equal( Reveal.getSlideBackground( 1, 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(1)' ), 'v index 0 returns first vertical child' ); assert.equal( Reveal.getSlideBackground( 1, 0 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(2)' ), 'v index 0 returns first vertical child' );
assert.equal( Reveal.getSlideBackground( 1, 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(2)' ), 'v index 1 returns second vertical child' ); assert.equal( Reveal.getSlideBackground( 1, 1 ), document.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(3)' ), 'v index 1 returns second vertical child' );
assert.strictEqual( Reveal.getSlideBackground( 100 ), undefined, 'undefined when out of horizontal bounds' ); assert.strictEqual( Reveal.getSlideBackground( 100 ), undefined, 'undefined when out of horizontal bounds' );
assert.strictEqual( Reveal.getSlideBackground( 1, 100 ), undefined, 'undefined when out of vertical bounds' ); assert.strictEqual( Reveal.getSlideBackground( 1, 100 ), undefined, 'undefined when out of vertical bounds' );
@ -523,8 +523,8 @@ Reveal.addEventListener( 'ready', function() {
var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' ); var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' );
// check that the images are applied to the background elements // check that the images are applied to the background elements
assert.ok( Reveal.getSlideBackground( 0 ).style.backgroundImage.indexOf( imageSource1 ) !== -1, 'data-background-image worked' ); assert.ok( Reveal.getSlideBackground( 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource1 ) !== -1, 'data-background-image worked' );
assert.ok( Reveal.getSlideBackground( 1, 0 ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' ); assert.ok( Reveal.getSlideBackground( 1, 0 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' );
}); });