iOS開發之動畫中的時間

来源:http://www.cnblogs.com/huahuahu/archive/2016/10/07/iOS-kai-fa-zhi-dong-hua-zhong-de-shi-jian.html
-Advertisement-
Play Games

概述在動畫中,我們會指定動畫的持續時間。例如scaleAnimation.duration = self.config.appearDuration那麼這個時間是怎麼定義的呢?是指的絕對時間嗎?層級時間結構layer在屏幕上的顯示位置是根據父layer的位置以及本身相對於父layer偏移定義的。與此... ...


概述

在動畫中,我們會指定動畫的持續時間。例如

scaleAnimation.duration = self.config.appearDuration

那麼這個時間是怎麼定義的呢?是指的絕對時間嗎?

層級時間結構

layer在屏幕上的顯示位置是根據父layer的位置以及本身相對於父layer偏移定義的。
與此類似,每一個layer都有自己的time space,計算本地時間(local time)時候,需要根據父layer的時間以及一定的轉換規則來計算出本地時間。
這個規則就是CAMediaTiming協議。每一個CALayerCAAnimation實現了這個協議。

關於時間的概念

  1. 絕對時間Absolute time
    CACurrentMediaTime函數返回,實際調用mach_absolute_time()
  2. active local time
    根據CAMediaTiming協議計算得到的當前對象上的時間。
  3. basic local time
    由於動畫可以重覆(repeat)或者回放(play backwards)。需要把active local time轉化為做動畫相關的時間。
    例如active local time是5.5s,動畫的重覆次數是10,動畫持續時間是1s。那麼5.5s的active local time對應的local time是0.5s。

CAMediaTiming協議

  1. beginTime

    Required. Specifies the begin time of the receiver in relation to its parent object, if applicable.

    指定了指定了父對象時間和子對象時間的偏移。

  2. speed

    Specifies how time is mapped to receiver’s time space from the parent time space

    對動畫以及子動畫速度應用一個縮放的因數。如果speed是2.0,那麼本地時間流逝的速度是父對象的時間流逝速度的兩倍。

  3. timeOffset

    Required. Specifies an additional time offset in active local time.

    對本地時間做了一個偏移。

時間轉換公式

  1. 從父layer轉化為active local time \[ t= max\left\{(t_p-begintime),0\right\}*speed+offset \] 其中\(t\)是本地時間,\(t_p\)是父layer的時間,其他都是CAMediaTiming要求實現的欄位。

例子

用一個簡單的例子來說明各個參數的影響。動畫很簡單,一個紅色的方塊從左移到右邊。動畫的持續時間是1s,沒有重覆。
fsdf

  1. 設置speed為2,begin time為0.3s,offset為0.5s,效果如下
    121
    與上面相比,三處不同
    1. 動畫的速度是原來的兩倍,這是因為動畫的speed是2。
    2. 動畫起始時,滑塊的位置為中央,而不是在左邊。這是因為offset為0.5s。由於動畫的持續時間是1s,0.5s時,動畫剛剛進行了一半,滑塊的位置是在屏幕中央。
    3. 點擊開始動畫的按鈕,到開始動畫,有一個延遲,這是因為begin time的時間不是預設值,而是有一個0.3s的延遲。
  2. 時間變換的圖像表示
    1. 從父layer的時間到子layer的active local time

      圖中,直線的斜率是speed,第一個y值不為零的點,對應的橫軸坐標是begintime,對應的y軸坐標是offset
    2. 從active local time到basic local time  圖中,不為0的部分的x軸長度,即是動畫時間,由repeattime或repeatDuration指定。由於這個動畫沒有repeattime或repeatDuration,因此就是動畫的duration。如果指定了動畫的時間,比如repeatcount為3,那麼非0部分會重覆3次。
      如果指定了autoreverses為yes,那麼折線會部分有負的曲率。
      第一個不為0的點對應的橫軸坐標即為offset。 fillMode可以理解為不在動畫時間內的y值是什麼。如果kCAFillModeBackwards,對應於橫軸在offset之前時,縱軸對應於offset。kCAFillModeForwards對應於橫軸在動畫結束之後,縱軸保存不變。
  3. 父對象和子對象聯動
    我們的例子中,動畫是加在layer上的,它們都遵守CAMediatiming協議,就CAMediatiming看來,動畫的父對象是layer。
    1. 設置父對象的speed
      我們設置layer的speed為2,動畫的speed為0.1,實際的速度會是0.2. 顛三倒四
    2. 設置父對象的offset 設置父對象的offset為0.5,那麼動畫將會在一半處開始。
      ds

關於begintime

根據公式
\[
t= max\left\{(t_p-begintime),0\right\}*speed+offset
\]
這裡begintime是應該怎麼指定呢?如果想把一個加到layer的動畫的延遲5s執行,應該把begintime直接設為5嗎?
由於begintime是相對於父對象(layer)的時間偏移。由於layer可能在很久以前就存在了,因此對於動畫來說\(t_p\)是一個很大的值。直接把begintime指定為5s,那麼\(t\)將會是一個很大的值。正確的做法是把begintime設置為5s+這個layer被加到父layer以後,度過的時間,稱為addtime.

    animation.beginTime = addTime + delay;

如何得到addtime

addTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];

參考

控制動畫時間
控制動畫時間
Time Warp in Animation


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 接上面的船舶管理業務,這裡介紹添加和修改操作。 目錄 1. 添加操作 2. 修改操作 3. 線上演示 1. 添加操作 1.1 創建AddShipWindow.js 在業務中的view目錄下創建一個AddShipWindow.js文件,表示一個增加船舶的視窗組件。 此文件中包含了一個form組件用於顯 ...
  • Atitit.gui api自動化調用技術原理與實踐 gui介面實現分類(h5,win gui, paint opengl,,swing,,.net winform,)1 Solu cate1 Solu1 other1 Ref2 gui介面實現分類(h5,win gui, paint opengl, ...
  • 最近一段時間正在對JavaScript進行學習,知識太多,需要進行實際的使用和總結,國慶長假正好有時間,寫了下麵對JavaScript總結,可能對事件的理解還不夠完善,希望讀者多多指導,拍磚,我將不勝感激。好了直接如題吧。 JavaScript中的事件流 DOM2級事件規定事件流分為3個階段: 第一 ...
  • 【BaseFragment】: 【LoadingPage】: ...
  • 【原因】: 在工程中既有本地的lib.jar文件,又有compile鏈接。 ...
  • 剛從 eclipse 轉到 android studio 的同學,編寫代碼時使用的快捷鍵不同,一時難以適應,當然可以通過設置,將快捷鍵模板設置成與 eclipse 相同的,但我個人不贊成,因為 Android Studio 裡面還有一些快捷鍵是 eclipse 裡面沒有的,所以還是通過項目來熟悉An ...
  • 網上有很多例子來演示Android客戶端和伺服器端數據如何實現交互不過這些例子大多比較繁雜,對於初學者來說這是不利的,現在介紹幾種代碼簡單、邏輯清晰的交互例子,本篇博客介紹第四種: 一、伺服器端: 代碼1:添加名為“AndroidServerServlet.Java”的文件 [java] view ...
  • 1.先重寫uiviewcontrol的方法 - (UIViewController *)viewController { for (UIView* next = [self superview]; next; next = next.superview) { UIResponder *nextRes ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...