Skip to content

Commit 7837682

Browse files
committed
feat(newtons-cradle): removes javascript and uses CSS only
1 parent 56bc3ad commit 7837682

File tree

2 files changed

+69
-58
lines changed

2 files changed

+69
-58
lines changed
+32-28
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,65 @@
1-
<script setup lang="ts">
2-
import { ref, onMounted } from 'vue'
3-
4-
const leftball = ref(true)
5-
6-
onMounted(() => {
7-
setInterval(() => {
8-
leftball.value = !leftball.value
9-
}, 1100)
10-
})
11-
</script>
1+
<script setup lang="ts"></script>
122

133
<template>
144
<div class="flex flex-row">
15-
<div class="flex flex-col grow">
16-
<div class="w-full h-2 bg-black rounded-full p-2 relative top-1"></div>
17-
<div class="flex flex-row">
18-
<div :class="['flex flex-col items-center', { leftball }]">
19-
<div class="flex bg-black w-1 h-32"></div>
20-
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
21-
</div>
22-
<div v-for="index in 5" :key="index">
23-
<div class="flex flex-col items-center">
5+
<div class="flex flex-row grow">
6+
<div
7+
class="flex h-full bg-black w-2 rotate-15 rounded-full items-center justify-center"
8+
></div>
9+
<div class="flex flex-col">
10+
<div class="w-full h-2 bg-black rounded-full relative top-2"></div>
11+
<div class="flex flex-row">
12+
<div class="flex flex-col items-center leftball">
13+
<div class="flex bg-black w-1 h-32"></div>
14+
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
15+
</div>
16+
<div v-for="index in 3" :key="index">
17+
<div class="flex flex-col items-center">
18+
<div class="flex bg-black w-1 h-32"></div>
19+
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
20+
</div>
21+
</div>
22+
<div class="flex flex-col items-center rightball">
2423
<div class="flex bg-black w-1 h-32"></div>
2524
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
2625
</div>
27-
</div>
28-
<div :class="['flex flex-col items-center', { rightball: !leftball }]">
29-
<div class="flex bg-black w-1 h-32"></div>
30-
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
3126
</div>
3227
</div>
28+
<div
29+
class="flex h-full bg-black w-2 -rotate-15 rounded-full items-center justify-center"
30+
></div>
3331
</div>
3432
</div>
3533
</template>
3634

3735
<style>
3836
.leftball {
39-
animation: leftball 1.2s cubic-bezier(0.5, 0, 0.5, 1) both;
37+
animation: leftball 2.5s cubic-bezier(0.5, 0, 0.5, 1) infinite both;
4038
transform: rotate(0deg);
4139
transform-origin: 50% 0%;
4240
}
4341
4442
.rightball {
45-
animation: rightball 1.2s cubic-bezier(0.5, 0, 0.5, 1) both;
43+
animation: rightball 2.5s cubic-bezier(0.5, 0, 0.5, 1) 1.25s infinite both;
4644
transform: rotate(0deg);
4745
transform-origin: 50% 0%;
4846
}
4947
5048
@keyframes leftball {
49+
25% {
50+
transform: rotate(75deg);
51+
}
5152
50% {
52-
transform: rotate(60deg);
53+
transform: rotate(0deg);
5354
}
5455
}
5556
5657
@keyframes rightball {
58+
25% {
59+
transform: rotate(-75deg);
60+
}
5761
50% {
58-
transform: rotate(-60deg);
62+
transform: rotate(0deg);
5963
}
6064
}
6165
</style>

src/views/NewtonsCradleView.vue

