美文网首页
基本网页特效(二)

基本网页特效(二)

作者: OmewSPG | 来源:发表于2021-10-27 09:35 被阅读0次

动画

动画原理

动画原理.png
        // 动画原理
        // 1. 获得盒子当前位置  
        // 2. 让盒子在当前位置加上1个移动距离
        // 3. 利用定时器不断重复这个操作
        // 4. 加一个结束定时器的条件
        // 5. 注意此元素需要添加定位, 才能使用element.style.left
        var div = document.querySelector('div');
        var btn = document.querySelector('button');

        btn.addEventListener("click", function () {
            var timer = setInterval(function () {
                if (div.offsetLeft > 400) {
                    clearInterval(timer);
                }
                div.style.left = div.offsetLeft + 1 + 'px';
            }, 10);
        })

动画函数封装

        // 给对象添加属性的方法
        // var obj = {};
        // obj.name = 'andy';

        // 动画函数封装
        // 用添加对象属性的方式,给不同对象添加不同属性的定时器,节省内存空间
        function animate(obj, target, step){
            // 另外,在调用函数之前先清楚掉原来的定时器,以免多次点击按钮之后定时器累加造成动画加速
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                if (obj.offsetLeft > target) {
                    clearInterval(obj.timer);
                }
                obj.style.left = obj.offsetLeft + step + 'px';
            }, 10);
        }


        var box1 = document.querySelector('.box1');
        var box2 = document.querySelector('.box2');
        var box3 = document.querySelector('.box3');
        var btn = document.querySelector('button');

        // 调用函数

        btn.addEventListener("click", function () {
            animate(box1, 400, 1);
            animate(box2, 500, 3);
            animate(box3, 600, 5);
        })

缓动动画

缓动动画原理

缓动动画原理.png
        // 缓动动画原理:
        // 1. 让盒子每次移动的距离慢慢变小, 速度就会慢慢落下来。
        // 2. 核心算法:(目标值 - 现在的位置) / 10 做为每次移动的距离 步长
        // 3. 停止的条件是: 让当前盒子位置等于目标位置就停止定时器
        function animate(obj, target, speed){
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                // 缓动动画需要写在定时器里面
                var step = (target - obj.offsetLeft) / speed;
                if (obj.offsetLeft > target) {
                    clearInterval(obj.timer);
                }
                obj.style.left = obj.offsetLeft + step + 'px';
            }, 10);
        }

        var box1 = document.querySelector('.box1');
        var box2 = document.querySelector('.box2');
        var box3 = document.querySelector('.box3');
        var btn = document.querySelector('button');

        // 调用函数

        btn.addEventListener("click", function () {
            animate(box1, 400, 10);
            animate(box2, 500, 20);
            animate(box3, 600, 40);
        })

缓动动画在多个目标点之间的移动

        // 缓动动画在多个目标点之间的移动:
        function animate(obj, target, speed){
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                // 缓动动画需要写在定时器里面
                // JavaScript中需要避免出现小数,否则会导致移动距离出现偏差
                var step = (target - obj.offsetLeft) / speed;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                if (obj.offsetLeft == target) {
                    clearInterval(obj.timer);
                }
                obj.style.left = obj.offsetLeft + step + 'px';
            }, 20);
        }

        var box1 = document.querySelector('.box1');
        var btn = document.querySelector('button');
        var flag = true;

        // 调用函数

        btn.addEventListener("click", function () {
            if(flag){
                animate(box1, 610, 10);
                flag = false;
            }else{
                animate(box1, 10, 10);
                flag = true;
            }
        })

点击animate按钮,图片会在指定位置来回移动

添加回调函数

回调函数作为参数传进动画函数当中,会在动画效果结束后执行:

        // 缓动动画添加回调函数:
        function animate(obj, target, callback){
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                // 缓动动画需要写在定时器里面
                // JavaScript中需要避免出现小数,否则会导致移动距离出现偏差
                var step = (target - obj.offsetLeft) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                if (obj.offsetLeft == target) {
                    clearInterval(obj.timer);
                    // 回调函数写在清除定时器的判断条件里
                    if(callback){
                        callback();
                    }
                }
                obj.style.left = obj.offsetLeft + step + 'px';
            }, 20);
        }

        var box1 = document.querySelector('.box1');
        var btn = document.querySelector('button');
        var flag = true;

        // 调用函数

        btn.addEventListener("click", function () {
            if(flag){
                animate(box1, 610, function(){
                    box1.style.backgroundImage = "url('pic/Megumin.jpg')";
                });
                flag = false;
            }else{
                animate(box1, 10, function(){
                    box1.style.backgroundImage = "url('pic/Kana.jpg')";
                });
                flag = true;
            }
        })

