day17

day17缓冲动画

1.平滑运动

  • 需求:点击起飞 盒子开始移动 移动到1000px 盒子停止

<body>
    <button>起飞</button>
    <div></div>
    <script>
        /* 
            需求:点击起飞按钮  红色盒子开始移动  移动到1000px的位置开始停止
        */
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        //添加点击事件
        btn.onclick = function () {
           var timer =  setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left")) + 10;
                if(current==1000){
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + "px";
            }, 50)
​
        }
    </script>

2.缓冲动画基础功能

  • 需求:目标值是500和目标值是1000 所花费的时间是一样的

<body>
    <button>起飞</button>
    <div></div>
    <script>
        /* 
            需求:目标值是500和目标值是1000 所花费的时间是一样的
            速速 = 路程 / 时间
        */
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        //添加点击事件
        btn.onclick = function () {
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left"));
                var speed = (500 - current) / 10;// speed  速度/步长
                console.log(current);//永远达不到目标值
                if (current == 500) {
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + speed + "px";
            }, 50)
​
        }
    </script>
  • 问题1:永远到不了目标值

    • 原因:当current是491的时候 speed=0.9 left值=parseInt(491.9px) =491 所以current的值始终在491

    • 解决方法:让speed向上取整 Math.ceil

<body>
    <button>起飞</button>
    <div></div>
    <p></p>
    <script>
        /* 
             问题1:永远达不到目标值
             原因:当current是491的时候 speed=0.9 left值=parseInt(491.9px) =491 所以current的值始终在491
             解决方法:让speed向上取整  Math.ceil
        */
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        //添加点击事件
        btn.onclick = function () {
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left"));
                var speed = (500 - current) / 10; // speed  速度/步长
                speed = Math.ceil(speed);
                console.log(speed);
                if (current == 500) {
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + speed + "px";
            }, 50)
​
        }
    </script>
</body>

3缓冲动画来回运动

  • 需求:从left值是1000的位置 缓冲到500的位置

  • 问题2:往回运动的时候 永远无法达到目标值

    • 分析:current是509的时候 speed的值是-0.9 Math.ceil之后就成了-0 speed的值最终是0 left值还是509 导致目标值永远都是509

    • 解决:让speed向下取整 Math.floor

<body>
    <button>起飞</button>
    <div></div>
    <p></p>
    <script>
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        /* 
            问题2:往回运动的时候  永远无法达到目标值
            分析:current是509的时候  speed的值是-0.9 Math.ceil之后就成了-0 speed的值最终是0   left值还是509 导致目标值永远都是509
            解决:让speed向下取整  Math.floor
        */
        //添加点击事件
        btn.onclick = function () {
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left"));
                var speed = (500 - current) / 10; // speed  速度/步长
                speed = Math.floor(speed);
                console.log(current);
                if (current == 500) {
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + speed + "px";
            }, 50)
​
        }
    </script>
</body>
​
  • 来回运动speed值的问题

    • 0-500 speed的值正数 Math.ceil

    • 1000-500 speed的值是负数 Math.floor

<body>
    <button>起飞</button>
    <div></div>
    <p></p>
    <script>
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        /* 
           speed值的问题
             0-500  speed的值正数   Math.ceil
             1000-500 speed的值是负数  Math.floor
        */
        //添加点击事件
        btn.onclick = function () {
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(oDiv, "left"));
                var speed = (500 - current) / 10; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == 500) {
                    // 清除定时器
                    clearInterval(timer)
                }
                oDiv.style.left = current + speed + "px";
            }, 50)
​
        }
    </script>
</body>

4.来回运动函数封装

<body>
    <button>起飞</button>
    <div></div>
    <p></p>
    <script>
        var btn = document.getElementsByTagName("button")[0];
        var oDiv = document.getElementsByTagName("div")[0]
        /* 
           speed值的问题
             0-500  speed的值正数   Math.ceil
             1000-500 speed的值是负数  Math.floor
        */
        //添加点击事件
        btn.onclick = function () {
​
            buffMove(oDiv, "left", 500, 20);
        }