+37-30
Original file line numberDiff line numberDiff line change
@@ -12,67 +12,72 @@ const dependencies: IDependency[] = []
1212
const currentTab = ref('experiment')
1313
1414
const codeBlockString: string = `
15-
<script setup lang="ts">
16-
import { ref, onMounted } from 'vue'
17-
18-
const leftball = ref(true)
19-
20-
onMounted(() => {
21-
setInterval(() => {
22-
leftball.value = !leftball.value
23-
}, 1100)
24-
})
25-
<\/script>
15+
<script setup lang="ts"><\/script>
2616
2717
<template>
2818
<div class="flex flex-row">
29-
<div class="flex flex-col grow">
30-
<div class="w-full h-2 bg-black rounded-full p-2 relative top-1"></div>
31-
<div class="flex flex-row">
32-
<div :class="['flex flex-col items-center', { leftball }]">
33-
<div class="flex bg-black w-1 h-32"></div>
34-
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
35-
</div>
36-
<div v-for="index in 5" :key="index">
37-
<div class="flex flex-col items-center">
19+
<div class="flex flex-row grow">
20+
<div
21+
class="flex h-full bg-black w-2 rotate-15 rounded-full items-center justify-center"
22+
></div>
23+
<div class="flex flex-col">
24+
<div class="w-full h-2 bg-black rounded-full relative top-2"></div>
25+
<div class="flex flex-row">
26+
<div class="flex flex-col items-center leftball">
27+
<div class="flex bg-black w-1 h-32"></div>
28+
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
29+
</div>
30+
<div v-for="index in 3" :key="index">
31+
<div class="flex flex-col items-center">
32+
<div class="flex bg-black w-1 h-32"></div>
33+
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
34+
</div>
35+
</div>
36+
<div class="flex flex-col items-center rightball">
3837
<div class="flex bg-black w-1 h-32"></div>
3938
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
4039
</div>
41-
</div>
42-
<div :class="['flex flex-col items-center', { rightball: !leftball }]">
43-
<div class="flex bg-black w-1 h-32"></div>
44-
<div class="flex w-8 h-8 bg-black rounded-full border-2 border-black"></div>
4540
</div>
4641
</div>
42+
<div
43+
class="flex h-full bg-black w-2 -rotate-15 rounded-full items-center justify-center"
44+
></div>
4745
</div>
4846
</div>
4947
</template>
5048
5149
<style>
5250
.leftball {
53-
animation: leftball 1.2s cubic-bezier(0.5, 0, 0.5, 1) both;
51+
animation: leftball 2.5s cubic-bezier(0.5, 0, 0.5, 1) infinite both;
5452
transform: rotate(0deg);
5553
transform-origin: 50% 0%;
5654
}
5755
5856
.rightball {
59-
animation: rightball 1.2s cubic-bezier(0.5, 0, 0.5, 1) both;
57+
animation: rightball 2.5s cubic-bezier(0.5, 0, 0.5, 1) 1.25s infinite both;
6058
transform: rotate(0deg);
6159
transform-origin: 50% 0%;
6260
}
6361
6462
@keyframes leftball {
63+
25% {
64+
transform: rotate(75deg);
65+
}
6566
50% {
66-
transform: rotate(60deg);
67+
transform: rotate(0deg);
6768
}
6869
}
6970
7071
@keyframes rightball {
72+
25% {
73+
transform: rotate(-75deg);
74+
}
7175
50% {
72-
transform: rotate(-60deg);
76+
transform: rotate(0deg);
7377
}
7478
}
7579
</style>
80+
7681
`
7782
</script>
7883

@@ -81,12 +86,14 @@ onMounted(() => {
8186
<div class="flex flex-col mb-4 text-xl">
8287
<h2 class="text-5xl font-light mb-4">Newton's Cradle</h2>
8388
<div class="flex flex-col space-y-2">
84-
<span>Mimicking conservation of momentum with Vue animations</span>
89+
<span>Mimicking conservation of momentum with CSS animations.</span>
8590
<span>
8691
An animated version of the classic Newton's Cradle toy. An alternative would be to use
8792
something like
8893
<a href="https://brm.io/matter-js/" target="_blank" class="font-bold"> Matter.js </a> for
89-
a more realistic physics simulation.
94+
a more realistic physics simulation. This ended up using no Vue / Javascript and just CSS
95+
animations. Originally I used Vue to toggle the applied css classes to make the animation
96+
infinite but this can be done more easily using CSS.
9097
</span>
9198
<div class="flex flex-row space-x-2 py-4">
9299
<span>Dependencies:</span>

0 commit comments

Comments
 (0)