zoukankan      html  css  js  c++  java
  • 动画框架基础部分

    滚动到顶部:requestAnimationFrame

    function goTop(ms){
    	var originTop=document.body.scrollTop;
    	var translatYPS=originTop*16.7/ms;
    	var count=0;
    	console.log(translatYPS)
    	requestAnimationFrame(function frameFn(){	
    		console.log(count++)
    		var currentTop=document.body.scrollTop;
    // 		console.log(currentTop)
    		if(currentTop>0){
    			document.body.scrollTop=currentTop-translatYPS;
    			requestAnimationFrame(frameFn)
            }		
    	})
    }
    
    
    goTop(1000)
    

    滚动到顶部:定时器

    function goTop(ms){
    
    	var originTop=document.body.scrollTop;
    	var translatYPS=originTop*1000/60/ms;
    	var count=0;
    	console.log(translatYPS)
    	var timer=setInterval(()=>{	
    
    		
    		var currentTop=document.body.scrollTop;
    
    		if(currentTop>0){
    			console.log(count++)
    			document.body.scrollTop=currentTop-translatYPS;
    			
            }else{
    			clearInterval(timer)
    		}		
    	},1000/60)
    }
    
    
    goTop(1000)
    

    正弦余弦函数

    <!DOCTYPE html>
    <html>
    
    <head>
        <style>
            *{margin: 0}
            body {
                height: 500px;
            }
            [type="button"]{
                position: relative;
                left:-50px;
            }
            #circle {
                position: relative;
                top: 225px;
                float: left;
                text-align: center;
                line-height: 50px;
                 50px;
                background: blue;
                border-radius: 50%;
                /* transform:translate(0px,100px) */
            }
    
            hr {
                border- 1px 0px 0px 1px;
                border-style: solid;
                border-color: red;
                position: absolute;
                 500px;
            }
    
            hr:nth-of-type(1) {
                top: 0px;
            }
    
            hr:nth-of-type(2) {
                top: 125px;
            }
    
            hr:nth-of-type(3) {
                top: 225px;
            }
    
            hr:nth-of-type(4) {
                top: 250px;
            }
    
            hr:nth-of-type(5) {
                top: 275px;
            }
    
            hr:nth-of-type(6) {
                top: 375px;
            }
    
            hr:nth-of-type(7) {
                top: 500px;
            }
        </style>
    </head>
    
    <body>
        <button type="button">开始正弦运动</button>
        <button type="button">开始余弦运动</button>
        <div id='circle'>X</div>
        <hr>
        <hr>
        <hr>
        <hr>
        <hr>
        <hr>
        <hr>
        <script>
            let btns = document.querySelectorAll('[type=button]');
            let circle = document.querySelector('#circle');
    
            let x = 0;
            let maxLength = 500;
            //Y轴最大高度
            let A = 100;
            //x轴的系数
            let w = 2;
            //A*Math.sin(++y*w*Math.PI/180)(1px相当1角度)一帧水平方向走1px(这里为一角度)。
            //Math.PI/180 每角度占的弧度y*Math.PI/180增加的弧度(1px这里相当1角度相当多少弧度)
            //(!inx?0:Math.PI / 2)   正弦 余弦  是否加Math.PI/2
            for (let [inx, btn] of btns.entries()) {
                (function () {
                    let tranX=!inx?0:Math.PI / 2;
                    btn.addEventListener('click', function () {
                        requestAnimationFrame(function frameFn() {
                            console.log(circle.style.transform)
                            if (getTranslatePosition(circle, 'x') < maxLength) {
                                ++x;
                                circle.style.transform = 'translate(' + x + 'px,' + (-A * Math.sin(w * (x * Math.PI / 180 + tranX))) + 'px)';
                                requestAnimationFrame(frameFn);
                            }
                        })
                    })
                })(inx)
            }
    
            //"translate(264px, 99.4522px)".match(/translate((.*)px,(.*)px)/)
            function getTranslatePosition(el, direction) {
                let reg = /translate((.*)px,(.*)px)/;
                let transformArr = el.style.transform.match(reg);
                return !transformArr ? 0 :
                    direction = 'x' ? transformArr[1] :
                        direction = 'y' ? transformArr[2] :
                            [transformArr[1], transformArr[2]];
            }
        </script>
    </body>
    
    </html>
    

    精确控制动画的时间

    <!DOCTYPE html>
    <html>
    
    <head>
        <style>
            * {
                margin: 0
            }
    
            body {
                height: 500px;
            }
    
            [type="button"] {
                position: relative;
                left: -50px;
            }
    
            #circle {
                position: relative;
                top: 225px;
                float: left;
                text-align: center;
                line-height: 50px;
                 50px;
                background: blue;
                border-radius: 50%;
                /* transform:translate(0px,100px) */
            }
    
            hr {
                border- 1px 0px 0px 1px;
                border-style: solid;
                border-color: red;
                position: absolute;
                 500px;
            }
    
            hr:nth-of-type(1) {
                top: 0px;
            }
    
            hr:nth-of-type(2) {
                top: 125px;
            }
    
            hr:nth-of-type(3) {
                top: 225px;
            }
    
            hr:nth-of-type(4) {
                top: 250px;
            }
    
            hr:nth-of-type(5) {
                top: 275px;
            }
    
            hr:nth-of-type(6) {
                top: 375px;
            }
    
            hr:nth-of-type(7) {
                top: 500px;
            }
        </style>
    </head>
    
    <body>
        <button type='button' id='sin'>开始正弦运动5S</button>
        <button type='button' id='cos'>开始余弦运动5S</button>
        <div id='circle'>X</div>
        <hr>
        <hr>
        <hr>
        <hr>
        <hr>
        <hr>
        <hr>
        <script>
            
            let circle = document.querySelector('#circle');
    
            let x = 0;
            //动画持续时长
            let duration = 5000;
    
            //Y轴最大高度
            let A = 100;
            //x轴的系数
            let w = 2;
    
            sin.addEventListener('click', function () { move(circle, duration, sinFn) });
            cos.addEventListener('click', function () { move(circle, duration, cosFn) });
    			
            //duration {{numebr}}持续时长
            //movefn   {{function}}移动函数
            //console.log(timeProportion,circle.style.transform)
            //timeProportion 当前帧占整个周期的时间比例
            function move(el, duration, movefn) {
                let start = Date.now()
                requestAnimationFrame(function frameFn() {
                    let timeProportion = (Date.now() - start) / duration;
                    if (timeProportion < 1) {
                        movefn(el)
                        requestAnimationFrame(frameFn);
                    }
                })
            }
            function sinFn(el) {
                el.style.transform = 'translate(' + ++x + 'px,' + (-A * Math.sin(w * (x * Math.PI / 180))) + 'px)';
            }
            function cosFn(el) {
                el.style.transform = 'translate(' + ++x + 'px,' + (-A * Math.sin(w * (x * Math.PI / 180 + Math.PI / 2))) + 'px)';
            }
        </script>
    </body>
    
    </html>
    

    动画的基本封装

     start: function (finished) {
                var startTime = Date.now();
                var duration = this.duration,
                    self = this;
    
                requestAnimationFrame(function step() {
                    var p = (Date.now() - startTime) / duration;
                    if (p < 1.0) {
                        self.progress(p);
                        requestAnimationFrame(step);
                    } else {
                        if (typeof finished === 'function') {
                            finished()
                        }
                        self.progress(1.0);
                    }
                });
            }
    

    动画的暂停与继续(封装时基于promise,使用时基于async await步)

    <!DOCTYPE html>
    <html>
    
    <head>
        <style>
            #block {
                position: absolute;
                left: 100px;
                top: 100px;
                 20px;
                height: 20px;
                background: red;
                border-radius: 50%;
            }
        </style>
    </head>
    
    <body>
        <button type="button" id='btn'>暂停</button>
        <button type="button" id='continuebtn'>继续</button>
    
        <div id='block'></div>
        <script>
            class Animator {
                constructor(fn, duration = 500) {
                    this.duration = duration;
                    this.pauseState = false;
                    this.startTime = 0;
                    this.pauseTime = [];
                    this.continueTime = [];
                    this.pauseCount=-1;
                    this.fn = fn;
                }
                static sum(arr=[]){
                    return arr.reduce((current,next)=>{
                        return current+next
                    },0)
                }
                go(delay = 0) {
                    console.log('delay',delay)
                    if (!delay) this.startTime = Date.now();
                    return new Promise((resolve, reject) => {
                        let frameFn = () => {
                            var proport = (Date.now() - this.startTime - delay) / this.duration;
                            if (proport < 1) {
                                if (!this.pauseState) {
                                    this.fn(proport);
                                    requestAnimationFrame(frameFn);
                                }
                            } else {
                                this.fn(1);
                                resolve('done');
                            }
                        }
                        requestAnimationFrame(frameFn);
                    })
                }
                pause() {
                    this.pauseCount++;
                    this.pauseTime.push(Date.now());
                    console.log('this.pauseTime',this.pauseTime)
                    this.pauseState = true;
                }
                continue() {
                    this.continueTime.push(Date.now());
                    console.log(this.continueTime,this.pauseTime)
                    this.pauseState = false;
                    this.go(Animator.sum(this.continueTime) - Animator.sum(this.pauseTime))
                }
            }
            var a1 = new Animator(function (p) {
                var tx = 500 * p;
                block.style.transform = 'translateX(' + tx + 'px)';
            }, 3000);
            var a2 = new Animator(function (p) {
                var ty = 300 * p;
                block.style.transform = 'translate(500px,' + ty + 'px)';
            }, 3000);
            block.addEventListener('click', async function () {
                await a1.go();
                await a2.go();
            });
            btn.addEventListener('click', function () {
                a1.pause();
            })
            continuebtn.addEventListener('click', function () {
                a1.continue();
            })
        </script>
    </body>
    
    </html>
    

    多动画的控制(暂停、继续)(promise async await)

    <!DOCTYPE html>
    <html>
    
    <head>
        <style>
            #block {
                position: absolute;
                left: 100px;
                top: 100px;
                 20px;
                height: 20px;
                background: red;
                border-radius: 50%;
            }
        </style>
    </head>
    
    <body>
        <button type="button" id='btn'>暂停</button>
        <button type="button" id='continuebtn'>继续</button>
    
        <div id='block'></div>
        <script>
            class Cartoon {
                constructor(fn, duration = 500) {
                    this.duration = duration;
                    this.fn = fn;
    
                    this.startTime = 0;
                    this.pauseTimeArr = [];
                    this.continueTimeArr = [];
                }
                static sum(arr = []) {
                    return arr.reduce((current, next) => {
                        return current + next
                    }, 0)
                }
                //执行动画
                go() {
                    this.startTime = Date.now();
                    return new Promise((resolve, reject) => {
                        let frameStep = () => {
                            let proport = 0;
                            let isPause = this.pauseTimeArr.length > this.continueTimeArr.length;
                            if (isPause) {
                                //console.log('length', this.pauseTimeArr.length, this.continueTimeArr.length)
                                proport = (Cartoon.sum(this.pauseTimeArr) - Cartoon.sum(this.continueTimeArr) - this.startTime) / this.duration;
                            }
                            else {
                                proport = (Date.now() - this.startTime - (Cartoon.sum(this.continueTimeArr) - Cartoon.sum(this.pauseTimeArr))) / this.duration;
                            }
                            //console.log('比例', proport)
                            if (proport < 1) {
                                if (!isPause) {
                                    this.fn(proport);
                                }
                                requestAnimationFrame(frameStep);
                            } else {
                                this.fn(1);
                                resolve('done');
                            }
                        }
                        requestAnimationFrame(frameStep);
                    })
                }
                //暂停动画
                pause() {
                    if (this.startTime) this.pauseTimeArr.push(Date.now())
                }
                //继续动画(暂停过)
                continue() {
                    if (this.startTime && (this.pauseTimeArr.length > this.continueTimeArr.length)) this.continueTimeArr.push(Date.now())
                }
                //重置动画
                reset() {
    
                }
            }
            class Cartoons {
                constructor(...cartoons) {
                    this.cartoons = []
                    this.currentInx=0;
                    for (let cartoon of cartoons) {
                        this.cartoons.push(new Cartoon(...cartoon))
                    }
                }
                async go() {
                    while (this.currentInx < this.cartoons.length) {
                        if (await this.cartoons[this.currentInx].go()=='done')
                            this.currentInx++
                    }
                }
                pause() {
                    this.cartoons[this.currentInx].pause()
                }
                continue() {
                    this.cartoons[this.currentInx].continue()
                }
            }
            // let a1 = new Cartoon(function (p) {
            //     let tx = 500 * p;
            //     block.style.transform = 'translateX(' + tx + 'px)';
            // }, 3000);
            // let a2 = new Cartoon(function (p) {
            //     let ty = 300 * p;
            //     block.style.transform = 'translate(500px,' + ty + 'px)';
            // }, 3000);
            var c1 = [function (p) {
                let tx = 500 * p;
                block.style.transform = 'translateX(' + tx + 'px)';
            }, 3000]
    
            var c2 = [function (p) {
                let ty = 300 * p;
                block.style.transform = 'translate(500px,' + ty + 'px)';
            }, 3000]
            let c = new Cartoons(c1, c2)
            block.addEventListener('click', function () {
                c.go();
                // console.log(111, await a1.go())
                //await a2.go();
            });
              btn.addEventListener('click', function () {
                c.pause();
            })
            continuebtn.addEventListener('click', function () {
                c.continue();
            })
            // block.addEventListener('click', async function () {
            //     console.log(111, await a1.go())
            //     //await a2.go();
            // });
            // btn.addEventListener('click', function () {
            //     a1.pause();
            // })
            // continuebtn.addEventListener('click', function () {
            //     a1.continue();
            // })
        </script>
    </body>
    
    </html>
    

  • 相关阅读:
    python爬取酷狗音乐
    python爬取酷我音乐
    排列组合+逆元模板
    python爬取QQVIP音乐
    一维数组的动态和
    买卖股票的最佳时机 II
    最佳买卖股票时机含冷冻期
    买卖股票的最佳时机
    子集
    最短无序连续子数组
  • 原文地址:https://www.cnblogs.com/leee/p/7404991.html
Copyright © 2011-2022 走看看