​
        function buffMove(elem, attr, target, time) {
            /* elem 缓冲的元素 attr 需要缓冲的样式  target是目标值 time是缓冲时间 */
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(elem, attr));
                var speed = (target - current) / time; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == target) {
                    // 清除定时器
                    clearInterval(timer)
                }
                elem.style[attr] = current + speed + "px";
            }, 50)
        }
    </script>
</body>

5.透明度缓冲

  • 问题3:缓冲透明度从1到0 没有缓冲动画

    • 分析:current是1的时候 speed的值-0.1 用Math.floor取整之后变成-1 opacity的值是0

    • 解决:是因为透明度的值太小了 将透明度的值放大n倍 放大100倍

<body>
    <div></div>
    <script>
        /* 
            问题3:缓冲透明度从1到0 没有缓冲动画
            分析:current是1的时候 speed的值-0.1 用Math.floor取整之后变成-1 opacity的值是0   
            解决:是因为透明度的值太小了  将透明度的值放大n倍 放大100倍
        */
        var oDiv = document.getElementsByTagName("div")[0];
        oDiv.onclick = function () {
            // 更改透明度  1-0
            buffMove(oDiv, "opacity", 0.2, 10)
        }
​
        function buffMove(elem, attr, target, time) {
            /* elem 缓冲的元素 attr 需要缓冲的样式  target是目标值 time是缓冲时间 */
            target = target * 100
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                var current = parseInt(getStyle(elem, attr) * 100);
                var speed = (target - current) / time; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == target) {
                    // 清除定时器
                    clearInterval(timer)
                }
                // 其他属性
                // elem.style[attr] = current + speed + "px";
                // 透明度opacity
                elem.style[attr] = (current + speed) / 100;
            }, 50)
        }
    </script>
</body>

6.缓冲任意属性

<body>
    <div></div>
    <script>
        var oDiv = document.getElementsByTagName("div")[0];
        oDiv.onclick = function () {
            // buffMove(oDiv,"width",500,10)
            buffMove(oDiv,"opacity",0.2,10)
        }
        function buffMove(elem, attr, target, time) {
        /* elem 缓冲的元素 attr 需要缓冲的样式  target是目标值 time是缓冲时间 */
            var timer = setInterval(function () {
                //在当前left值的基础上+10
                if (attr == 'opacity') { // 透明度属性
                    var current = parseInt(getStyle(elem, attr) * 100);
                    // opacity target的取值范围是0-1  才需要*100   其他属性大于1 不需要*100
                    target = target > 1 ? target : target * 100
                } else {//其他属性
                    var current = parseInt(getStyle(elem, attr));
                }
                var speed = (target - current) / time; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == target) {
                    // 清除定时器
                    clearInterval(timer)
                }
                if (attr == "opacity") {
                    // 透明度opacity
                    elem.style[attr] = (current + speed) / 100;
                } else {
                    // 其他属性
                    elem.style[attr] = current + speed + "px";
                }
            }, 50)
        }
    </script>
</body>

7.抽屉式运动

  • 问题1:在移入事件的缓冲动画没有完成之前就移除 会造成盒子抽搐

    • 分析:是因为定时器累计的问题

    • 解决:在定义一个新的定时器之前就清除原先的定时器 确保只有一个定时器

  • 问题2:同时运动多个盒子 盒子无法达到目标值

    • 分析:多个盒子都是调用buffMove函数 一进入这个函数就将之前的定时器清除掉了 共用了一个定时器的缘故

    • 解决:给每个盒子都单独定义一个timer,将每个盒子的定时器id都存储到元素的自定义属性timer上

