JS

写一个H5签到金币掉落动画

2018-09-04  本文已影响932人  辣瓜瓜
效果gif

最近项目上写了一个签到页面,其中有一个功能设计的是点击签到,有一个金币坠落的效果,现在总结记录一下:

需求

  1. 中间已签到的金色圆球需要倾斜掉落,然轻微反弹后竖直显示。
  2. 四周的小金币不能同时掉落在屏幕上,需要有先后次序。
  3. 当小金币和金色圆球完全出现在屏幕后需等待500毫秒。
  4. 金色圆球逐渐放大并变淡。
  5. 小金币此时竖直下落,速度逐渐加快。

实现步骤

如果要实现此效果,至少需要两组动画衔接在一起。
第一组动画是金币掉落,金色圆球倾斜反弹出现在页面上;第二组是金色圆球逐渐放大并变淡金币,金币加速掉落。

具体代码

第1步:HTML布局

<div class="signin" id="signin">
    <div class="coin animated ">
        <img id="bg" class="bg animated " src="../../images/v3/coin.png">
        <img class="texts animated " src="../../images/v3/hasdone@2x.png">
    </div>
</div>

第2步:CSS布局代码
确定小金币和金色大圆球掉落的最终位置

.signin{display:none;position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;overflow:hidden}
.coin{width:4.12rem;height:4.12rem;font-size:30px;margin-left:calc((100% - 4.12rem) / 2);margin-top:calc((9.22rem / 2) - 1.5rem);position:relative}
.coin .bg{float:left;width:4.12rem;height:4.12rem}
.coin .texts{position:absolute;top:1.7rem;left:1.11rem;width:1.9rem;height:.72rem}
.coin1{width:.68rem;height:.5rem;position:absolute;top:.3rem;right:0;animation-delay:0.3s}
.coin2{width:.33rem;height:.43rem;position:absolute;top:.5rem;left:3.7rem;animation-delay:0.25s}
.coin3{width:.67rem;height:.8rem;position:absolute;top:3.3rem;left:.9rem;animation-delay:0.2s}
.coin4{width:.75rem;height:.55rem;position:absolute;top:3.7rem;right:1.3rem;animation-delay:0.15s}
.coin5{width:.83rem;height:.59rem;position:absolute;top:6.8rem;right:1.1rem;animation-delay:0.1s}
.coin6{width:.8rem;height:.74rem;position:absolute;top:8rem;right:.3rem;animation-delay:0.05s}
.coin7{width:2.12rem;height:1.9rem;position:absolute;top:8.7rem;left:1.2rem;animation-delay:0.05s}

第3步:CSS动画代码

金色大圆球从高处下落

.animated {
    -webkit-animation-duration: 1s;
    animation-duration: 1s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
    -webkit-animation-iteration-count: 1;
    animation-iteration-count: 1;
}

@keyframes bounceInDown {
    from,
    60%,
    75%,
    90%,
    to {
        -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
        animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    }
    0% {
        -webkit-transform: translate3d(0, -3000px, 0);
        transform: translate3d(0, -3000px, 0);
    }
    60% {
        -webkit-transform: translate3d(0, 25px, 0);
        transform: translate3d(0, 25px, 0);
    }
    75% {
        -webkit-transform: translate3d(0, -10px, 0);
        transform: translate3d(0, -10px, 0);
    }
    90% {
        -webkit-transform: translate3d(0, 5px, 0);
        transform: translate3d(0, 5px, 0);
    }
    to {
        -webkit-transform: translate3d(0, 0, 0);
        transform: translate3d(0, 0, 0);
    }
}

.bounceInDown {
    -webkit-animation-name: bounceInDown;
    animation-name: bounceInDown;
    -webkit-animation-duration: 0.8s;
    animation-duration: 0.8s;
}

金色大圆球旋转30度

@keyframes rotateInDownRight {
    from {
        opacity: 0;
        transform: rotate(60deg);
    }
    60% {
        opacity: 1;
        transform: rotate(60deg);
    }
    to {
        transform: rotate(0);
    }
}

.rotateInDownRight {
    -webkit-animation-name: rotateInDownRight;
    animation-name: rotateInDownRight;
    -webkit-animation-duration: 0.8s;
    animation-duration: 0.8s;
}

已签到文本动画

@keyframes rotateInDownRighttext {
    from {
        opacity: 0;
        transform: rotate(60deg) scale(1.2);
    }
    75% {
        opacity: 1;
        transform: rotate(60deg) scale(1);
    }
    to {
        transform: rotate(0) scale(1);
    }
}

.rotateInDownRighttext {
    -webkit-animation-name: rotateInDownRighttext;
    animation-name: rotateInDownRighttext;
    -webkit-animation-duration: 0.8s;
    animation-duration: 0.8s;
}

