상태 트랜지션

카탈로그
  1. 1. 감시자를 이용한 상태 애니메이션
  2. 2. 동적 상태 트랜지션
  3. 3. 컴포넌트를 이용한 트랜지션 구성
  4. 4. 디자인에 생명을 불어넣기

Vue의 트랜지션 시스템은 진입, 진출 및 목록을 애니메이션으로 만드는 많은 간단한 방법을 제공하지만 데이터 자체에 대한 애니메이션은 어떻게 해야할까요?

  • 숫자와 계산
  • 색 표시
  • SVG노드의 위치
  • 엘리먼트의 크기 및 기타 속성

이들 모두는 이미 원시 숫자로 저장되어 있거나 숫자로 변환 될 수 있습니다. 그렇게하면 Vue의 반응성 및 컴포넌트 시스템과 함께 써드파티 라이브러리를 사용하여 트윈 상태로 상태 변경 사항을 애니메이션으로 만들 수 있습니다.

감시자를 이용한 상태 애니메이션

감시자를 사용하면 숫자 속성의 변경 사항을 다른 속성으로 애니메이션 할 수 있습니다. 처음에는 복잡해 보일 수도 있으므로 GreenSock을 사용하여 예제를 살펴 보겠습니다.

1
2
3
4
5
6
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>

<div id="animated-number-demo">
<input v-model.number="number" type="number" step="20">
<p>{{ animatedNumber }}</p>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
new Vue({
el: '#animated-number-demo',
data: {
number: 0,
tweenedNumber: 0
},
computed: {
animatedNumber: function() {
return this.tweenedNumber.toFixed(0);
}
},
watch: {
number: function(newValue) {
TweenLite.to(this.$data, 0.5, { tweenedNumber: newValue });
}
}
})

{{ animatedNumber }}

숫자를 갱신하면 변경 사항이 입력 아래에 애니메이션으로 표시됩니다. 이것은 멋진 멋져 보이지만, 예를 들어 유효한 CSS 색상과 같이 숫자로 직접 저장되지 않은 것은 어떻게 할까요? 다음은 Tween.jsColor.js를 추가하여 이를 수행하는 방법입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>
<script src="https://cdn.jsdelivr.net/npm/color-js@1.0.3"></script>

<div id="example-7">
<input
v-model="colorQuery"
v-on:keyup.enter="updateColor"
placeholder="Enter a color"
>
<button v-on:click="updateColor">Update</button>
<p>Preview:</p>
<span
v-bind:style="{ backgroundColor: tweenedCSSColor }"
class="example-7-color-preview"
></span>
<p>{{ tweenedCSSColor }}</p>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
var Color = net.brehaut.Color

new Vue({
el: '#example-7',
data: {
colorQuery: '',
color: {
red: 0,
green: 0,
blue: 0,
alpha: 1
},
tweenedColor: {}
},
created: function () {
this.tweenedColor = Object.assign({}, this.color)
},
watch: {
color: function () {
function animate () {
if (TWEEN.update()) {
requestAnimationFrame(animate)
}
}

new TWEEN.Tween(this.tweenedColor)
.to(this.color, 750)
.start()

animate()
}
},
computed: {
tweenedCSSColor: function () {
return new Color({
red: this.tweenedColor.red,
green: this.tweenedColor.green,
blue: this.tweenedColor.blue,
alpha: this.tweenedColor.alpha
}).toCSS()
}
},
methods: {
updateColor: function () {
this.color = new Color(this.colorQuery).toRGB()
this.colorQuery = ''
}
}
})
1
2
3
4
5
.example-7-color-preview {
display: inline-block;
width: 50px;
height: 50px;
}

Preview:

{{ tweenedCSSColor }}

동적 상태 트랜지션

Vue의 트랜지션 컴포넌트와 마찬가지로 데이터 백업 상태 트랜지션을 실시간으로 업데이트 할 수 있으므로 프로토 타이핑에 특히 유용합니다! 간단한 SVG 다각형을 사용해도, 변수를 조금씩 사용하기 전까지는 생각하기 어려운 많은 효과를 얻을 수 있습니다.

위 데모의 전체 코드는 이 fiddle 참조하십시오.

컴포넌트를 이용한 트랜지션 구성

여러 상태 트랜지션을 관리하면 Vue 인스턴스 또는 컴포넌트의 복잡성을 빠르게 높일 수 있습니다. 다행히도 많은 애니메이션을 전용 하위 컴포넌트로 추출 할 수 있습니다. 이전 예제의 숫자를 이용하는 애니메이션을 사용해 보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
<script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>

<div id="example-8">
<input v-model.number="firstNumber" type="number" step="20"> +
<input v-model.number="secondNumber" type="number" step="20"> =
{{ result }}
<p>
<animated-integer v-bind:value="firstNumber"></animated-integer> +
<animated-integer v-bind:value="secondNumber"></animated-integer> =
<animated-integer v-bind:value="result"></animated-integer>
</p>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// 이 복잡한 트위닝 로직은 이제 응용 프로그램에서
// 애니메이션을 적용하려는 숫자 사이에서 재사용 할 수 있습니다.
// 또한 컴포넌트는보다 동적인 트랜지션 및 복잡한 트랜지션 전략을
// 구성할 수 있는 깨끗한 인터페이스를 제공합니다.
Vue.component('animated-integer', {
template: '<span>{{ tweeningValue }}</span>',
props: {
value: {
type: Number,
required: true
}
},
data: function () {
return {
tweeningValue: 0
}
},
watch: {
value: function (newValue, oldValue) {
this.tween(oldValue, newValue)
}
},
mounted: function () {
this.tween(0, this.value)
},
methods: {
tween: function (startValue, endValue) {
var vm = this
function animate () {
if (TWEEN.update()) {
requestAnimationFrame(animate)
}
}

new TWEEN.Tween({ tweeningValue: startValue })
.to({ tweeningValue: endValue }, 500)
.onUpdate(function () {
vm.tweeningValue = this.tweeningValue.toFixed(0)
})
.start()

animate()
}
}
})

// 모든 Vue 인스턴스에서 모든 복잡성이 제거 되었습니다!
new Vue({
el: '#example-8',
data: {
firstNumber: 20,
secondNumber: 40
},
computed: {
result: function () {
return this.firstNumber + this.secondNumber
}
}
})
+ = {{ result }}

+ =

자식 컴포넌트 내에서, 이 페이지에서 다룬 트랜지션 전략과 Vue의 기본 제공 트랜지션 시스템에서 제공하는 트랜지션 전략을 조합하여 사용할 수 있습니다. 함께 사용할 할 수 있는 것에는 거의 제한이 없습니다.

디자인에 생명을 불어넣기

애니메이션을 추가하는 것은 생명을 불어 넣는 일 입니다. 불행하게도 디자이너가 만든 아이콘, 로고 및 마스코트들은 이미지나 정적 SVG입니다. 그래서 Github의 octocat, Twitter의 새 및 기타 로고들은 살아있는 것들과 유사하지만 살아 움직이지는 못합니다.

Vue가 도와줄 수 있습니다. SVG는 단순한 데이터일 뿐이므로 놀라거나, 생각할 때, 경고할때 어떻게 할 지 예시가 필요합니다. 그 다음 Vue는 데이터들을 트랜지션하여 환영페이지, 로딩 표시기, 알림을 감정적이고 매력적으로 만들 수 있습니다.

Sarah Drasner는 타이밍과 인터랙션 중심의 상태 변화를 조합하여 아래의 데모를 만들었습니다.

See the Pen Vue-controlled Wall-E by Sarah Drasner (@sdras) on CodePen.