上面的例子,缓动动画效果结束后会更改盒子内的图片

JS封装

// 缓动动画添加回调函数:
function animate(obj, target, callback) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        // 缓动动画需要写在定时器里面
        // JavaScript中需要避免出现小数,否则会导致移动距离出现偏差
        var step = (target - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (obj.offsetLeft == target) {
            clearInterval(obj.timer);
            // 回调函数写在清除定时器的判断条件里
            /* if (callback) {
                callback();
            } */
            // 使用逻辑中断来代替判断语句
            callback&&callback();
        }
        obj.style.left = obj.offsetLeft + step + 'px';
    }, 20);
}

在使用的时候,别忘了在头文件里引用该js文件:

    <script src='animate.js'></script>

轮播图效果

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

    <style>
        /*清除元素默认的内外边距  */
        * {
            margin: 0;
            padding: 0;
        }



        a {
            text-decoration: none;
        }

        .main {
            width: 610px;
            margin: 0 auto;
            margin-top: 60px;
        }

        .focus {
            position: relative;
            width: 600px;
            height: 300px;
            border: red 2px solid;

            overflow: hidden;
        }

        img {
            width: 600px;
        }

        li {
            list-style: none;
        }

        ul {
            position: absolute;
            top: 0;
            left: 0;
            width: 600%;
        }

        ul li {
            float: left;
        }

        .arrow-l,
        .arrow-r {
            display: none;
            position: absolute;
            top: 50%;
            margin-top: -20px;
            width: 24px;
            height: 40px;
            background: rgba(0, 0, 0, .3);
            text-align: center;
            line-height: 40px;
            color: #fff;
            font-family: 'icomoon';
            font-size: 18px;
            z-index: 2;
        }

        .arrow-r {
            right: 0;
        }

        .circle {
            position: absolute;
            bottom: 10px;
            left: 50px;
        }

        .circle li {
            float: left;
            width: 8px;
            height: 8px;
            /*background-color: #fff;*/
            border: 2px solid rgba(255, 255, 255, 0.5);
            margin: 0 3px;
            border-radius: 50%;
            /*鼠标经过显示小手*/
            cursor: pointer;
        }

        .current {
            background-color: #fff;
        }
    </style>
    <script src='animate.js'></script>

</head>