放大然后消失

@keyframes bigVanish {
    from {
        opacity: 1;
        transform: scale(1);
    }
    to {
        opacity: 0;
        transform: scale(3);
    }
}

.bigVanish {
    -webkit-animation-name: bigVanish;
    animation-name: bigVanish;
    -webkit-animation-duration: 0.4s;
    animation-duration: 0.4s;
    animation-delay: 1s;
}


6枚金币掉落

@keyframes coinDown {
    from {
        -webkit-transform: translate3d(0, -3000px, 0);
        transform: translate3d(0, -3000px, 0);
    }
    to {
        -webkit-transform: translate3d(0, 0, 0);
        transform: translate3d(0, 0, 0);
    }
}
@keyframes goDown {
    from {
        -webkit-transform: translate3d(0, 0, 0);
        transform: translate3d(0, 0, 0);
    }
    to {
        -webkit-transform: translate3d(0, 1000px, 0);
        transform: translate3d(0, 1000px, 0);
    }
}
.signin>img{
    -webkit-animation-name: coinDown;
    animation-name: coinDown;
    -webkit-animation-duration: 0.8s;
    animation-duration: 0.8s;
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
}
.signin>img.goDown{
    -webkit-animation-name: goDown;
    animation-name: goDown;
    -webkit-animation-duration: 1s;
    animation-duration: 1s;
    animation-delay: 1s;
}

第4步:Javascript

增加clss、判断是否拥有claa

function hasClass(elem, cls) {
    cls = cls || '';
    if(cls.replace(/\s/g, '').length == 0) return false; //当cls没有参数时,返回false
    return new RegExp(' ' + cls + ' ').test(' ' + elem.className + ' ');
}

function addClass(elem, cls) {
    if(!hasClass(elem, cls)) {
        elem.className = elem.className == '' ? cls : elem.className + ' ' + cls;
    }
}

获取基本信息

var container = document.getElementById('signin');
var btn = document.getElementById('btn');
var coinBg = document.getElementsByClassName("bg")[0];
var texts = document.getElementsByClassName("texts")[0];
var coinImgs = document.getElementsByClassName("coins");
var coin = document.getElementsByClassName("coin")[0];

/*定义小金币基本信息 */
var coinPosition = [
    [0.3, 0],
    [0.5, 3.5],
    [3.3, 6],
    [3.7, 1.3],
    [6.8, 1.1],
    [8, 0.3],
    [8.7, 4.2]
];
var coinSize = [
    [0.68, 0.5],
    [0.33, 0.43],
    [0.67, 0.8],
    [0.75, 0.55],
    [0.83, 0.59],
    [0.8, 0.74],
    [2.12, 1.9]
];

动画事件触发的监听

btn.addEventListener('click', function() {
    addClass(coin, "bounceInDown")
    addClass(coinBg, "rotateInDownRight")
    addClass(texts, "rotateInDownRighttext")
    container.style.display="block"
    init()

}, false);

开始金币动画掉落

function init() {
    try {
        for(var i = 0; i < 7; i++) {
            container.appendChild(createALeaf(i));
        }
        second();
    } catch(e) {
        console.log("error")
    }

}

function createALeaf(i) {
    var image = document.createElement('img');
    image.src = '../../images/v3/coin' + (i + 1) + '.png';
    image.className = 'coins animated';
    image.style.width = coinSize[i][0] + "rem";
    image.style.height = coinSize[i][1] + "rem";
    image.style.top = coinPosition[i][0] + "rem";
    image.style.right = coinPosition[i][1] + "rem";
    image.style.webkitAnimationName = "coinDown";
    image.style.animationName = "coinDown";
    // 随机delay时间
    var leafDelay = 0.05 * (7 - i);
    image.style.webkitAnimationDelay = leafDelay + "s";
    image.style.animationDelay = leafDelay + "s";
    return image;
}

设置监听,当第一组动画执行完毕后执行下面的代码

//第二部分金币掉落和已签到放大
function second() {
    //最后一枚金币出现在屏幕的动画结束时触发
    coinImgs[0].addEventListener("webkitAnimationEnd", function(e) {
        //console.log("动画执行完毕");
        if(hasClass(coinImgs[0], "goDown")) {
            console.log("下一步");
        }
        addClass(texts, "bigVanish")
        addClass(coinBg, "bigVanish")
        Array.from(coinImgs).forEach((item, index) => {
            coinImgs[index].style.animationName = '';
            coinImgs[index].style.animationDelay = '';
            addClass(coinImgs[index], "goDown")
        });
    }, false);
}

完整代码

上一篇 下一篇

猜你喜欢

热点阅读