日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

高中物理学运动公式实现js动画

發布時間:2024/3/24 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高中物理学运动公式实现js动画 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在網頁上創建動畫一般有兩種方式:css和javascript。它們在創建動畫的時間和性能上是不一樣的,各有利弊。選擇哪種方法實際上取決于項目,以及想要實現什么類型的動畫。

一般使用css動畫來實現比較簡單的“一次性轉換”,為UI元素轉換比較小的獨立狀態。例如從側面引入導航欄菜單,模太框彈出等。
要實現高級效果時,例如彈跳,加速,減速等比較復雜的動畫,則使用Javascript動畫。現在有很多比較好的JS動畫框架,例如TweenMax,Velocity,animo.js,jquery。

不管是css還是javascript來創建動畫,我們都會聽到一個詞“緩動”。自然界中沒有東西從一點呈線性的移動到另一點,一般可能需要加速或減速。在經典動畫中,經常會出現“緩入”,“緩出”,“緩入緩出”效果。緩動使動畫不再那么尖銳或生硬。
css中,我們要想達到這些效果,只需要使用一些關鍵字:
* linear
* ease-in
* ease-out
* ease-in-out

那這么關鍵字的背后到底是什么原理呢?如何用javascript來實現這些緩動效果。

動畫是關于時間的函數,本質就是利用瀏覽器和GPU的渲染過程定時改變元素的屬性。

使用javascript實現動畫時一般是使用requestAnimationFrame,我們可能經常也會用setInterval和setTimeout來實現動畫,但是它們實現的動畫都不會與屏幕的刷新率同步,并且很可能出現抖動和跳幀,例如jQuery就是采用setInterval來實現動畫,所以jQuery動畫的幀率會偏低(jQuery為甚么不采用RAF)。

“Talk is cheap, show me the code”。下面學習實現下月影總結的動畫原理。原理簡單,實現經典。

