瀏覽代碼

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

Hakim El Hattab 6 年之前
父節點
當前提交
4ba0d73345
共有 5 個文件被更改,包括 57 次插入31 次删除
  1. 14 12
      README.md
  2. 7 2
      css/reveal.css
  3. 9 2
      css/reveal.scss
  4. 23 11
      js/reveal.js
  5. 4 4
      test/test.js

+ 14 - 12
README.md

@@ -624,12 +624,13 @@ All CSS color formats are supported, like rgba() or hsl().
 #### Image Backgrounds
 By default, background images are resized to cover the full page. Available options:
 
-| Attribute                    | Default    | Description |
-| :--------------------------- | :--------- | :---------- |
-| 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-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. |
+| Attribute                        | Default    | Description |
+| :------------------------------- | :--------- | :---------- |
+| 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-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-content-opacity  | 1          | Opacity of the background image on a 0-1 scale. 0 is transparent and 1 is fully opaque. |
 ```html
 <section data-background-image="http://example.com/image.png">
 	<h2>Image</h2>
@@ -642,12 +643,13 @@ By default, background images are resized to cover the full page. Available opti
 #### Video Backgrounds
 Automatically plays a full size video behind the slide.
 
-| Attribute                    | Default | Description |
-| :--------------------------- | :------ | :---------- |
-| data-background-video        |         | A single video source, or a comma separated list of video sources. |
-| 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-size         | cover   | Use `cover` for full screen and some cropping or `contain` for letterboxing. |
+| Attribute                        | Default | Description |
+| :---------------------------     | :------ | :---------- |
+| data-background-video            |         | A single video source, or a comma separated list of video sources. |
+| 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-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
 <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>

+ 7 - 2
css/reveal.css

@@ -1015,10 +1015,15 @@ body {
   visibility: hidden;
   overflow: hidden;
   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-repeat: no-repeat;
-  background-size: cover;
-  transition: all 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+  background-size: cover; }
 
 .reveal .slide-background.stack {
   display: block; }

+ 9 - 2
css/reveal.scss

@@ -1091,11 +1091,18 @@ $controlsArrowAngleActive: 36deg;
 		overflow: hidden;
 
 		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-repeat: no-repeat;
 		background-size: cover;
-
-		transition: all 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
 	}
 
 	.reveal .slide-background.stack {

+ 23 - 11
js/reveal.js

@@ -933,14 +933,18 @@
 			backgroundColor: slide.getAttribute( 'data-background-color' ),
 			backgroundRepeat: slide.getAttribute( 'data-background-repeat' ),
 			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' );
-
-		// Carry over custom classes from the slide to the background
 		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 ) {
 			// Auto-wrap image urls in url(...)
 			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.backgroundRepeat +
 															data.backgroundPosition +
-															data.backgroundTransition );
+															data.backgroundTransition +
+															data.backgroundContentOpacity );
 		}
 
 		// 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.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 );
 
+		// 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 );
 
 		// If backgrounds are being recreated, clear old classes
@@ -981,6 +990,7 @@
 		slide.classList.remove( 'has-light-background' );
 
 		slide.slideBackgroundElement = element;
+		slide.slideBackgroundContentElement = contentElement;
 
 		// If this slide has a background color, add a class that
 		// signals if it is light or dark. If the slide has no background
@@ -3311,10 +3321,12 @@
 
 
 		// Show the corresponding background element
-		var background = getSlideBackground( slide );
+		var background = slide.slideBackgroundElement;
 		if( background ) {
 			background.style.display = 'block';
 
+			var backgroundContent = slide.slideBackgroundContentElement;
+
 			// If the background contains media, load it
 			if( background.hasAttribute( 'data-loaded' ) === false ) {
 				background.setAttribute( 'data-loaded', 'true' );
@@ -3327,7 +3339,7 @@
 
 				// Images
 				if( backgroundImage ) {
-					background.style.backgroundImage = 'url('+ encodeURI( backgroundImage ) +')';
+					backgroundContent.style.backgroundImage = 'url('+ encodeURI( backgroundImage ) +')';
 				}
 				// Videos
 				else if ( backgroundVideo && !isSpeakerNotes() ) {
@@ -3355,7 +3367,7 @@
 						video.innerHTML += '<source src="'+ source +'">';
 					} );
 
-					background.appendChild( video );
+					backgroundContent.appendChild( video );
 				}
 				// Iframes
 				else if( backgroundIframe && options.excludeIframes !== true ) {
@@ -3378,7 +3390,7 @@
 					iframe.style.maxHeight = '100%';
 					iframe.style.maxWidth = '100%';
 
-					background.appendChild( iframe );
+					backgroundContent.appendChild( iframe );
 				}
 			}
 

+ 4 - 4
test/test.js

@@ -130,8 +130,8 @@ Reveal.addEventListener( 'ready', function() {
 	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( 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, 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, 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(3)' ), 'v index 1 returns second vertical child' );
 
 		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' );
@@ -523,8 +523,8 @@ Reveal.addEventListener( 'ready', function() {
 		var imageSource2 = Reveal.getSlide( 1, 0 ).getAttribute( 'data-background' );
 
 		// 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( 1, 0 ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background 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 ).querySelector( '.slide-background-content' ).style.backgroundImage.indexOf( imageSource2 ) !== -1, 'data-background worked' );
 	});