静的で動きのないプロトタイプは、控えめに言っても吸い込みます。 静的プロトタイプを使用すると、視覚的なデザインを表示できますが、相互作用のデザインは表示できません。
アプリケーションの相互作用設計の重要性を考えると、静的なプロトタイプはピースが欠けているパズルのようなものであると言えます。 では、誰もがこのすべての代わりにインタラクティブなプロトタイプを作成しないのはなぜですか? さて、After Effectsのようなユーティリティでは、プロトタイピングに時間がかかりすぎる場合があります。 そして、プロトタイプ自体は必要ないかもしれません。
Framerを試してください:デザイナーと開発者向けのユーティリティは非常に使いやすいです。
このFramerチュートリアルでは、 Volegによって作成されたアニメーションメニューを作成します 。
最も興味深い部分に焦点を当てます-メニューの折りたたみと展開のアニメーションのプロトタイプを作成します。
開始する
まず、次のプログラムをダウンロードしてインストールします(このチュートリアルでは無料の試用版を使用できます)。
フレーマーを開きます。 ようこそ画面が表示されます:
[アニメーション](左端のアイコン)をクリックして、サンプルプロジェクトを表示します。
左側がコードパネル、右側がプロトタイプパネルです。 それらの間には、レイヤーパネルがあります。
コードをさまよう、それが何をするかを理解してみてください。 理解できないものが残っていても心配しないでください。
このプロジェクトを閉じます。 独自に作成します。
新しいプロトタイプを作成する
Framerで新しいファイルを作成します:File-> New 。 次に- 挿入 -> レイヤーを選択して、新しいレイヤーを作成します。
レイヤー属性の表示をキャンセルするには、コードエディターの空の場所をクリックします。 これで、各パネルに新しいレイヤーが表示されます。
- コードパネルのコードと同様
- レイヤーパネルのリンクとして
- プロトタイプパネルの灰色の四角のような
レイヤーパネルでレイヤーの名前にカーソルを合わせて、プロトタイプ上の位置を確認します。
コードバーで名前を正方形に変更します。
コードの行の左側にあるボックスをクリックして、レイヤーパネルでレイヤーの属性を表示および変更し、プロトタイプパネル内を移動します。
四角形をプロトタイプの中心にドラッグし、コードパネルとレイヤーパネルで変更を確認します。
プロトタイプと対話することによるレイヤーの変更は、コードにすぐに表示されます-逆も同様です。 コードとビジュアルエディターの両方を使用して変更を加える機能は、XcodeおよびSwiftとは対照的に、Framerでのプロトタイプ作成の大きな利点を提供します。
既存のコードを削除して、次を入力します。
square = new Layer x: 250 y: 542 height: 250 width: 250 backgroundColor: "rgba(255,25,31,0.8)"
また、プロトタイプのすべてが変更されました。 きれいですよね?
発言。 Javascriptにコンパイルするシンプルな言語であるCoffeeScriptを使用して、Framerでコードを記述します。 一度も使用したことがない場合でも心配しないでください。このレッスンから構文について多くを学ぶことができます。
CoffeeScriptではインデントが重要であることに注意してください。 したがって、インデントが私のインデントと一致することを確認してください。一致しない場合、コードは機能しません。 CoffeScriptのインデントは{}を置き換えます。
タブとスペースは同じものではありません。 デフォルトでは、Framerはタブを使用するため、次のようなスペースを含むコードが表示される場合:
行の先頭にあるスペースを削除し、タブに置き換えます。
コードをコピーして貼り付けて新しい行に移動するときは、 常に行の先頭より前のすべてを削除してください。 そうしないと、コードが他の何かの一部として解釈される可能性があります。
最初のフレーマーアニメーション
魔法の時が来ました。 クリックしてオレンジ色の円にすることで、赤い正方形を作成します。 レイヤーの説明の後に空の行を追加し、次を貼り付けます。
square.onTap -> square.backgroundColor = "rgba(255,120,0,0.8)" square.borderRadius = 150
XcodeやSwiftよりもFramerでプロトタイプを作成する最大の利点は、変更を行った直後にプロトタイプとやり取りできることです。 Xcodeでプロジェクトをビルドして実行するコストがかからないため、プロトタイピングの速度が大幅に向上します。
さて、私はあなたが何を考えているか知っています。 アニメーションの速度を落とす必要があります-遷移が急激すぎるため、ユーザーは赤い正方形に戻ることができません。 これは簡単に修正できます。
クリック後に正方形に何が起こるかを指定する代わりに、新しい状態を追加します。
追加したコードをこれで置き換えます。
# 1 square.states.add orangeCircle: backgroundColor: "rgba(255,120,0,0.8)" borderRadius: 150 # 2 square.onTap -> square.states.next()
それを理解しましょう。
- これは、 squareの新しいorangeCircle状態について説明しています。 この新しい状態は、 backgroundColor属性をorangeに、 borderRadiusを150に設定します 。プロパティの完全なリストについては、 framer.jsのドキュメントを参照してください。
- ここでイベントが設定されます-押すと、正方形が次の状態になります。
正方形をクリックして、新しい遷移を表示します。
これで、形状がアニメーション化されてorangeCircle状態になり、元の状態に戻ります。 これは、状態をレイヤーの状態ループに追加したため、 orangeCircleの後の次の状態がデフォルトの状態になっているためです。
状態をもう1つ追加してみましょう。 セクション1の後に次の行を追加します。
square.states.add greenRounded: backgroundColor: ("green") borderRadius: 50
プロトタイプパネルの正方形をクリックします。 3つの状態すべてのサイクルが表示されます。
ほんの数行のコードとほとんどインストールなしで、スムーズな(滑らかな)アニメーションを作成しました。
UIなど、より複雑でクールなものに進むことができると思います。
Framerを使用してアニメーションを作成します。
作成するアニメーションをもう一度見てみましょう。
アニメーションを作成する上で最も重要な部分は、単純なコンポーネントに分解することです。 これは、アニメーションを理解するだけでなく、ステップバイステップの説明を作成するのにも役立ちます。 このアニメーションで解決すべき3つの問題があります。選択状態、選択解除、およびそれらの間の遷移です。
選択解除
ユーザーが最初に見るもの:
- タップする4つのバナー。
- 各バナーには、独自の色、アイコン、タイトルがあります。
- 各バナーは、その下のバナーに影を落とします。
選択済み
ユーザーがバナーをクリックした後に表示されるもの:
- 色、タイトル、小さなアイコンのあるトップバー。
- 白い背景。
- 上部パネルは、下部レイヤーに影を落とします。
- 下部に4つの均等に分散したビュー-上部に2つ、下部に2つ。
- プレゼンテーションの色は、選択したバナーによって異なります。
ユーザーは、2つの状態間の遷移を選択します。 選択解除状態では、ユーザーは色付きのバナーの1つをタップします。 選択状態で、トップパネルに。
選択解除から選択への移行
移行時に行われることは次のとおりです。
- 4つのバナーはすべて展開され、下に移動して、次のバナーが終了するところから開始します。 結果として、各バナーは画面の4分の1を占めます。
- バナーは常に順序付けられているため、クリックされたバナーは、 選択解除された状態でのバナーの表示方法には影響しません。
- バナー拡張アニメーションはゆっくりと開始し、その後大幅に加速し、フェードで終了します。
- 各バナーには独自の影があります。
- アイコンは、サイズの0から100%に拡大します。 アニメーションはすぐに始まり、フェードで終わります。
- テキストは、拡大するバナーの下を4/5移動します
アニメーション全体が壊れたので、最も楽しい部分、つまりその構築に進むことができます。
発言。 具体的には、このアニメーションは簡単に分割できましたが、通常、 QuickTimeを使用してアニメーションを記録し、 After EffectsまたはAdobe Photoshopでスローダウンして詳細を強調すると非常に便利です。 たとえば、この手法は、バナーをタップしてすぐにアイコンを非表示にするか、徐々にアイコンを表示するかを判断するのに役立ちました。
手配
まず、レッスン用の一連の写真をアップロードします。 アーカイブには、アイコン、フォント、テキスト、ビューなど、アニメーションの作成に必要なものがすべて含まれています。 Archiveフォントをインストールします。 スケッチファイルを開く前にこれを行うことが重要です。そうしないと、正しく表示されません。 次に、 SweetStuff.sketchを開き、作成したものを確認します。
Framerに戻って、新しいファイルFile → Newを作成しましょう。 次はインポートです。
サイズを1倍のままにして、もう一度[ インポート ]をクリックします。 以下が表示されます。
フレーマーは、スケッチファイル内のすべてのレイヤーへのリンクを含むスケッチ変数を作成しました。 レイヤーパネルでは、それらすべてを見ることができます。
発言。 [ インポート ]をクリックする前に、スケッチファイルが開かれていることを確認してください。開いていない場合、Framerはそれを認識できません。
プロトタイプは多くのデバイスで動作するはずです。 したがって、選択したデバイスへのリンクとしてデバイス変数を作成し、その画面サイズに必要なすべてを配置します。
スケッチ変数の後に次を追加します。
device = Framer.Device.screen
使いやすくするために、色の定数を追加します。
blue = "rgb(97,213,242)" green = "rgb(150,229,144)" yellow = "rgb(226,203,98)" red = "rgb(231,138,138)"
次に、コンテナレイヤーを作成して、他のすべてを保存します。
container = new Layer width: device.width height: device.height backgroundColor: 'rgba(255, 255, 255 1)' borderRadius: 5 clip: true
ここで、 コンテナレイヤーを作成し、デバイスの画面サイズと同じサイズを設定します。 次にbackgroundColorを白に設定します -これがビューの背景になります。 他のすべてのレイヤーはこのレイヤーに追加されます。 clipをtrueに設定することにより、コンテナの外側には何も表示されないことを示します。
選択解除状態
選択解除された画面をインストールすることから始めましょう。
メニューのレイヤー。 各レイヤーの幅と高さを知っているので、それらを定数として定義します。
menuHeight = container.height/4 menuWidth = container.width
以下のコードを追加して、何が起こるかを見てください。
cookieMenu = new Layer height: menuHeight width: menuWidth x: 0 y: 0 backgroundColor: blue
ここで、Cookieメニューの新しいレイヤーを作成し、青い背景、x、y座標、および幅で高さを設定します。
メニューの残りの部分で同じことをする必要がありますが、覚えておいてください-y座標は前のレイヤーの終わりから始まります: y:prevousMenu.y + previousMenu.height 。
cupcakeMenu = new Layer height: menuHeight width: menuWidth x: 0 y: cookieMenu.y + cookieMenu.height backgroundColor: green fruitMenu = new Layer height: menuHeight width: menuWidth x: 0 y: cupcakeMenu.y + cupcakeMenu.height backgroundColor: yellow iceCreamMenu = new Layer height: menuHeight width: menuWidth x: 0 y: fruitMenu.y + fruitMenu.height backgroundColor: red
次に、影を追加して、各メニューが他のメニューの一番上から始まるような錯覚を作成します。
各レイヤーの説明の最後に、次を追加します。
shadowY: 2 shadowBlur: 40 shadowSpread: 3 shadowColor: "rgba(25,25,25,0.3)"
やった! しかし、停止してください、それはそのように表示されません。 これは、 iceCreamMenuが上部にあり、その逆ではなく、レイヤーが上から下に順に追加されたためです。
メニューの位置を変更し、正しい順序で表示する関数を作成します。 Framerの関数定義のシグネチャは次のとおりです。
functionName = ([params]) ->
レイヤーを定義した後にメニューを再配置するには、次の関数を追加します。
repositionMenus = () -> iceCreamMenu.bringToFront() fruitMenu.bringToFront() cupcakeMenu.bringToFront() cookieMenu.bringToFront() repositionMenus()
repositionMenus関数は引数を取らず、メニューレイヤーを下から上に移動します。 次は関数呼び出しです。
プロトタイプパネルを見てください-影が正しい順序で表示されるようになりました。
アイコンとヘッダーを追加する
cookieMenuから始めましょう。 ファイルの最後に次のコード行を追加します。
cookieIcon = sketch.Cookie cookieIcon.superLayer = cookieMenu cookieText = sketch.CookieText cookieText.superLayer = cookieMenu
ここで2つの変数が作成されます: cookieIconおよびcookieTextは 、Sketchの対応するオブジェクト-CookieおよびCookieTextによって初期化されます。 次に、 cookieMenuレイヤーをsuperLayerプロパティに割り当てます 。
次のタスクは、これらのレイヤーを配置することです。 cookieIconは親レイヤー(superLayer)の中央に配置し、 cookieTextは水平に中央に配置する必要がありますが、親レイヤーに対して4/5だけ垂直に下に移動します。
アイコンを中央揃えに処方する:
cookieIcon.center()
テキストの位置を確立するには、次を追加します。
cookieText.centerX() cookieText.y = cookieText.superLayer.height * 0.8
残りのメニュー項目について、これをすべて繰り返します。
cookieIcon = sketch.Cookie cookieIcon.superLayer = cookieMenu cookieIcon.center() cookieText = sketch.CookieText cookieText.superLayer = cookieMenu cookieText.centerX() cookieText.y = cookieText.superLayer.height * 0.8 cupcakeIcon = sketch.Cupcake cupcakeIcon.superLayer = cupcakeMenu cupcakeIcon.center() cupcakeText = sketch.CupcakeText cupcakeText.superLayer = cupcakeMenu cupcakeText.centerX() cupcakeText.y = cupcakeText.superLayer.height * 0.8 fruitIcon = sketch.Raspberry fruitIcon.superLayer = fruitMenu fruitIcon.center() fruitText = sketch.FruitText fruitText.superLayer = fruitMenu fruitText.centerX() fruitText.y = fruitText.superLayer.height * 0.8 iceCreamIcon = sketch.IceCream iceCreamIcon.superLayer = iceCreamMenu iceCreamIcon.center() iceCreamText = sketch.IceCreamText iceCreamText.superLayer = iceCreamMenu iceCreamText.centerX() iceCreamText.y = iceCreamText.superLayer.height * 0.8
これは多かれ少なかれ、選択解除された状態に似ています。
リファクタリング
しかし、振り返ってみると、画面にコードが多すぎることがわかります。
すべての状態を詳細に書き留める必要があるときに、コードがどれだけ大きくなるかを考えてください。
各メニュー項目に個別のレイヤー、アイコン、テキストを作成する代わりに、読みやすさと正確さを簡素化する関数を作成します。
menuHeightとmenuWidthを定義した後に記述したすべてを、次のものに置き換えます。
# 1 menuItems = [] colors = [blue, green, yellow, red] icons = [sketch.Cookie, sketch.Cupcake, sketch. Raspberry, sketch.IceCream] titles = [sketch.CookieText, sketch.CupcakeText, sketch.FruitText, sketch.IceCreamText] # 2 addIcon = (index, sup) -> icon = icons[index] icon.superLayer = sup icon.center() icon.name = "icon" # 3 addTitle = (index, sup) -> title = titles[index] title.superLayer = sup title.centerX() title.y = sup.height - sup.height*0.2 title.name = "title" # 4 for menuColor, i in colors menuItem = new Layer height: menuHeight width: menuWidth x: 0 y: container.height/4 * i shadowY: 2 shadowBlur: 40 shadowSpread: 3 shadowColor: "rgba(25,25,25,0.3)" superLayer: container backgroundColor: menuColor scale: 1.00 menuItems.push(menuItem) addIcon(i, menuItem) addTitle(i, menuItem) repositionMenus = () -> menuItems[3].bringToFront() menuItems[2].bringToFront() menuItems[1].bringToFront() menuItems[0].bringToFront() repositionMenus()
このコードの機能:
- メニュー項目、色、アイコン、ヘッダーを保存する配列を宣言します。
- この関数は、メニュー項目の各レイヤーにアイコンを追加します。
- 見出しだけでも同じです。
- ここでは、各メニュー項目のループを実行して、新しいレイヤーを作成し、関数を呼び出してアイコンとヘッダーを追加します。 これらのレイヤーは、後でそれらにすばやくアクセスできるように、 menuItems配列に格納されることに注意してください。
そして、紳士dies女は純粋なコードです。 どうぞ
選択状態への移行
最初のステップは、 menuItemsを使用してメインループにcollapseという新しい状態を追加することです。 考えてみてください。 折り畳み状態になったとき、各menuItemで何をする必要がありますか?
展開状態から折りたたみ状態に移行する必要があります
今後の変更の概要:
- レイヤーのy座標は0になります。
- 高さは画面の1/4から画面の1/9に減少します。
- アイコンが徐々に消えます。
- テキストのy座標が変更され、上に移動します。
- 選択したmenuItemの影のみが表示されます 。
手始めに、単純なことに注目してください: menuItemの高さとy座標。 forループの2行をコメントアウトしますが、削除しないでください-後で必要になります。
# addIcon(i, menuItem) # addTitle(i, menuItem)
発言。 行をコメントアウトするには、 Command + /を押します。
collapsedMenuHeight定数を、 コンテナレイヤーの後の残りの定数に追加します。
collapsedMenuHeight = container.height/9
menuItems.push(menuItem)の前に折りたたみ状態を追加します。
menuItem.states.add collapse: height: collapsedMenuHeight y : 0
次に、 menuItemsをclickイベントに応答させる必要があります。 ループの直後、 repositionMenusの前に、各menuItemのイベントをアナウンスします。
#onTap listeners menuItems[0].onTap -> for menuItem in menuItems menuItem.states.next() this.bringToFront() menuItems[1].onTap -> for menuItem in menuItems menuItem.states.next() this.bringToFront() menuItems[2].onTap -> for menuItem in menuItems menuItem.states.next() this.bringToFront() menuItems[3].onTap -> for menuItem in menuItems menuItem.states.next() this.bringToFront()
menuItemをクリックするたびに、ループはmenuItemsのすべての要素を通過し、各要素を次の状態にします。 This.bringToFront()は、選択したmenuItemを残りのレイヤーの上に公開します。 後のイベントは簡単に変更できます。互いに別々に発表したためです。
発言。 thisキーワードは、名前を直接使用する代わりに、現在処理中のオブジェクトを参照する必要がある場合に役立ちます。 これはよりクリーンで、ほとんどの場合短く、コードの可読性を向上させます。
クリックの仕組みを確認してください。
最後の仕上げ
アイコンとヘッダーを返し、いくつかの問題を修正します。 これを行うには、 menuItemが選択されたときを追跡する必要があります。 ループの後、 onTapイベントの前に変数を追加します。
selected = false
最初に何も選択されていないため、 selectedをfalseに初期化します 。
これで、選択状態と選択解除状態を切り替える関数を作成できます。 repositionMenus関数の前に、次を追加します。
# 1 menuStateChange = (currentItem) -> # 2 for menuItem in menuItems menuItem.states.next() # 3 if !selected currentItem.bringToFront() # 4 else repositionMenus() # 5 selected = !selected
- currentItemパラメーター(押されたmenuItemメニュー項目)を取ります 。
- すべてのmenuItemを通過し、各アイテムを次の状態にします。
- menuItemが選択されていない場合、 selectedはfalseなので、 currentItemを前方に設定します。
- menuItemが選択された場合、 selectedはtrueであるため、 repositionMenus()関数を使用してメニューを元の状態に戻す必要があります。
- 最後に、現在の値と反対の値を割り当てます。
これで、 onTapの実装でこの関数を使用できます。 各メニュー項目について、 onTapを変更します 。
menuItems[0].onTap -> menuStateChange(this)
かっこいい。 さて、注意深く見ると、メニュー項目が圧縮されると、影が何となく太く見えます。 これは、レイヤーの4つの影すべてが互いに重なり合っているためです。
修正するには、 menuStateChangeでループを変更します。
for menuItem in menuItems if menuItem isnt currentItem menuItem.shadowY = 0 menuItem.shadowSpread = 0 menuItem.shadowBlur = 0 menuItem.states.next()
レイヤーが選択されていない場合、レイヤーが圧縮されると影は削除されます。 今でも、アニメーションはかなりクールに見えますが、アイコンとタイトルの2つが欠落しています。 menuItemsループでこれらの2行のコメントを解除します(ループの最後の行であることを確認してください)。
addIcon(i, menuItem) addTitle(i, menuItem)
addIconおよびaddTitleで子レイヤーに名前を追加したことを覚えていますか? これで便利になります。 これらの名前は、 menuItemのレイヤーを区別するのに役立ちます。
menuStateChange()の後に、メニューを圧縮するために次の行を追加します。
collapse = (currentItem) -> # 1 for menuItem in menuItems # 2 for sublayer in menuItem.subLayers # 3 if sublayer.name is "icon" sublayer.animate properties: scale: 0 opacity: 0 time: 0.3 # 4 if sublayer.name is "title" sublayer.animate properties: y: collapsedMenuHeight/2 time: 0.3
コードを見ていきましょう。
- すべてのmenuItems要素を繰り返し処理します。
- menuItemごとに、その子レイヤー( subLayers )を反復処理します。
- アイコンレイヤーがキャッチされた場合、0.3秒の間、スケール= 0、不透明度= 0にアニメートします。
- タイトルレイヤーが捕捉された場合、Y座標を現在のメニュー項目の中心にアニメーション化します。
前の関数が追加された直後に、別の関数を追加します。
expand = () -> # 1 for menuItem in menuItems # 2 for sublayer in menuItem.subLayers # 3 if sublayer.name is "icon" sublayer.animate properties: scale: 1 opacity: 1 time: 0.3 # 4 if sublayer.name is "title" sublayer.animate properties: y: menuHeight * 0.8 time: 0.3
- menuItems要素を繰り返し処理します。
- 各menuItemの子レイヤーを反復処理します。
- 子レイヤーがiconの場合、0.3秒以内に最大100%、不透明度-最大1のスケールでアニメーション化します 。
- 子レイヤーがタイトルの場合、Y座標をmenuHeight * 0.8にアニメーション化します。
呼び出しを追加して、 collapse()およびexpand()をmenuStateChange()に追加します。
menuStateChange = (currentItem) -> # remove shadow for layers not in front for menuItem in menuItems if menuItem isnt currentItem menuItem.shadowY = 0 menuItem.shadowSpread = 0 menuItem.shadowBlur = 0 menuItem.states.next() if !selected currentItem.bringToFront() collapse(currentItem) else expand() repositionMenus() selected = !selected
プロトタイプパネルを確認してください-アイコンとタイトルのアニメーション化は正常に機能します。
ほぼ完了です。 少し左! :]
アニメーション設定
Framerでは、任意のレイヤーをアニメーション化できます。 アニメーション設定は、次のパラメーターによって決定されます。
- プロパティ:幅、高さ、スケール、borderRadiusなど。それぞれ幅、高さ、スケール、境界線の半径。 レイヤーは、任意の状態から、ここで構成した状態に変換されます。
- 時間:アニメーションの持続時間。
- repeat:アニメーションを繰り返す回数。
- 遅延:アニメーションの前に一時停止が必要かどうか、およびそれがどれだけ続くか。
- 曲線:アニメーション速度。
- カーブオプション:アニメーションカーブの速度を微調整します 。
曲線と曲線のオプションはかなりわかりにくいですね。 これらを使用して、 Framer.jsアニメーションプレイグラウンドオプションを使用して、アニメーションカーブのプロトタイプを作成できます。
プロトタイプのアニメーションカーブを定義しなかったため、Framerはデフォルトでイージーカーブを使用します。
タフで不自然に見えます。 スプリングカーブの方が適しています。これにより、移行ステップで発生するすべてをより適切に制御できます。
次に、上記のすべてをcurveOptions設定の数値に変換します。
スプリングカーブ(スプリング)には次のパラメータが必要です。
- 緊張 。 おそらく「材料」は何でできているのでしょうか。 数値が大きいほど、速度とリバウンドが大きくなります。
- 摩擦 抵抗値。 数値が大きいほど、アニメーションは速くフェードします。
- 速度 初期アニメーション速度。
これらの数字がわからなくても、遊んでみてください。 プロトタイプでは、速度が異なる2つのアニメーションを見たいと思います。
メニューアニメーション:ゆっくりと開始し、大幅に加速し、劇的に減速します。
アイコンとタイトルのアニメーション:アイコンのサイズが100%から0%に変化し、アニメーションが突然発生します。 すぐに開始しますが、突然フェードします。 前のアニメーションと比較して、このアニメーションは緊張が少なく、異なる速度間の遷移が高速です。
menuItems.push(menuItem)の前に、次を追加します。
menuItem.states.animationOptions = curve: "spring" curveOptions: tension: 200 friction: 25 velocity: 8 time: 0.25
ここでは、メニュー項目にスプリングアニメーションを割り当て、 張力 = 200、 摩擦 = 25、 速度 = 8に設定します。アニメーションは、アイコンやヘッダーよりも速く移動します。
すべてのsublayer.animateを見つけ、 プロパティセクションのタイムラインの後に次を追加します。
curve: "spring" curveOptions: tension: 120 friction: 18 velocity: 5
ヘッダーとアイコンの同じ春のアニメーションがここに追加されます。
このコードを4回追加します。アイコンと見出しに対して、 折りたたみで2回、 展開で2回です。 結果を比較するには-サンプル関数:
collapse = (currentItem) -> for menuItem in menuItems for sublayer in menuItem.subLayers if sublayer.name is "icon" sublayer.animate properties: scale: 0 opacity: 0 time: 0.3 curve: "spring" curveOptions: tension: 120 friction: 18 velocity: 5 if sublayer.name is "title" sublayer.animate properties: y: collapsedMenuHeight/2 time: 0.3 curve: "spring" curveOptions: tension: 120 friction: 18 velocity: 5
最終的には次のようになります。
次はどこに行きますか?
すべてがうまくいきました!最初のFramerプロトタイプおめでとうございます。プロジェクトはこちらからダウンロードできます。彼はこのレッスンよりも少し進んで、各メニュー項目にビューを表示する方法を示しています。同じプロトタイプとともに、完全なプロジェクトがXcode + Swiftで作成されました。
- 1. 公式ドキュメントとそのレッスンで Framerの詳細を学ぶことができます。
- Framerのレイヤーは、パン、スワイプ、ピンチジェスチャなど、他の多くのイベントにも応答できます。このようなイベントの詳細については、こちらをご覧ください。
- 条件で何ができるか。
- アニメーションセクションのFramerのイージングカーブで曲線について読むことができます。
- animation curves Framer .
- .
- , Swift Xcode iOS Animations by Tutorials .