簡體   English   中英

如何平滑過渡CSS背景圖像?

[英]How can I smoothly transition CSS background images?

那里的主要解決方案是:

“只需加載一個加載屏幕,直到加載頁面”。

但我的目標是構建能夠非常快速地顯示基礎知識的頁面,而無需加載屏幕,然后在圖像和花哨功能准備好后進行轉換。 所以我會等到它被加載,然后淡入它。或者我將加載一個非常低分辨率的版本,然后在它准備好時淡入高分辨率。

我還沒想到的這種做法的一個方面是如何用背景圖像來做。

如何通過背景圖像實現平滑淡入的效果?

我願意用:

  • 使用Javascript
  • JQuery的
  • 任何現代的JQuery庫
  • CSS技巧/“黑客”

但我想避免:

  • 使用覆蓋元素並在頂部淡化。

正如@dandavis的評論中所指出的,實際上有一個CSS過渡屬性:background-image。

解決方案,利用CSS背景過渡屬性:

  1. 創建兩個相同大小的背景圖像:一個透明,一個是預期的。 (如果你沒有使它們大小相同, 你會得到這種效果! );

  2. 使用transition: background-image 1s來產生過渡效果

  3. 使用Javascript預加載圖像並在准備好后重置背景圖像。 CSS將負責其余部分。

顯着的局限性


工作實例

 var image = new Image(); image.onload = function () { $(".element").css("background-image", "url('" + image.src + "')"); } image.src = "https://c1.staticflickr.com/3/2439/3728897793_ff1c78c5d9.jpg"; //image to be transitioned to 
 html{ width:100%; height:100%; } body{ width:100%; height:100%; padding:0px; margin:0px; } .element{ width:100%; height:100%; background-image:url('http://i.imgur.com/HRV3DsM.jpg'); -webkit-transition: background-image 5s; } 
 <div class="element"> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> 

我想我有一個解決方案! (對不起,剛剛離開我得到了這個工作:)

 //library (minified) this.BgImgFader=function(){var styleRules;function getArray(str){if(str.indexOf(',')==0){str.substring(1);}if(str.lastIndexOf(',')==str.length-1){str.substring(0,str.length-1);}if(str.indexOf(',')==-1){var selectors=[str];}else{var selectors=str.split(',');}for(var i=0;i<selectors.length;i++){selectors[i]=selectors[i].trim();}return selectors;}function getStyleSheet(style){if(typeof style==='number'){return document.styleSheets[style];}else{for(var i=0;i<document.styleSheets.length;i++){var file=document.styleSheets[i].href;file=file.substring(file.lastIndexOf('/')+1);if(file.toLowerCase()==style.toLowerCase()){return document.styleSheets[i];}}}}function addStyleRule(sheet,selector,declarations){if(sheet.addRule){sheet.addRule(selector,declarations);}else{sheet.insertRule(selector+'{'+declarations+'}');}}this.prepare=function(style,selectors){var selectors=getArray(selectors);var styleSheet=getStyleSheet(style);for(var i=0;i<selectors.length;i++){addStyleRule(styleSheet,selectors[i],'position:relative;');addStyleRule(styleSheet,selectors[i]+'::after','position:absolute;top:0;right:0;bottom:0;left:0;opacity:0.0;content:"";');}};this.fade=function(style,selectors,global,opacity,endOpacity,delta){var selectors=getArray(selectors);var styleSheet=getStyleSheet(style);styleRules=styleSheet.rules?styleSheet.rules:styleSheet.cssRules;fadeOpacity(selectors,global,opacity,endOpacity,delta,[]);};function fadeOpacity(selectors,global,opacity,endOpacity,delta,rules){opacity+=delta;if(rules.length==0){for(var i=0;i<selectors.length;i++){for(var j=0;j<styleRules.length;j++){if(global&&styleRules[j].selectorText.toLowerCase().indexOf(selectors[i].toLowerCase()+'::after')!=-1){rules.push(styleRules[j]);}else if(styleRules[j].selectorText.toLowerCase()==selectors[i].toLowerCase()+'::after'){rules.push(styleRules[j]);break;}}}}for(var i=0;i<rules.length;i++){rules[i].style.opacity=opacity;}if(opacity<endOpacity){setTimeout(function(){fadeOpacity(selectors,global,opacity,endOpacity,delta,rules);},0);}else{for(var i=0;i<rules.length;i++){rules[i].style.opacity=endOpacity;}rules.length=0;}}}; //instantiate BgImgFader in global domain var BgImgFader = new BgImgFader(); window.onload = function(){ //prepare specified elements BgImgFader.prepare(0, '.exampleClass'); //style, selectors //fade specified elements BgImgFader.fade(0, '.exampleClass', true, 0, 0.5, 0.002); //style, selectors, global, startOpacity, endOpacity, delta }; 
 #exampleId { width: 300px; height: 200px; margin: 10px 0px 0px 10px; background-color: #AAAAAA; } #exampleId .exampleClass { width: 200px; height: 130px; padding: 5px; } #exampleId .exampleClass::after {background:url(https://placeimg.com/640/480/any) center/cover no-repeat;} 
 <div id="exampleId"> Some other text to illustrate how this can be implemented. <div class="exampleClass"> I assume you want transparent background images because you have text in the element that you do want to show from the start? </div> </div> 