<body>
    <div class="main">
        <div class="focus">
            <!-- 左侧按钮 -->
            <a href="javascript:;" class="arrow-l">←</a>
            <!-- 右侧按钮 -->
            <a href="javascript:;" class="arrow-r">→</a>
            <!-- 核心的滚动区域 -->
            <ul>
                <li>
                    <a href="#"><img
                            src="https://patchwiki.biligame.com/images/blhx/8/87/1axukjehcwyowqeh8f4xobkbvjyija7.jpg"
                            alt=""></a>
                </li>
                <li>
                    <a href="#"><img
                            src="https://patchwiki.biligame.com/images/blhx/5/5d/aqs86t38ezjjwl1qjlgz9lylsdcojle.jpg"
                            alt=""></a>
                </li>
                <li>
                    <a href="#"><img
                            src="https://patchwiki.biligame.com/images/blhx/6/66/ntqh7jf5f4ce20qopr5192qxgadbw2x.jpg"
                            alt=""></a>
                </li>
                <li>
                    <a href="#"><img
                            src="https://patchwiki.biligame.com/images/blhx/f/f4/izxkrqb9iey4ooqws4dimq8r0yttx7b.jpg"
                            alt=""></a>
                </li>
                <li>
                    <a href="#"><img
                            src="https://patchwiki.biligame.com/images/blhx/3/33/0kz6xpi03oisfing6l3w4547hag1kpr.jpg"
                            alt=""></a>
                </li>
            </ul>
            <!-- 小圆圈 -->
            <ol class="circle">
            </ol>
        </div>
    </div>

    <script>
        // 网页轮播图
        // 需求:
        // 1. 鼠标经过轮播图模块,左右按钮显示,离开即隐藏两个按钮
        // 2. 点击右侧按钮一次,图片往左播放一次,反之则向右播放一张
        // 3. 图片播放时,下面的小圆点跟随一起变化
        // 4. 点击小圆点,可以播放对应的图片
        // 5. 鼠标不经过轮播图模块,会自动播放图片
        // 6. 鼠标经过时,自动播放停止

        // 获取元素
        var box = document.querySelector('.focus');
        var arrow_l = document.querySelector('.arrow-l');
        var arrow_r = document.querySelector('.arrow-r');

        var pic = document.querySelector('img');
        var ul = document.querySelector('ul');
        var ol = document.querySelector('.circle');

        var num = 0;
        var dot = 0;
        var flag = true;   // 节流阀

        // 显示/隐藏箭头
        box.addEventListener('mouseenter', function () {
            arrow_l.style.display = 'block'
            arrow_r.style.display = 'block'
            clearInterval(timer);
            timer = null;    // 清楚定时器变量
        });

        box.addEventListener('mouseleave', function () {
            arrow_l.style.display = 'none'
            arrow_r.style.display = 'none'
            timer = setInterval(function () {
                arrow_r.click();
            }, 2000);
        });

        // 动态生成小圆圈
        // console.log(pic.length);
        for (var i = 0; i < ul.children.length; i++) {
            var li = document.createElement('li');
            li.setAttribute('index', i);
            ol.append(li);

            // 小圆圈的排他算法
            li.addEventListener('click', function () {
                for (var j = 0; j < ol.children.length; j++) {
                    ol.children[j].className = '';
                }
                this.className = 'current';

                // 对应图片跳转
                var index = this.getAttribute('index');
                // console.log(index);
                animate(ul, -index * pic.clientWidth);

                num = index;
                dot = index;
            })

        }
        ol.children[0].className = 'current';

        /*     ol.addEventListener('click',function(e){
                   for(var i = 0; i < ul.children.length; i++){
                       ol.children[i].className = '';
                   }
                   e.target.className = 'current';
                   console.log(e.target);
               }) */

        // 这里虽然想到用事件委托,虽然点击圆点也能实现相应效果
        // 但是如果不小心点到圆点之间的间隔,e.target会判定是ol,所有小圆点都会消失

        // 将第一张图片复制到最后面,利用视觉差来做出循环效果
        // 因为克隆是在小圆点生成之后,所以不会影响小圆点的总数量
        var firstPic = ul.children[0].cloneNode(true);    // 完全克隆
        ul.appendChild(firstPic);

        // 点击箭头跳转图片
        arrow_r.addEventListener('click', function () {
            if (flag) {
                flag = false;   // 关闭节流阀
                // 图片无缝滚动
                if (num == ul.children.length - 1) {
                    ul.style.left = 0;
                    num = 0;
                }
                num++;
                animate(ul, -num * pic.clientWidth, function () {
                    flag = true;    // 打开节流阀
                });

                dot++;
                if (dot == ol.children.length) {
                    dot = 0;
                }
                circleChange();
            }
        });


        arrow_l.addEventListener('click', function () {
            if (flag) {
                flag = false;
                if (num == 0) {
                    num = ul.children.length - 1;
                    ul.style.left = -num * pic.clientWidth + 'px';
                }

                num--;
                animate(ul, -num * pic.clientWidth, function(){
                    flag = true;
                });

                dot--;
                dot = dot < 0 ? ol.children.length - 1 : dot;
                circleChange();
            }
        });

        // 更改圆点位置
        function circleChange() {
            for (var i = 0; i < ol.children.length; i++) {
                ol.children[i].className = '';
            }
            ol.children[dot].className = 'current';
        };


        // 自动轮播功能
        var timer = setInterval(function () {
            // 手动调用事件
            arrow_r.click();
        }, 2000);
    </script>
</body>
</html>

说明一下什么是节流阀:


节流阀.png

返回顶部动画

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <style>
        .slide-bar {
            position: absolute;
            left: 50%;
            top: 300px;
            margin-left: 600px;
            width: 45px;
            height: 130px;
            background-color: pink;
        }

        .w {
            width: 1200px;
            margin: 10px auto;
        }

        .header {
            height: 150px;
            background-color: purple;
        }

        .banner {
            height: 250px;
            background-color: skyblue;
        }

        .main {
            height: 1000px;
            background-color: yellowgreen;
        }

        span {
            display: none;
            position: absolute;
            bottom: 0;
        }

        .goBack {
            display: none;
        }
    </style>