<body>
    <div>1</div>
    <div>2</div>
    <script>
        var oDiv = document.getElementsByTagName("div");
        oDiv[0].onmouseover = function(){
                // 200px-500px
                buffMove(oDiv[0],"width",500,10)
        }
        oDiv[0].onmouseout = function(){
               // 500px-200px
               buffMove(oDiv[0],"width",200,10)
​
        }
        oDiv[1].onmouseover = function(){
             //200-500px;
             buffMove(oDiv[1],"width",500,10)
        }
        oDiv[1].onmouseout = function(){
             //500px-200px
            buffMove(oDiv[1],"width",200,10)
​
        }
        // var timer;
        function buffMove(elem, attr, target, time) {
            /* elem 缓冲的元素 attr 需要缓冲的样式  target是目标值 time是缓冲时间 */
            clearInterval(elem.timer);
            //将每个盒子的定时器id都存储到元素的自定义属性timer上
            elem.timer = setInterval(function () { 
                //在当前left值的基础上+10
                if (attr == 'opacity') { // 透明度属性
                    var current = parseInt(getStyle(elem, attr) * 100);
                    // opacity target的取值范围是0-1  才需要*100   其他属性大于1 不需要*100
                    target = target > 1 ? target : target * 100
                } else {//其他属性
                    var current = parseInt(getStyle(elem, attr));
                }
                var speed = (target - current) / time; // speed  速度/步长
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                console.log(current);
                if (current == target) {
                    // 清除定时器
                    clearInterval(elem.timer)
                }
                if (attr == "opacity") {
                    // 透明度opacity
                    elem.style[attr] = (current + speed) / 100;
                } else {
                    // 其他属性
                    elem.style[attr] = current + speed + "px";
                }
            }, 50)
        }
    </script>
</body>

8.多属性运动

  • 问题1:运动多个属性的时候,无法多次调用buffMove函数,因为后者会覆盖前者

    • 解决:buffMove只能调用一次 可以每次传值的时候一个对象,对象存储格式为{"width":500,"height":500} {"样式名":目标值}

    <script>
        var oDiv = document.getElementsByTagName("div")[0];
        oDiv.onclick = function () {
            // 想同时运动多个属性 buffMove只能调用一次 可以每次传值的时候传多个 参数{"width":500,"height":500}
            buffMove(oDiv, { "width": 500, "height": 500 }, 10)
        }
        //需求:同时运动width和height
        function buffMove(elem, attrObj, time) {
            /* elem 缓冲的元素 attrObj同时运动属性的对象{样式名:目标值}*/
            clearInterval(elem.timer);
            elem.timer = setInterval(function () {
                 // name变量中存储的是width height 也就是要缓冲的样式
                 // 目标值attrObj[name]   原先的目标值target需要替换成attrObj[name]
                for (var name in attrObj) {
                    //在当前left值的基础上+10
                    if (name == "opacity") {
                        // name是opacity
                        var current = parseInt(getStyle(elem, name) * 100);
                        // target的值是0-1 更改的是透明度,透明度需要*100   target>1 其他属性的值 不需要*100
                        attrObj[name] = attrObj[name] > 1 ? attrObj[name] : attrObj[name] * 100  //
                    } else {
                        // name是其他属性
                        var current = parseInt(getStyle(elem, name));
                    }
                    var speed = (attrObj[name] - current) / time; // speed  速度/步长
                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                    console.log(current);
                    if (current == attrObj[name]) {
                        // 清除定时器
                        clearInterval(elem.timer)
                    }
                    if (name == "opacity") {
                        // 透明度opacity
                        elem.style[name] = (current + speed) / 100;
                    } else {
                        // 其他属性
                        elem.style[name] = current + speed + "px";
                    }
                }
            }, 50)
        }
    </script>
  • 问题2:如果多个属性的目标值不一致,个别属性无法到达目标点

    • 分析:如果某一个属性达到目标值 就会进到if(current==attrObj[name]) 就会清除定时器 导致剩余属性无法继续执行

    • 解决:

    1.假设所有属性都达到目标点再去清除定时器 var tag = true

    2.验证你假设的情况 一个一个属性的去验证

    3.验证之后你会得到一个结论 你的假设要么成立 要么不成立 如果成立清除定时器

