jQuery+CSS3搞一个动画简历

栏目: jQuery · 发布时间: 7年前

内容简介:又到了一年一度躁动不安的季节,跳槽升职加薪当然需要一份很nice的简历啦,作为一位在本圈刚出道的前端小白,当然需要一份很nice的简历啦!

在线预览(移动端慎入)

github

又到了一年一度躁动不安的季节,跳槽升职加薪当然需要一份很nice的简历啦,作为一位在本圈刚出道的前端小白,当然需要一份很nice的简历啦!

图片展示

设计粗糙,原谅一个理科生(理科都还没学好)的审美

介绍页

jQuery+CSS3搞一个动画简历

技能清单页

jQuery+CSS3搞一个动画简历

经历页

jQuery+CSS3搞一个动画简历

作品页

jQuery+CSS3搞一个动画简历

联系方式页

jQuery+CSS3搞一个动画简历

核心动画延迟函数

js文件目录

│  jqExt.js // 扩展一些jq插件
│  main.js // 主函数
│  pageFirst.js // 第一屏动画
│  pageSecond.js // 第二屏动画
│  pageThird.js // 第三屏动画
│  pageFourth.js // 第四屏动画
|  pageFifth.js // 第五屏动画
│  startAni.js // 页面初始化动画
│  utils.js // 工具函数
复制代码

核心延迟函数

网站一共分为五屏,每翻到一屏都会执行当前页面的动画,由于动画为延迟逐个进行的方式,一开始非常简单粗暴的使用setTimeout嵌套,酱紫:

setTimeout(() => {
    /* 需要执行的动画内容 */
    setTimeout(() => {
        /* 需要执行的动画内容 */
        setTimeout(() => {
            /* 需要执行的动画内容 */
        }, delay);
    }, delay);    
}, delay);
复制代码

臭名远扬的回调函数,其实我是没问题的,可是咱得考虑到开源呀,这整出去不是打自个脸吗,所以自个封装了一个非常简易还有点low的延迟库,酱紫:

class Timeout {
    constructor() {
        this.timer = null; // 定时器
        this.fns = []; // 存储所有运动函数
        this.index = 0; // 索引
    }
    to(fn = () => { }, time = 0) {
        // 存储所有执行函数以及对应的延迟时间
        this.fns.push({
            fn,
            time
        });
        return this;
    }
    start() {
        const _this = this;
        /* 通过索引判断当前动画是否执行完毕,不需要继续执行 */
        if (_this.index === _this.fns.length) return;
        // 清除定时器
        _this.pause();
        _this.timer = setTimeout(() => {
            //执行当前阶段函数
            requestAnimationFrame(_this.fns[_this.index].fn);
            // 索引+1
            _this.index++;
            if (_this.index === _this.fns.length) _this.pause();
            else _this.start();
            // 时间递增
        }, _this.fns[_this.index].time);
    }
    // 暂停
    pause() {
        clearTimeout(this.timer);
    }
};
复制代码

调用方式如下:

const t = new Timeout();
t.to(() => {
    /* 动画函数 */
}, delay)
.to(() => {
    /* 动画函数 */
}, delay)
......
// 执行当前动画组
t.start();
复制代码

这就好多了

每个屏最终都会导出当前屏动画的 开始暂停 开关

module.exports = {
    start() {
        t.start();
        /* 当前屏其他动画开始函数 */
    },
    pause() {
        t.pause();
        /* 当前屏其他动画暂停函数 */
    }
};
复制代码

当页面滚动到当前屏,执行start开始方法,离开之后执行pause暂停,尤其是需要canvas和setInterval的屏,暂停能节约性能开销呢

首屏随机行驶的小车原理

预览

jQuery+CSS3搞一个动画简历

首先准备若干量小车div,蜷缩在屏幕外边随时准备待命,开一个定时器,随机抓出一辆小车放生

共有三个要素决定小车的运动形式(行驶方向、上下位置、运动速度)

行驶方向

车从左到右行驶 或 从右到左行驶

.car {
    // 小车向右边行驶
    &.left {
        animation-name: moveL;
        @keyframes moveL {
            0% {
                transform: translateX(-300px) rotateY(0);
            } 100% {
                transform: translateX(140vw) rotateY(0);
            }
        }
    }

    // 小车向左边行驶
    &.right {
        animation-name: moveR;
        @keyframes moveR {
            0% {
                transform: translateX(140vw) rotateY(180deg);
            } 100% {
                transform: translateX(-300px) rotateY(180deg);
            }
        }
    }
    
    // 鼠标移动到小车上停止
    &:hover {
        animation-play-state: paused;
    }
 }
复制代码

上下位置

枚举出所有小车可能出现的最佳位置,方便js随机动态生成class

.car {
    /* 枚举出左右车道小车位置,方便js随机动态生成class */
    // 左车道
    &.bl1 {
        bottom: 91%;
        z-index: 8;
    }
    &.bl2 {
        bottom: 92%;
        z-index: 7;
    }
    // ......
    
    // 右车道
    &.br1 {
        bottom: 71%;
        z-index: 18;
    }

    &.br2 {
        bottom: 72%;
        z-index: 17;
    }
    // ......
}
复制代码

行驶时间

.car {
    // 时间
    &.t1 {
        animation-duration: 1s;
    }

    &.t2 {
        animation-duration: 2s;
    }
    // ......
}
复制代码

核心js代码如下:

