figmaでオブジェクトを作成して、web上で表示させそれをアニメーションする方法を見ていきます。
関連記事
【figma】必要なことを覚えてオブジェクトを自由に作成する
2022年02月05日
Figmaオブジェクトを作成してアニメーションさせる
figmaでオブジェクトを作成していきます。
① 500px × 500px のフレームを作成して、その② x=150px y=100px の位置に200pxの線のオブジェクトを作成します。
フレームのfill属性を削除、stroke属性を追加、線のオブジェクトはペンツールで作成、ストロークの色を変更して太さを10pxに指定しています。
SVGをブラウザで表示
③ フレームを右クリック > Copy/Paste as > Copy as SVG でコピーしたSVGをhtmlファイルにペーストします。
<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="0.5" width="499" height="499" stroke="black"/>
<path id="line" d="M150 100H350" stroke="#37CBEC" stroke-width="10"/>
</svg>
3: 線のpathに id=”line” を追加します。
animateTransform要素でアニメーション
animateTransformでは、移動、スケーリング、回転およびまたはゆがみのアニメーション制御することができ、実用的な移動と、回転を見ていきます。
移動(translate)
<path id="line" d="M150 100H350" stroke="#37CBEC" stroke-width="10">
<animateTransform attributeName="transform" type="translate" from="0 0" to="100 100" dur="4s" repeatCount="indefinite" />
</path>
pathの内部にanimateTransformタグを追加します。
水平方向や垂直方向 from=”x y” から to=”x y” へ移動します。
0 0が現在の位置で、マイナスも使うことができます。
共通属性
- dur=”4s” → 移動時間を4秒で指定、(ms, m ,h)が単位で使用できます。
- repepatCount=”indefinite” → 繰り返し移動が行われます、数値を入れるとその回数だけ行われます。
回転
<path id="line" d="M150 100H350" stroke="#37CBEC" stroke-width="10">
<animateTransform attributeName="transform" type="rotate" from="0 250 100" to="360 250 100" dur="4s" repeatCount="indefinite" />
</path>
オブジェクトの中心の点 (250 100)の位置を中心に、0度から360度回転するアニメーションが行われます。
useタグに書いてもOK
<symbol id="a">
<path id="line" d="M150 100H350" stroke="#37CBEC" stroke-width="10">
</path>
</symbol>
<use xlink:href="#a">
<animateTransform attributeName="transform" type="rotate" from="0 250 100" to="360 250 100" dur="4s" repeatCount="indefinite" />
</use>
useタグ内にanimateTransformタグを設置してもアニメーションします。
※symbolタグでpathを囲い、useタグでsymbolのidを指定して複数回呼びだすことができます。
cssプロパティでアニメーション
animateTransformでアニメーションを実装するよりもこちらのほうが、見やすく使い勝手がいいのでおすすめです。
#line {
transform-origin: calc(100% * 250 / 500) calc(100% * 100 / 500);
animation: animate 4s linear infinite;
}
@keyframes animate {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(100px, 100px);
}
}
2: アニメーションの起点を設定します。
線のオブジェクトの中心を、フレームの左上の原点(0, 0)からの割合で指定します。
3: 100% × 中心点 ÷ 全体 をx軸とy軸で指定しています。
※calc()を使うと、cssプロパティで計算することができます。
4: animationプロパティは以下のプロパティを一括指定することができます。
animation-name | アニメーション名 |
animation-duration | 所要時間 |
animation-delay | 開始時間を遅延 |
animation-direction | アニメーション再生の向き |
animation-fill-mode | delay時、再生後にどのスタイルを適用させるか |
animation-timing-function | 再生速度の変化 linear ease-in-out etc.. |
animation-play-state | アニメーションの paused / running |
animation-iteration-count | アニメーションが繰り返される回数、infiniteで無制限 |
animation: name duration timing count の順で指定しています。
アニメーションの作り方
@keyframes アニメーション名 その中に、6-14: 最初(0%)から最後(100%)までの割合で、プロパティを囲んでアニメーションを作ります。
12: 上の例は、最後の(100px, 100px) の位置まで水平移動するアニメーションになっています。
transformプロパティ
translate(100px, 100px); | 水平移動 |
rotate(360deg); | 回転 |
scale(1.5, 0); | 拡大・縮小 |
skew(45deg, 45deg); | x, y方向の歪み |
transformプロパティ以外にもstroke fill opacity 等のプロパティも使用できます。
関連記事
【CSS×figma】SVGストロークアニメーションを作成する
2023年01月10日
Figmaモーフィングでアニメーション
アンカーポイントの移動やハンドルを変更による、オブジェクトの変形をアニメーションしていきます。
① 線のオブジェクトをコピーして、線の中心にアンカーポイントを追加して② 曲線のオブジェクト(wave右上がり)を作成します。
③ フレームを右クリック > Copy/Paste as > Copy as SVG でコピーしたSVG から曲線のオブジェクト(右上がり)のpathタグを既存のsvgタグに追加します。
<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="0.5" width="499" height="499" stroke="black" />
<path id="line" d="M150 100H350" stroke="#37CBEC" stroke-width="10">
</path>
<path d="M150 250C150 250 184.983 308.244 250 250C315.017 191.756 350 250 350 250" stroke="#37CBEC" stroke-width="10" />
</svg>
7: 曲線のオブジェクト(wave右上がり)、このpathタグの中にanimateタグを入れてアニメーションさせます。
① 曲線のオブジェクトの中心のアンカーポイントのハンドルを変更して、曲線のオブジェクト(wave右下がり)に変形します、
変形できたら先程と同様に、② フレームを右クリック > Copy/Paste as > Copy as SVG でコピーしたSVG から曲線のオブジェクト(右下がり)のpathタグを用意します。
※変形前、変形後のアンカーポイントの数は同じでなくてはいけません。
ここで変形前(右上がり)のpathタグ(A)と変形後(右下がり)のpathタグ(B)を用意できたので、アニメーションさせていきます。
わかりやすいように変更前と変更後を並べて比較していきます。
<path d="M150 250C150 250 184.983 308.244 250 250C315.017 191.756 350 250 350 250" stroke="#37CBEC" stroke-width="10" />
<path stroke="#37CBEC" stroke-width="10">
<animate attributeName="d" begin="0" dur="2s" repeatCount="indefinite"
values="M150 250C150 250 184.983 308.244 250 250C315.017 191.756 350 250 350 250;
M150 250C150 250 198.636 187.174 250 250C301.364 312.826 350 250 350 250;
M150 250C150 250 184.983 308.244 250 250C315.017 191.756 350 250 350 250
" />
</path>
3: pathタグの d属性 を取り除き、4: animateタグの values属性 で指定しています。
- attributeName=”d” → d属性に対してアニメーション
- values → 5: A(wave右上がり) ;(セミコロン) → 6: B(wave右下がり) ;(セミコロン) → 7: A(wave右上がり) と順にdの値を指定
- begin → 開始時間を0に指定、その他マウスイベント(click, mouseover)や他アニメーションの状態(#id.end, #id.start)を指定、セミコロンで区切って複数指定する事もできる。(0; click)
- end → 停止時間を指定、その他マウスイベント(click, mouseover)や他アニメーションの状態(#id.end, #id.start)を指定
- dur → 所要時間
- repeatCount → アニメーションが繰り返される回数、indefiniteで無制限
- fill → 終了時どのスタイルが適用されるか、開始時 remove | 終了時 freeze
モーションパス
オブジェクトがオブジェクトに沿って動くアニメーションを作成します。
モーションパス用のオブジェクトを作成して、先程作ったwaveオブジェクトに沿って動かしていきます。
① フレームの原点を基準にアニメーションするので、星オブジェクト作成後、中心をフレームの原点に合わせた状態で、② フレームを右クリック > Copy/Paste as > Copy as SVG svgのコピーから、星オブジェクトのpathタグを用意します。
<path id="wave" stroke="#37CBEC" stroke-width="10">
<animate id="wave1" attributeName="d" begin="0" dur="2s" repeatCount="indefinite"
values="M150 250C150 250 184.983 308.244 250 250C315.017 191.756 350 250 350 250;
M150 250C150 250 198.636 187.174 250 250C301.364 312.826 350 250 350 250;
M150 250C150 250 184.983 308.244 250 250C315.017 191.756 350 250 350 250
" />
</path>
<path d="M0 -25L5.61285 -7.72543H23.7764L9.08178 2.95085L14.6946 20.2254L0 9.54915L-14.6946 20.2254L-9.08178 2.95085L-23.7764 -7.72543H-5.61285L0 -25Z" fill="#F0C964">
<animateMotion dur="5s" repeatCount="indefinite" repeatCount="indefinite" keyPoints="0;0.5;1" keyTimes="0;0.3;1" calcMode="linear" rotate="auto">
<mpath xlink:href="#wave"></mpath>
</animateMotion>
</path>
1: waveオブジェクトに idを追加します。
9-13: 星オブジェクトのpathタグの中にanimateMotionタグを追加して、11: 更にmpathタグで対象のオブジェクトのidを指定ます。
- rotate=”auto” → オブジェクトの傾きに沿って対象のオブジェクトが傾きます。初期値 0
- keyPoints=”0; 0.5; 1″ keyTimes=”0; 0.3; 1″ calcMode=”linear” → 開始 0から終了1までのアニメーションの速度を指定します。例は、中間点(0.5)に、1.5秒(0.3 × 5s(全体))で通過して3.5秒で終了点まで到達するように指定されています。keyPointsとkeyTimesの数は同数でなければいけません。
マスク
あるオブジェクト(mask)と重なる部分のみを表示させる事ができます。
① waveオブジェクトの中間周辺を覆うようにオブジェクトを作成します。
② フレームを右クリック > Copy/Paste as > Copy as SVG でコピーしたSVG から四角のオブジェクトのpathタグ飲みを既存のSVGにコピーします。
追加したオブジェクトをmaskにして星のオブジェクトがその範囲のみ見えるようにしていきます。
<g mask="url(#rect)">
<path d="M0 -25L5.61285 -7.72543H23.7764L9.08178 2.95085L14.6946 20.2254L0 9.54915L-14.6946 20.2254L-9.08178 2.95085L-23.7764 -7.72543H-5.61285L0 -25Z" fill="#F0C964">
<animateMotion dur="5s" repeatCount="indefinite" keyPoints="0;0.5;1" keyTimes="0;0.3;1" calcMode="linear" rotate="auto">
<mpath xlink:href="#wave"></mpath>
</animateMotion>
</path>
</g>
<mask id="rect">
<rect x="198.636" y="155.101" width="96.2207" height="186.027" fill="#E25656" />
</mask>
maskを作成する
10: 追加したオブジェクトのpathタグ
このオブジェクトをmaskにする場合、9-11: maskタグで囲いidを指定します。
maskを適用させる
1-7: 星のオブジェクトのpathタグをg(group)タグで囲ってmaskを指定します。
mask="url(#rect)"
交差部分のみ表示されているのがわかります。
- style=”mask-type: luminance;” → 輝度マスクが適用されます。マスクが白に近づくほどオブジェクトがはっきり表示され、黒だと表示されません。例の場合は中間色なので透過して表示されています。
- style=”mask-type: alpha;” → アルファマスクが適用されます。マスクが不透明(opacity: 1)に近づくほどオブジェクトがはっきり表示され、透明(opacity: 0;)だと表示されません。
以上figmaでオブジェクトを作成して、web上で表示させそれをアニメーションする方法でした。
全体のコード
<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" y="0.5" width="499" height="499" stroke="black" />
<path id="line" d="M150 100H350" stroke="#37CBEC" stroke-width="10">
</path>
<!-- <path d="M150 250C150 250 184.983 308.244 250 250C315.017 191.756 350 250 350 250" stroke="#37CBEC" stroke-width="10" /> -->
<path id="wave" stroke="#37CBEC" stroke-width="10">
<animate attributeName="d" begin="0" dur="2s" repeatCount="indefinite" values="M150 250C150 250 184.983 308.244 250 250C315.017 191.756 350 250 350 250;
M150 250C150 250 198.636 187.174 250 250C301.364 312.826 350 250 350 250;
M150 250C150 250 184.983 308.244 250 250C315.017 191.756 350 250 350 250
" />
</path>
<g mask="url(#rect)">
<path d="M0 -25L5.61285 -7.72543H23.7764L9.08178 2.95085L14.6946 20.2254L0 9.54915L-14.6946 20.2254L-9.08178 2.95085L-23.7764 -7.72543H-5.61285L0 -25Z" fill="#F0C964">
<animateMotion dur="5s" repeatCount="indefinite" keyPoints="0;0.5;1" keyTimes="0;0.3;1" calcMode="linear" rotate="auto">
<mpath xlink:href="#wave"></mpath>
</animateMotion>
</path>
</g>
<mask id="rect" style="mask-type: luminance;">
<rect x="198.636" y="155.101" width="96.2207" height="186.027" fill="#ccc" />
</mask>
</svg>
#line {
transform-origin: calc(100% * 250 / 500) calc(100% * 100 / 500);
/* animation: animate 4s linear 1; */
}
@keyframes animate {
100% {
/* transform: translate(100px, 100px); */
/* transform: rotate(360deg); */
/* transform: scale(1.5, 0); */
/* transform: skew(100deg); */
}
}