<body>
    <div></div>
    <script>
        /* 
             问题1:如果多个属性目标值不一致的话  个别属性无法达到目标点
             分析:如果某一个属性达到目标值 就会进到if(current==attrObj[name]) 就会清除定时器 导致剩余属性无法继续执行
             解决:
                 1.假设所有属性都达到目标点再去清除定时器  var tag = true  
                 2.验证你假设的情况  一个一个属性的去验证
                 3.验证之后你会得到一个结论  你的假设要么成立  要么不成立   如果成立清除定时器
        
        */
        var oDiv = document.getElementsByTagName("div")[0];
        oDiv.onclick = function () {
            
            buffMove(oDiv, { "width": 1, "height": 1000 }, 10)
        }
   
        function buffMove(elem, attrObj, time) {
            /* elem 缓冲的元素 attrObj同时运动属性的对象{样式名:目标值}*/
            clearInterval(elem.timer);
            elem.timer = setInterval(function () {
                var tag = true;// 初始值定义为true  假设所有的属性都达到了目标点
                for (var name in attrObj) {
                    //在当前left值的基础上+10
                    if (name == "opacity") {
                        // name是opacity
                        var current = parseInt(getStyle(elem, name) * 100);
                        // target的值是0-1 更改的是透明度,透明度需要*100   target>1 其他属性的值 不需要*100
                        attrObj[name] = attrObj[name] > 1 ? attrObj[name] : attrObj[name] * 100  //
                    } else {
                        // name是其他属性
                        var current = parseInt(getStyle(elem, name));
                    }
                    var speed = (attrObj[name] - current) / time; // speed  速度/步长
                    speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                    
                    //2.去验证假设的情况
                    if(current!=attrObj[name]){
                        tag = false
                    }
                   
                    if (name == "opacity") {
                        // 透明度opacity
                        elem.style[name] = (current + speed) / 100;
                    } else {
                        // 其他属性
                        elem.style[name] = current + speed + "px";
                    }
                }
                // 3.判断结论是否成立
                if(tag){
                    clearInterval(elem.timer)
                }
            }, 50)
        }
    </script>
</body>
Day17 中,我们可以通过 Flask 框架快速搭建一个 BBS 论坛。具体步骤如下: 1. 创建 Flask 应用 ```python from flask import Flask app = Flask(__name__) ``` 2. 创建数据库 ```python from flask_sqlalchemy import SQLAlchemy app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///bbs.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) ``` 3. 创建数据库模型 ```python class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, nullable=False) password = db.Column(db.String(20), nullable=False) class Post(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100), nullable=False) content = db.Column(db.Text, nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) ``` 4. 创建路由和视图函数 ```python @app.route('/') def index(): posts = Post.query.all() return render_template('index.html', posts=posts) @app.route('/post/<int:post_id>') def post(post_id): post = Post.query.get(post_id) return render_template('post.html', post=post) @app.route('/new_post', methods=['GET', 'POST']) def new_post(): if request.method == 'POST': title = request.form['title'] content = request.form['content'] user_id = 1 # 假设当前用户为 id 为 1 的用户 post = Post(title=title, content=content, user_id=user_id) db.session.add(post) db.session.commit() return redirect('/') return render_template('new_post.html') @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] user = User.query.filter_by(username=username, password=password).first() if user: session['user_id'] = user.id return redirect('/') else: flash('用户名或密码错误') return render_template('login.html') @app.route('/logout') def logout(): session.pop('user_id', None) return redirect('/') ``` 5. 创建 HTML 模板 创建 index.html、post.html、new_post.html、login.html 四个模板文件,并且使用 jinja2 模板引擎渲染数据。 6. 运行应用 ```python if __name__ == '__main__': app.run() ``` 以上就是快速搭建 BBS 论坛的主要步骤,当然在实际应用中还需要考虑更多细节问题,比如用户认证、数据校验、页面美化等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值