</head>

<body>
    <div class="slide-bar">
        <a class="goBack">Top</a>
    </div>
    <div class="header w">Header</div>
    <div class="banner w">Bannner</div>
    <div class="main w">Main</div>

    <script>
        // 仿淘宝侧边固定栏
        var slide_bar = document.querySelector('.slide-bar');
        var banner = document.querySelector('.banner');

        var bannerTop = banner.offsetTop;
        var slideBarTop = slide_bar.offsetTop - bannerTop;

        var main = document.querySelector('.main');
        var btn = document.querySelector('.goBack');
        var mainTop = main.offsetTop;

        // 页面滚动事件
        document.addEventListener('scroll', function () {
            // window.pageYOffset 页面被卷去的头部
            console.log(window.pageYOffset);
            // 当页面卷到banner栏时,固定slideBar在页面的显示位置,
            if (window.pageYOffset >= bannerTop) {
                slide_bar.style.position = 'fixed'
                slide_bar.style.top = slideBarTop + 'px';
            } else {
                slide_bar.style.position = 'absolute';
                slide_bar.style.top = '300px';
            }

            // 当页面卷到main盒子时,显示top模块
            if (window.pageYOffset >= mainTop) {
                btn.style.display = 'block';
            } else {
                btn.style.display = 'none';
            }
        });

        slide_bar.addEventListener('click',function(){
            animate(window, 0);
        })


        // 缓动动画添加回调函数:
        function animate(obj, target, callback) {
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                // 缓动动画需要写在定时器里面
                // JavaScript中需要避免出现小数,否则会导致移动距离出现偏差
                var step = (target - window.pageYOffset) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                if (window.pageYOffset == target) {
                    clearInterval(obj.timer);
                    // 回调函数写在清除定时器的判断条件里
                    /* if (callback) {
                        callback();
                    } */
                    // 使用逻辑中断来代替判断语句
                    callback && callback();
                }
                // obj.style.left = obj.offsetLeft + step + 'px';
                window.scroll(0, window.pageYOffset + step);
            }, 20);
        }
    </script>
</body>
</html>

其实只需要把动画的目标地点从水平更改为垂直就行了

相关文章

  • 基本网页特效(二)

    动画 动画原理 动画函数封装 缓动动画 缓动动画原理 缓动动画在多个目标点之间的移动 点击animate按钮,图片...

  • 2017-3-14 JS学习笔记

    document 获取网页基本结构 document 可以把一些东西写在网页中 写入网页的基本结构 星海特效的一些...

  • 基本网页特效(一)

    offset系列 offset概述 offset与style的区别 演示 HTML: CSS: 元素偏移offse...

  • 前端基本功--js实战1 9.24

    一、js作用1.网页特效2.网页交互3.表单验证总之就是控制结构和样式。二、js基本语句都是属于内置对象,内置对象...

  • 第八节 特效、选择器、过滤器

    1、特效 网页显示: 2 、基本选择器 3、层级选择器 网页显示: 4、筛选器 网页显示: 5、筛选器(conta...

  • 网页特效

    元素偏移量offset系列 动态获取元素的偏移 获取元素距离带有定位父元素的位置 获取元素的自身大小 返回的数值都...

  • 网站推荐 (不定时更新)

    1.网页设计 jQuery插件库:JS特效,网页特效,以及各种html5,css3动画和效果Bootstrap,来...

  • 文斌跟着李南江学习HTML5—CSS学习

    经过一个星期的学习,让我们了解了网页的基本结构搭建,但是在网上搜索别人的网页都是五彩缤纷,各种特效,这时老师...

  • 常见网页特效

    1.下拉框联动 下拉框联动效果用于在两个或多个内容相关联的下拉框中选取数据,比如在招聘网站中选择求职意向时,需要先...

  • 网页切换特效

    目前网页没有使用任何特效,直接浏览器访问并不觉得难看,不过 App 首页也是用 WebView 加载网页,载入之前...

网友评论

      本文标题:基本网页特效(二)

      本文链接:https://www.haomeiwen.com/subject/raryaltx.html