codepen: https ://codepen.io/anon/pen/QMLPbr

我基本上最終建立了一個小型圖書館。 純JavaScript,不需要jQuery。


你要做的就是在JS中添加這三個BgImgFader行:

 //instantiate BgImgFader in global domain var BgImgFader = new BgImgFader(); window.onload = function(){ //prepare specified elements BgImgFader.prepare(0, '.exampleClass'); //stylesheet, selectors //fade specified elements BgImgFader.fade(0, '.exampleClass', true, 0, 0.5, 0.002); //stylesheet, selectors, global, startOpacity, endOpacity, delta }; 

並將以下內容添加到CSS中的所有background-image-elements:

 #example {...} #example::after {background:url(path/to/image.png) center/cover no-repeat;} 

因此,對於具有背景圖像的每個元素,您必須#example::after { rule並將背景圖像放在那里#example::after {添加#example::after { (您不必在HTML中執行此操作,僅在CSS中執行此操作。)


我已經將庫的源代碼添加為下面的代碼片段。 評論在代碼中。
您可以將代碼粘貼到自己腳本的頂部,也可以將代碼放在文件和HTML中,鏈接到該文件,就像您對任何其他庫一樣(在您自己的代碼之前):

 <script type="text/javascript" src="path/to/bgimgfader.js"></script> 

 /** * BgImgFader - Library: * This library makes it possible to fade the background-image of an element. * The image can be faded in or out. * * Compatibility: * - IE9 and higher should be fine, lower could give trouble. * - Older versions of FF/Chrome will probably give some problems too, but I think we can safely assume * that those who chose either one of these browsers, did so because they choose NOT to live in the past.. * - Opera and others... I have absolutely no idea. * * ################################################################################# * INSTRUCTIONS--------------------------------------------------------------------- * 1. In CSS: * a. For every element with a background-image, create an '::after' rule, and put the image in there: * (You don't have to create these '::after'-elements in the HTML) * * #element {...} * #element::after {background:url(path/to/image.png) center/cover no-repeat;} * * The following declarations will be added by the BgImgFader, keep that in mind: * #element {position:relative;} * #element::after {position:absolute; top:0;right:0;bottom:0;left:0; opacity:0.0; content:"";} * * (The important one is 'position:relative;', the ones on the '::after'-element have no consequences) * * --------------------------------------------------------------------------------- * 2. In JavaScript: * a. Instantiate the BgImgFader in the global domain: var BgImgFader = new BgImgFader(); * * * b. Prepare the elements with a background-image: BgImgFader.prepare(0, 'elements'); //style, selectors * * - style: Reference to the style sheet with the rules for the specified elements. * This can be either an INTEGER for internal style sheets (0), * or a STRING of a filename for external style sheets ('style.css'). * - selectors: STRING reference to the selectors in the style rules. * This works the same as in the CSS, below a few examples. * Individual tags: ('div') ('#id') ('.class') * Multiple tags: ('div.class') ('#id .class') ('.class.subclass') * Multiple selectors: ('div, #id, div.class, #id .class, .class.subclass') * * * c. Initiate the fade: BgImgFader.fade('style.css', 'elements', true, 0, 0.5, 0.005); //style, selectors, global, startOpacity, endOpacity, delta * * - style: See 2b for the details. * - selectors: See 2b for the details. * - global: BOOLEAN that deternimes whether only complete matches for the selectors are allowed, * or partial matches as well, increasing the range of the BgImgFader. * TRUE allowes partial matches: feed the BgImgFader '.class' and it will also try to fade 'div .class'. * FALSE allowes only complete matches. * - startOpacity: FLOAT that indicates the start opacity (0.0 - 1.0). * - endOpacity: FLOAT that indicates the end opacity (0.0 - 1.0). * - delta: FLOAT that indicates the delta of every fade-iteration (1.0 - 0.00000000...1). * The effective range is approximately (0.1 - 0.0001). * A smaller delta means a slower fade. * A positive delta in combination with start<end fades the image in. * A negative delta in combination with start>end fades the image out. * * ################################################################################# */ this.BgImgFader = function() { var styleRules; //GET/SET-FUNCTIONS================================================================= //GET SELECTORS--------------------------------------------------------------------- function getArray(str) { /* This function is invoked by this.prepare() and this.fade(). * This function converts the specified string of selectors to an array, and returns that. */ //strip trailing comma's if (str.indexOf(',')==0) {str.substring(1);} //strip first comma if (str.lastIndexOf(',')==str.length-1) {str.substring(0,str.length-1);} //strip last comma //store selectors in array if (str.indexOf(',')==-1) {var selectors = [str];} else {var selectors = str.split(',');} //trim trailing spaces for (var i=0; i<selectors.length; i++) { selectors[i] = selectors[i].trim(); } return selectors; } //GET STYLE SHEET------------------------------------------------------------------- function getStyleSheet(style) { /* This function is invoked by this.prepare() and this.fade(). * This function returns a reference to the specified style sheet, * based on either a number or a filename of the sheet. * A number is for internal sheets, where the number stands * for its location in the HTML (eg the first '<style></style>'). * A filename is for external sheets (eg 'style.css'). * See the instructions in the header of this file for details. */ if (typeof style === 'number') { return document.styleSheets[style]; } else { //find style sheet for (var i=0; i<document.styleSheets.length; i++) { var file = document.styleSheets[i].href; file = file.substring(file.lastIndexOf('/')+1); if (file.toLowerCase() == style.toLowerCase()) { return document.styleSheets[i]; } } } } //SET STYLE RULE-------------------------------------------------------------------- function addStyleRule(sheet, selector, declarations) { /* This function is invoked by this.prepare(). * This function dynamically adds the specified rule to the specified style sheet. */ if (sheet.addRule) {sheet.addRule(selector,declarations);} //IE... else {sheet.insertRule(selector+'{'+declarations+'}');} //NON-IE... } //PREPARE=========================================================================== this.prepare = function(style, selectors) { /* This function is invoked by an external function, outside of the library. * This function is an interface for external scripts to access this library. * The function prepares the elements specified by the selectors, by adding certain style rules * to them that are necessary for this library to successfully manipulate the background-image. */ var selectors = getArray(selectors); var styleSheet = getStyleSheet(style); for (var i=0; i<selectors.length; i++) { addStyleRule(styleSheet,selectors[i],'position:relative;'); addStyleRule(styleSheet,selectors[i]+'::after','position:absolute; top:0;right:0;bottom:0;left:0; opacity:0.0; content:"";'); } }; //FADE BACKGROUND IMAGE============================================================= //INIT------------------------------------------------------------------------------ this.fade = function(style, selectors, global, opacity, endOpacity, delta) { /* This function is invoked by an external function, outside of the library. * This function is an interface for external scripts to access this library. * The function initiates the fading process. It first stores the appropriate * set of style rules into the style rules variable, and then invokes * fadeOpacity() to start the fading. */ var selectors = getArray(selectors); var styleSheet = getStyleSheet(style); styleRules = styleSheet.rules ? styleSheet.rules : styleSheet.cssRules; //IE uses 'rules', NON-IE use 'cssRules' fadeOpacity(selectors,global,opacity,endOpacity,delta,[]); }; //FADE------------------------------------------------------------------------------ function fadeOpacity(selectors, global, opacity, endOpacity, delta, rules) { /* This function is invoked by fade(). * This function fades the background-image of the specified elements, by * adding the delta to the current opacity, and then setting the opacity * of all specified elements to that new value. */ opacity += delta; if (rules.length == 0) { //find the css-rules that match the specified selector(s) for (var i=0; i<selectors.length; i++) { for (var j=0; j<styleRules.length; j++) { if (global && styleRules[j].selectorText.toLowerCase().indexOf(selectors[i].toLowerCase()+'::after')!=-1) { rules.push(styleRules[j]); } else if (styleRules[j].selectorText.toLowerCase() == selectors[i].toLowerCase()+'::after') { rules.push(styleRules[j]); break; } } } } //set the opacity of the background-image for every matched rule for (var i=0; i<rules.length; i++) { rules[i].style.opacity = opacity; } //check if the end-opacity is reached if (opacity < endOpacity) { setTimeout(function(){fadeOpacity(selectors,global,opacity,endOpacity,delta,rules);},0); //invoke itself again } else { //manually set the opacity to the end-opacity (otherwise it'll be off by a fraction) for (var i=0; i<rules.length; i++) { rules[i].style.opacity = endOpacity; } rules.length = 0; } } }; 
 source code of library, not a working code snippet! 
(庫的源代碼,不是工作代碼片段)

有趣的事實:這在jsfiddle.net不起作用 ,因為它們自己的樣式表與小提琴中的樣式表混合在一起,使得無法確定所需的CSS規則所在的表(基於數字)。

不清楚你是否已經解決了這個問題:對於常規<img>圖像,將另一個<img>置於其上方(顯示:內聯塊;可見性:隱藏;)並且監聽高分辨率圖像的onload將起作用:

$("high-res").load(function() {
    $(this).css({visibility: "hidden", opacity: 0}).fadeIn("slow");
}

編輯:反過來(將高分辨率放在低分辨率后,然后淡出低分辨率)也有效。 但你不會繞過覆蓋的東西。

CSS背景圖像的淡入是不可能的。 它們沒有不透明度值。 你唯一能做的就是將內容放在<img>上方的<img> <div> ,並以同樣的方式淡化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM