2017-02-19 29 views
1

Я пытаюсь динамически добавлять transform: translate3d для перемещения div, но в конце преобразования div возвращается в исходное положение. Я добавляю новую таблицу стилей и использую insertRule(). Любые идеи, что может быть причиной этого?Динамическое добавление преобразования - возвращается к исходному значению в конце

Вот a fiddle:

slideshow = (function() { 
    function slideshow() { 
    var _this = this; 
    this.divMiddle; 
    this.divLarge = []; // holds full sized image 
    this.largeSize = []; 
    this.slide = -1; 
    this.oldSlide = -1; 
    this.img = []; 

    this.divMiddle = document.createElement("div"); 
    this.divMiddle.id = "divMiddle"; 
    this.divMiddle.style.position = "relative" 
    this.divMiddle.style.width = "500px"; 
    this.divMiddle.style.height = "400px"; 
    this.divMiddle.style.border = "1px solid black"; 
    document.body.appendChild(this.divMiddle); 
    document.getElementById("next").addEventListener("click", function() { 
     _this.transitionSlides(1) 
    }); 
    document.getElementById("prev").addEventListener("click", function() { 
     _this.transitionSlides(-1) 
    }); 

    this.oldSlide = -1; 
    this.slide = -1; 
    this.transitionSlides(1); 
    } 

    // transition between slides - fading new one in and old one out 
    slideshow.prototype.transitionSlides = function(direction) { 
    // if not the first one loaded, will do transition 
    var begin, end; 
    this.oldSlide = this.slide; 
    this.slide += direction; 
    if (this.slide > this.oldSlide) { 
     this.createImage(); 
    } 
    if (CSSRule.KEYFRAMES_RULE) { 
     var prefix = "" 
    } else if (CSSRule.WEBKIT_KEYFRAMES_RULE) { 
     var prefix = "-webkit-" 
    } 
    var style = document.createElement("style"); 
    document.head.appendChild(style); 

    // fade out the old slide 
    if (this.oldSlide >= 0) { 
     // fade(this.divLarge[this.oldSlide], 1, .1, 20);  
     this.divLarge[this.oldSlide].style.opacity = ".3"; 

     var oldMargin = (parseInt(this.divMiddle.style.width) - parseInt(this.largeSize[this.oldSlide].displayWidth))/2; 
     begin = 0; 
     if (direction == 1) { 
     // next 
     // move existing slide from left to right 
     end = (parseInt(this.largeSize[this.oldSlide].displayWidth) + oldMargin); 
     } else { 
     // prev 
     // move existing slide from right to left 
     end = -(parseInt(this.largeSize[this.oldSlide].displayWidth) + oldMargin + 1); 
     } 
     var rule = "@" + prefix + "keyframes moveOld {" + 
     "0% {" + prefix + "transform: translate3d(" + begin + "px, 0, 0); }" + 
     "100% {" + prefix + "transform: translate3d(" + end + "px, 0, 0); }" + 
     "}"; 
     style.sheet.insertRule(rule, 0); 

     var rule2 = "#" + this.divLarge[this.oldSlide].id + "{" + prefix + "animation: moveOld 3s linear" + "}"; 
     style.sheet.insertRule(rule2, 0); 

    } 
    // fade in the new slide 
    //fade(this.divLarge[this.slide], .1, 1, 20); 
    this.divLarge[this.slide].style.opacity = "1"; 
    this.divLarge[this.slide].style.display = "block"; 

    var margin = (parseInt(this.divMiddle.style.width) - parseInt(this.largeSize[this.slide].displayWidth))/2; 
    begin = 0; 
    if (this.oldSlide == -1) { 
     // first slide - don't move 
     this.divLarge[this.slide].style.left = margin + "px"; 
     end = 0; 
    } else if (direction == 1) { 
     // next 
     // move new slide from left to right 
     // move to starting position 
     this.divLarge[this.slide].style.left = (oldMargin - parseInt(this.largeSize[this.slide].displayWidth)) + "px"; 
     end = (-oldMargin + parseInt(this.largeSize[this.slide].displayWidth) + margin); 
    } else { 
     // prev 
     // move new slide from right to left 
     // move to starting position 
     this.divLarge[this.slide].style.left = (oldMargin + parseInt(this.largeSize[this.oldSlide].displayWidth)) + "px"; 
     end = +oldMargin - (parseInt(this.largeSize[this.slide].displayWidth) + margin); 
    } 
    var rule = "@" + prefix + "keyframes moveNew {" + 
     "0% {" + prefix + "transform: translate3d(" + begin + "px, 0, 0); }" + 
     "100% {" + prefix + "transform: translate3d(" + end + "px, 0, 0); }" + 
     "}"; 
    style.sheet.insertRule(rule, 0); 

    var rule2 = "#" + this.divLarge[this.slide].id + "{" + prefix + "animation: moveNew 2s linear" + "}"; 
    style.sheet.insertRule(rule2, 0); 
    } 

    slideshow.prototype.createImage = function() { 
    var img = document.createElement("img"); 
    var from = 100; 
    var to = 300; 
    var width = Math.floor(Math.random() * (to - from + 1) + from); 
    var height = Math.floor(Math.random() * (to - from + 1) + from); 
    img.src = "http://placehold.it/" + width + "x" + height; 
    img.style.height = height; 
    img.style.width = width; 
    this.img.push(img); 

    var div = document.createElement("div"); 
    div.id = "slideshow-large-" + (this.img.length - 1) 
    div.style.display = "none"; 
    div.style.top = ((parseInt(this.divMiddle.style.height) - height)/2) + "px"; 
    div.style.position = "absolute"; 
    div.style.width = width + "px"; 
    div.className = "slideshow-large"; 
    div.appendChild(img); 

    this.divLarge.push(div); 
    this.largeSize.push({ 
     displayWidth: width, 
     displayHeight: height 
    }); 
    this.divMiddle.appendChild(div); 
    } 

    return slideshow; 

})(); 

var ss = new slideshow(); 

стили и HTML

<div id="next">Next Slide</div> 
<div id="prev">Prev Slide</div> 


#divMiddle { 
    width: 600px; 
    height: 600px; 
    display: flex; 
    position: relative; 
    top: 0px; 
    left: 0px; 
    overflow: hidden; 
} 

div.slideshow-large { 
    overflow: hidden; 
    top: 0; 
    position: absolute; 
} 

div.slideshow-large img { 
    display: block; 
} 

div.slideshow-large span { 
    position: absolute; 
    top: 0; 
    left: 0; 
    z-index: 1070; 
} 
+0

Может ли создать минимальный фрагмент кода с проблемой? Теперь он слишком велик, я могу только предложить вам прочитать об [свойстве-анимации-режиме] (https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode). –

+1

@SergeyDenisov - Вы ударяете ноготь по голове. И я немного в недоумении, что я не опубликовал очень простой пример, как вы отметили (было поздно ...). Я новичок в анимации (очевидно), и в любом из примеров я никогда не сталкивался с анимацией-заполнением-режимом. Такая базовая настройка, которая, по вашему мнению, будет включена. Благодаря! – mseifert

+0

Помог ли вам 'animation-fill-mode'? –

ответ

0

Вы должны добавить animation-fill-mode: forwards в свой код, он будет держать анимацию в конечной стоимости. Для вашего примера кода это будет примерно так:

... 
var rule2 = "#" + this.divLarge[this.slide].id + "{" + prefix + "animation: moveNew 2s linear forwards" + "}"; 
... 
+0

@mseifert вы могли бы также поддержать ответ. –