読者です 読者をやめる 読者になる 読者になる

みかづきブログ その3

3ヶ月つづけてみました。

JavaScriptにCSSアニメーションの終了を伝える方法を考える

kimizuka.hatenablog.com

kimizuka.hatenablog.com

kimizuka.hatenablog.com



最近、CSSアニメーションの終了をJSに伝える手法をもろもろ試し、これからは transitionend をつかおうと心に決めたのですが、これまでは transitionend のことを信頼してなかったので下記のような方法を考案し、つかってました。

  1. アニメーションさせる要素は .data-sec という子要素を持つ
  2. SCSSをつかい、.data-sec の zoom には transition-duration と同じ値を入れる
  3. アニメーションさせる要素に .anim というクラスが振られた際にアニメーションがスタートする
  4. JS側は .data-sec の zoom を取得し transition-duration の値を知る

JavaScript

(function(win, doc, ns) {
    
    "use strict";
    
    function Sprite(id) {
        var that = this;
        
        _init();
        
        function _init() {           
            that.duration = 0;
            that.$elm     = $("#" + id);
            that.$sec     = $("<div>");
            
            that.$sec.addClass("data-sec").css({
                display: "none",
                width: 0,
                height: 0
            });
            
            that.$elm.append(that.$sec);
        }
    }
    
    Sprite.CONST = {
        START_KLASS : "anim"
    };
    
    Sprite.EVENT = {
        ANIM_END : "animend"
    };
    
    Sprite.prototype.start = function() {
        var that = this,
            dfd  = new ns.Util.Deferred(),
            zoom;
        
        that.$elm.addClass(Sprite.CONST.START_KLASS);
        
        if (!that.duration) {
            zoom = that.$sec.css("zoom");
            if (/\%/.test(zoom)) {
                that.duration = parseFloat(that.$sec.css("zoom"), 10) * 10;
            } else {
                that.duration = parseFloat(that.$sec.css("zoom"), 10) * 1000;
            }
        }
        
        setTimeout(function() {
            var param = {
                duration : that.duration
            };
            
            dfd.resolve(param);
        }, that.duration);
        
        return dfd;
    };
    
    Sprite.prototype.reset = function() {
        var that = this;
        
        that.$elm.removeClass(Sprite.CONST.START_KLASS);
    };
    
    ns.Sprite = Sprite;
    
})(this, document, App);

SCSS

@mixin sprite($duration) {
    transition-duration: #{$duration}s;

    .data-sec {
        zoom: $duration;
    }
}

.sprite {
    $duration: .5;
    
    @include sprite($duration);
}

body {
    background: #e3e3e3;
}

.box {
    position: absolute;
    top: 0; bottom: 0;
    left: 0; right: 0;
    margin: auto;
    border-radius: 20px;
    width: 120px; height: 120px;
    background: #3e3e3e;
    box-shadow: 0 0 2px rgba(0, 0, 0, .2);
    transition-property: all;
    transition-timing-function: ease-in-out;
    
    &.anim {
        width: 200px; height: 200px;
    }
}

DEMO



【追記】jQueryをつかえばもっと単純な話でした。kimizuka.hatenablog.com