// 需要用到的运动类
const moveStyle = {
    dir: ['left', 'right'],
    time: ['t1', 't2', 't3', 't4', 't5', 't6', 't7', 't8'],
    pos: [['bl1', 'bl2', 'bl3', 'bl4', 'bl5', 'bl6', 'bl7', 'bl8'], ['br1', 'br2', 'br3', 'br4', 'br5', 'br6', 'br7', 'br8']]
}
const move = () => {
    /* moveArr为需要运动的小车集合 */
    /* 随机取出一辆小车 len为小车个数 */
    moveObj = moveArr[Math.floor(Math.random() * len)];
    // 选出一辆不处于运动状态的小车
    while (moveObj.prop('isAnimated')) {
        moveObj = moveArr[Math.floor(Math.random() * len)];
    };
    // 将即将运动的小车的加上运动标识
    moveObj.prop('isAnimated', true);
    /* 这里来一个55开,决定当前小车行驶方向 */
    const dirNum = Math.round(Math.random()); // 0或1
    // 生成运动类名
    const className = `${moveStyle.dir[dirNum]} ${moveStyle.time[Math.ceil(Math.random() * 8)]} ${moveStyle.pos[dirNum][Math.ceil(Math.random() * 7)]}`;
    // 给小车加上class,并将类名存储到自定义数据中,方便后期清空
    moveObj.addClass(className).prop('csName', className);
    // 每隔四秒走一次
    timer = setTimeout(() => {
        requestAnimationFrame(move);
    }, 4000);
}
复制代码

当然,我们需要监听当前小车车是否运动完毕,以此来取消它的运动状态,所以需要搞一个监听:

// 当animate完成,会触发当前事件
car.bind("animationEnd webkitAnimationEnd", animateComplete);
function animateComplete() {
    // 清空刚刚随机生成的class运动类,并且将当前的运动状态设置为false
    $(this).removeClass($(this).prop('csName')).prop('isAnimated', false);
};
复制代码

ok,差不多完成了,但是还有一个很重要的性能问题,假如浏览者离开了当前屏幕,我们就需要清空当前小车的运动定时器,最终我们依然导出了一个start(开始)和pause(暂停)函数

return {
    // 小车开始运动
    start: move,
    pause() {
        // 清除小车的定时器
        clearTimeout(timer);
        // 遍历所有小车,清空他们的运动状态
        cars.each(moveEl => {
            // 把运动中的车全部清除
            if ($(moveEl).prop('isAnimated')) $(moveEl).removeClass($(moveEl).prop('csName')).prop('isAnimated', false);
        });
    }
};
// 然后放到对应的页面中去
// 比如首屏最终的导出函数就成了酱紫:
module.exports = {
    start() {
    	t.start();
        /* 小车开始 */
    	carAniFn.start();
    },
    pause() {
    	t.pause();
    	/* 离开当前屏,小车暂停 */
    	carAniFn.pause();
    }
};
复制代码

页面切换效果

所有页面都包装在一个div里面,通过切换css类名来实现上下运动,css如下

/* vh是css3的一个相对单位,100vh相当于浏览器可视区域的高度 */
#swiper-box {
    .ts(.4s linear);
    &.page0 {
        .tf(translateY(0));
    }

    &.page1 {
        .tf(translateY(-100vh));
    }

    &.page2 {
        .tf(translateY(-200vh));
    }

    &.page3 {
        .tf(translateY(-300vh));
    }

    &.page4 {
        .tf(translateY(-400vh));
    }
}
复制代码

监听鼠标滚轮,在这里需要注意下chrome和firefox滚动方向需要做一下兼容:

/* 扩展jq函数 */
$.fn.extend({
    onscroll(fn) {
        let dir = null;
        let gg, ff;
        $(this).bind('mousewheel || DOMMouseScroll', function (e) {
            gg = e.originalEvent.wheelDelta;
            ff = e.originalEvent.detail;
            dir = gg ? (gg < 0 ? true : false) : (ff < 0 ? false : true);
            fn && fn(dir, e);
        });
        return $(this);
    }
});
复制代码

给需要滚动的父级元素加上鼠标滚轮事件

swiperBox.onscroll(function (dir) {
   /**/
    if (dir) index++;
    else index--;
    // 判断index是否超出范围,len为屏幕个数
    if (index >= len) index = 0;
    if (index < 0) index = len - 1;
    if (index === prev) return;
    // 暂停上一屏的动画
    arr[prev].pause();
    // 3d导航切换效果
    navA.eq(prev).removeClass('hover');
    navA.eq(index).addClass('hover');
    // 给父级加上已经写好的class类名
    swiperBox[0].className = 'page' + index;
});
复制代码

当滚动到当前屏之后,需要执行当前屏的动画,在这里我们监听父级页面是否运动完成,运动完成之后就按需加载当前页面对应的动画:

/* 将对应的页面存储到数组当中,用于判断是否已经require过 */
const partArr = [];
swiperBox.bind('transitionend webkitTransitionend', function (e) {
    /* 考虑到子元素会重复触发当前事件,判断下子 */
    if (e.target === this) {
        if (!partArr[index]) partArr[index] = requirePart(index); // 如果没有导入,进行导入
        prev = index; // 记录上一屏
        partArr[index].start(); // 执行当前屏的动画
    }
});
// 用于导入各个页面的函数
function requirePart(index) {
    switch (index) {
        case 0:
            return require('./pageFirst');
        case 1:
            return require('./pageSecond');
        case 2:
            return require('./pageThird');
        case 3:
            return require('./pageFourth');
        case 4:
            return require('./pageFifth');
    }
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming PHP

Programming PHP

Rasmus Lerdorf、Kevin Tatroe、Peter MacIntyre / O'Reilly Media / 2006-5-5 / USD 39.99

Programming PHP, 2nd Edition, is the authoritative guide to PHP 5 and is filled with the unique knowledge of the creator of PHP (Rasmus Lerdorf) and other PHP experts. When it comes to creating websit......一起来看看 《Programming PHP》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具