常見運動

  • 勻速運動

    讓小球在2s內向右勻速移動200px

    • 時間: t = T * p
    • 位移: St = S * p = v * t
    • 速度: v = St / t = S / T
    • 加速度: a = 0
  • circle.on('click', function() {var self = this;var startTime = Date.now();var distance = 200;var T = 2000;requestAnimationFrame(function step() {var p = Math.min(1.0, (Date.now() - startTime) / T);self.style.transform = 'translateX(' + (distance * p) + 'px)';if(p < 1.0){requestAnimationFrame(step);}}) })

    2.勻加速運動

    讓小球在2s內向右勻加速向右移動200px, 速度從0開始
    * 時間: t = T * p
    * 位移: St = S * p^2 = (S * t^2) / T^2
    * 速度: v = (2*S / T^2) * t = 2Sp/T
    * 加速度 a = 2*S / T^2

    circle.on('click', function() {var self = this;var startTime = Date.now();var distance = 200;var T = 2000;requestAnimationFrame(function step() {var p = Math.min(1.0, (Date.now() - startTime) / T);self.style.transform = 'translateX(' + (distance * p * p) + 'px)';if(p < 1.0){requestAnimationFrame(step);}})})

    3.勻減速運動

    讓小球在2s內向右勻減速向右移動200px, 速度從最大減為0
    * 時間: t = T * p
    * 位移: St = (2*S / T) * t - (S / T^2) * t^2 = Sp * (2 - p)
    * 速度: v = 2*S / T - 2*S / t^2 * t
    * 加速度 a = -2*S / T^2

    circle.on('click', function() {var self = this;var startTime = Date.now();var distance = 200;var T = 2000;requestAnimationFrame(function step() {var p = Math.min(1.0, (Date.now() - startTime) / T);self.style.transform = 'translateX(' + (distance * p * (2 - p)) + 'px)';if(p < 1.0){requestAnimationFrame(step);}})})

    4.拋物線運動

    circle.on('click', function() {var self = this;var startTime = Date.now();var disX = 200, disY = 200;var T = 1000 * Math.sqrt(2 * disY / 98);requestAnimationFrame(function step() {var p = Math.min(1.0, (Date.now() - startTime) / T);var tx = disX * p;var ty = disY * p * p;self.style.transform = 'translate(' + tx + 'px, ' +ty + 'px)';if(p < 1.0){requestAnimationFrame(step);}})

    5.簡諧擺動

    circle.on('click', function() {var self = this;var startTime = Date.now();var distance = 100;var T = 2000;requestAnimationFrame(function step() {var p = Math.min(1.0, (Date.now() - startTime) / T);var tx = distance * Math.sin(2 * Math.PI * p);self.style.transform = 'translateX(' + tx + 'px)';if(p < 1.0){requestAnimationFrame(step);}}) })

    6.正弦線

    circle.on('click', function() {var self = this;var startTime = Date.now();var distance = 100;var T = 2000;requestAnimationFrame(function step() {var p = Math.min(1.0, (Date.now() - startTime) / T);var ty = distance * Math.sin(2 * Math.PI * p);var tx = 2 * distance * p;self.style.transform = 'translate(' + tx + 'px,'+ ty +'px)';if(p < 1.0){requestAnimationFrame(step);}}) })

    7.圓周運動

    circle.on('click', function() {var self = this;var startTime = Date.now();var distance = 100;var T = 2000;var r = 100;requestAnimationFrame(function step() {var p = Math.min(1.0, (Date.now() - startTime) / T);var rotation = p * 360;self.style.transformOrigin = 'r' + 'px ' + r + 'px';self.style.transform = 'rotate(' + rotation +'deg)';if(p < 1.0){requestAnimationFrame(step);}})

    動畫封裝

    可以將動畫封裝成通用的對象,每次只需要實例定義單幀執行函數就可以了。

    參數:duration-動畫持續時間,progress每一幀執行的函數,easing-緩動效果(可傳可不傳) function Animator(duration, progress, easing) {this.duration = duration;this.progress = progress;this.easing = easing || function(p){return p}; } //調用start函數時可傳入參數,如果參數為false或者傳入的函數返回false,那么就說明進行循環動畫,相當于將css animation中的animation-iteration-count:infinite Animator.prototype.start = function(finished) {var self = this;var startTime = Date.now();var duration = self.duration;requestAnimationFrame(function step(){var p = (Date.now() - startTime) / duration;var next = true;if(p < 1.0) {self.progress(self.easing(p), p);}else { //第一次動畫之行完后開始執行回調函數if(typeof finished === 'function') {next = finished() === false;}else {next = finished === false;}//如果調用start時傳遞的參數為false或函數返回false,next便為true說明進行循環運動if(!next) {self.progress(self.easing(1.0), 1.0);}else {startTime += duration; //如果這里不加的話那么小球不會循環,而是一直向前運動self.progress(self.easing(p), p);}}//next為true,動畫繼續執行if(next) {requestAnimationFrame(step);}}) }

    目前這個函數存在的缺點就是雖然可以設置動畫執行為一次或一直循環,但是并不能設置動畫執行次數為2,3,4..,也不能設置動畫循環的方向,即不能像css animation設置animation-direction

    • 折線運動
      讓小球先向右運動再向下運動
    var a1 = new Animator(1000, function(p) {var tx = 100 * p;circle.style.transform = 'translateX(' + tx + 'px)'; }) var a2 = new Animator(1000, function(p) {var ty = 100 * p;circle.style.transform = 'translate(100px,' + ty + 'px)'; }) a1.start(function(){a2.start(); })

    動畫隊列

    為了能使多個動畫順序執行,需要用數組來模擬一個隊列管理動畫執行順序。

    function AnimationQueue(animators) {this.animators = animators || []; } AnimationQueue.prototype = {append: function() {var args = [].slice.call(arguments);this.animators.push.apply(this.animators, args);},flush: function() {if(this.animators.length) {var self = this;function play() {var animator = self.animators.shift();//如果數組中的對象是Animator的實例,則直接調用if(animator instanceof Animator) {animator.start(function() {if(self.animators.length) {play();}})}else { //數組中的對象不是Animator的實例,調用Animator的方法,可以在這里將之前的對象再次添加到animators數組中animator.apply(self);//通過這里可以進行循環運動if(self.animators.length) {play();}}}play();}} }
    • 彈跳的小球
      • 設20px為1米,下落距離為200px, 為10米
      • g = 10m/s
      • S = 1/2 * g * T^2 = 10
      • T = 1.414s = 1414ms
      • 下落階段 St = S * p^2
      • 上升階段 St = S - Sp * (2 - p)
    var c1 = new Animator(1000, function(p) {var ty = 200 * p * p;circle.style.transform = 'translateY(' + ty + 'px)'; }) var c2 = new Animator(1414, function(p) {var ty = 200 - 200 * p * (2 - p);circle.style.transform = 'translateY(' + ty + 'px)'; }) circle.addEventListener('click', function() {var animators = new AnimationQueue();animators.append(c1, c2, function execute() {this.append(c1,c2, execute);});animators.flush(); })

    • 彈跳幅度逐漸減小的小球
      • 上升時間:T = 0.7 * T
      • 上升距離:S = 0.49 * S
    circle.addEventListener('click', function() {var T = 1414;var a1 = new Animator(T, function(p) {var s = this.duration * 200 / T;var ty = s * (p * p - 1);circle.style.transform = 'translateY(' + ty + 'px)'; })var a2 = new Animator(T, function(p) {var s = this.duration * 200 / T;var ty = - s * p * (2 - p);circle.style.transform = 'translateY(' + ty + 'px)'; })var animators = new AnimationQueue();function foo() {a2.duration *= 0.7;if(a2.duration <= 0.0001) {animators.animators.length = 0;}}animators.append(a1, foo, a2, function b() {a1.duration *= 0.7;this.append(a1, foo, a2, b);});animators.flush(); })

    • 滾動的小球
      • 小球直徑:d = 50px
      • 圓周長: l = π * d;
      • 周期: T = 2s
      • 滾動時間: t = 4s
      • 滾動距離:S = π * d * t / T = 314px
    circle3.addEventListener('click', function() {var a1 = new Animator(4000, function(p) {var rotation = 'rotate(' + 720 * p + 'deg)';var x = 50 + 314 * p + 'px';circle3.style.transform = rotation;circle3.style.left = x;});var animators = new AnimationQueue();animators.append(a1, function b() {animators.append(a1, b);})animators.flush(); })

    以上就是利用我們學過的常見物理公式實現的js動畫效果。當然還可以有更多復雜的效果,如何實現各種優美的動畫也是值得深入學習的。

    總結

    以上是生活随笔為你收集整理的高中物理学运动公式实现js动画的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。