Skip to content

Commit 983cb4a

Browse files
sdrasbencodezen
andauthored
State Transitions Page Revamp (vuejs#260)
* update state examples, remove one * compose components * Update src/guide/transitions-state.md Co-authored-by: Ben Hong <[email protected]> * Update src/guide/transitions-state.md Co-authored-by: Ben Hong <[email protected]> Co-authored-by: Ben Hong <[email protected]>
1 parent 7c0d239 commit 983cb4a

File tree

1 file changed

+52
-132
lines changed

1 file changed

+52
-132
lines changed

src/guide/transitions-state.md

Lines changed: 52 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -52,104 +52,27 @@ Vue.createApp(Demo).mount('#animated-number-demo')
5252
</p>
5353
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
5454

55-
When you update the number, the change is animated below the input. This makes for a nice demo, but what about something that isn't directly stored as a number, like any valid CSS color for example? Here's how we could accomplish this with [Tween.js](https://github.com/tweenjs/tween.js) and [Color.js](https://github.com/brehaut/color-js):
56-
57-
```html
58-
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
59-
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
60-
61-
<div id="example-7">
62-
<input
63-
v-model="colorQuery"
64-
v-on:keyup.enter="updateColor"
65-
placeholder="Enter a color"
66-
/>
67-
<button v-on:click="updateColor">Update</button>
68-
<p>Preview:</p>
69-
<span
70-
v-bind:style="{ backgroundColor: tweenedCSSColor }"
71-
class="example-7-color-preview"
72-
></span>
73-
<p>{{ tweenedCSSColor }}</p>
74-
</div>
75-
```
76-
77-
```js
78-
var Color = net.brehaut.Color
79-
80-
new Vue({
81-
el: '#example-7',
82-
data: {
83-
colorQuery: '',
84-
color: {
85-
red: 0,
86-
green: 0,
87-
blue: 0,
88-
alpha: 1
89-
},
90-
tweenedColor: {}
91-
},
92-
created: function() {
93-
this.tweenedColor = Object.assign({}, this.color)
94-
},
95-
watch: {
96-
color: function() {
97-
function animate() {
98-
if (TWEEN.update()) {
99-
requestAnimationFrame(animate)
100-
}
101-
}
102-
103-
new TWEEN.Tween(this.tweenedColor).to(this.color, 750).start()
104-
105-
animate()
106-
}
107-
},
108-
computed: {
109-
tweenedCSSColor: function() {
110-
return new Color({
111-
red: this.tweenedColor.red,
112-
green: this.tweenedColor.green,
113-
blue: this.tweenedColor.blue,
114-
alpha: this.tweenedColor.alpha
115-
}).toCSS()
116-
}
117-
},
118-
methods: {
119-
updateColor: function() {
120-
this.color = new Color(this.colorQuery).toRGB()
121-
this.colorQuery = ''
122-
}
123-
}
124-
})
125-
```
126-
127-
```css
128-
.example-7-color-preview {
129-
display: inline-block;
130-
width: 50px;
131-
height: 50px;
132-
}
133-
```
134-
135-
TODO: put in example
55+
When you update the number, the change is animated below the input.
13656

13757
## Dynamic State Transitions
13858

13959
As with Vue's transition components, the data backing state transitions can be updated in real time, which is especially useful for prototyping! Even using a simple SVG polygon, you can achieve many effects that would be difficult to conceive of until you've played with the variables a little.
14060

141-
TODO: put in example
142-
143-
See [this example](https://codesandbox.io/s/github/vuejs/vuejs.org/tree/master/src/v2/examples/vue-20-dynamic-state-transitions) for the complete code behind the above demo.
61+
<p class="codepen" data-height="500" data-theme-id="39028" data-default-tab="js,result" data-user="Vue" data-slug-hash="a8e00648d4df6baa1b19fb6c31c8d17e" data-preview="true" style="height: 493px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Updating SVG">
62+
<span>See the Pen <a href="https://codepen.io/team/Vue/pen/a8e00648d4df6baa1b19fb6c31c8d17e">
63+
Updating SVG</a> by Vue (<a href="https://codepen.io/Vue">@Vue</a>)
64+
on <a href="https://codepen.io">CodePen</a>.</span>
65+
</p>
66+
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
14467

14568
## Organizing Transitions into Components
14669

14770
Managing many state transitions can quickly increase the complexity of a Vue instance or component. Fortunately, many animations can be extracted out into dedicated child components. Let's do this with the animated integer from our earlier example:
14871

14972
```html
150-
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
73+
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>
15174

152-
<div id="example-8">
75+
<div id="app">
15376
<input v-model.number="firstNumber" type="number" step="20" /> +
15477
<input v-model.number="secondNumber" type="number" step="20" /> = {{ result }}
15578
<p>
@@ -161,13 +84,22 @@ Managing many state transitions can quickly increase the complexity of a Vue ins
16184
```
16285

16386
```js
164-
// This complex tweening logic can now be reused between
165-
// any integers we may wish to animate in our application.
166-
// Components also offer a clean interface for configuring
167-
// more dynamic transitions and complex transition
168-
// strategies.
169-
Vue.component('animated-integer', {
170-
template: '<span>{{ tweeningValue }}</span>',
87+
const app = Vue.createApp({
88+
data() {
89+
return {
90+
firstNumber: 20,
91+
secondNumber: 40
92+
}
93+
},
94+
computed: {
95+
result() {
96+
return this.firstNumber + this.secondNumber
97+
}
98+
}
99+
})
100+
101+
app.component('animated-integer', {
102+
template: '<span>{{ fullValue }}</span>',
171103
props: {
172104
value: {
173105
type: Number,
@@ -179,55 +111,43 @@ Vue.component('animated-integer', {
179111
tweeningValue: 0
180112
}
181113
},
182-
watch: {
183-
value(newValue, oldValue) {
184-
this.tween(oldValue, newValue)
114+
computed: {
115+
fullValue() {
116+
return Math.floor(this.tweeningValue)
185117
}
186118
},
187-
mounted() {
188-
this.tween(0, this.value)
189-
},
190119
methods: {
191-
tween(startValue, endValue) {
192-
var vm = this
193-
function animate() {
194-
if (TWEEN.update()) {
195-
requestAnimationFrame(animate)
196-
}
197-
}
198-
199-
new TWEEN.Tween({ tweeningValue: startValue })
200-
.to({ tweeningValue: endValue }, 500)
201-
.onUpdate(function() {
202-
vm.tweeningValue = this.tweeningValue.toFixed(0)
203-
})
204-
.start()
205-
206-
animate()
207-
}
208-
}
209-
})
210-
211-
// All complexity has now been removed from the main Vue instance!
212-
new Vue({
213-
el: '#example-8',
214-
data() {
215-
return {
216-
firstNumber: 20,
217-
secondNumber: 40
120+
tween(newValue, oldValue) {
121+
gsap.to(this.$data, {
122+
duration: 0.5,
123+
tweeningValue: newValue,
124+
ease: 'sine'
125+
})
218126
}
219127
},
220-
computed: {
221-
result() {
222-
return this.firstNumber + this.secondNumber
128+
watch: {
129+
value(newValue, oldValue) {
130+
this.tween(newValue, oldValue)
223131
}
132+
},
133+
mounted() {
134+
this.tween(this.value, 0)
224135
}
225136
})
137+
138+
app.mount('#app')
226139
```
227140

228-
TODO: put in example
141+
<p class="codepen" data-height="300" data-theme-id="39028" data-default-tab="js,result" data-user="Vue" data-slug-hash="e9ef8ac7e32e0d0337e03d20949b4d17" data-preview="true" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="State Transition Components">
142+
<span>See the Pen <a href="https://codepen.io/team/Vue/pen/e9ef8ac7e32e0d0337e03d20949b4d17">
143+
State Transition Components</a> by Vue (<a href="https://codepen.io/Vue">@Vue</a>)
144+
on <a href="https://codepen.io">CodePen</a>.</span>
145+
</p>
146+
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
147+
148+
Now we can compose multiple states with these child components. It's exciting- we can use any combination of transition strategies that have been covered on this page, along with those offered by Vue's [built-in transition system](transitions.html). Together, there are very few limits to what can be accomplished.
229149

230-
Within child components, we can use any combination of transition strategies that have been covered on this page, along with those offered by Vue's [built-in transition system](transitions.html). Together, there are very few limits to what can be accomplished.
150+
You can see how we could use this for data visualization, for physics effects, for character animations and interactions, the sky's the limit.
231151

232152
## Bringing Designs to Life
233153

@@ -237,5 +157,5 @@ Vue can help. Since SVGs are just data, we only need examples of what these crea
237157

238158
Sarah Drasner demonstrates this in the demo below, using a combination of timed and interactivity-driven state changes:
239159

240-
<p data-height="265" data-theme-id="light" data-slug-hash="YZBGNp" data-default-tab="result" data-user="sdras" data-embed-version="2" data-pen-title="Vue-controlled Wall-E" class="codepen">See the Pen <a href="https://codepen.io/sdras/pen/YZBGNp/">Vue-controlled Wall-E</a> by Sarah Drasner (<a href="https://codepen.io/sdras">@sdras</a>) on <a href="https://codepen.io">CodePen</a>.</p>
160+
<p data-height="400" data-theme-id="light" data-slug-hash="YZBGNp" data-default-tab="result" data-user="sdras" data-embed-version="2" data-pen-title="Vue-controlled Wall-E" class="codepen">See the Pen <a href="https://codepen.io/sdras/pen/YZBGNp/">Vue-controlled Wall-E</a> by Sarah Drasner (<a href="https://codepen.io/sdras">@sdras</a>) on <a href="https://codepen.io">CodePen</a>.</p>
241161
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

0 commit comments

Comments
 (0)