Add animation
This commit is contained in:
parent
7720230013
commit
65dd624c09
5 changed files with 164 additions and 2 deletions
17
app.vue
17
app.vue
|
|
@ -21,13 +21,14 @@
|
|||
<template v-else>
|
||||
{{ t('loading') }}
|
||||
</template>
|
||||
<ChickenRun :run-animation="chickenRun" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
// import Modal from "bootstrap/js/dist/modal";
|
||||
// import KonamiCode from "konami-code-js";
|
||||
import KonamiCode from "konami-code-js";
|
||||
// import Swal from "sweetalert2";
|
||||
import { defineComponent } from "vue";
|
||||
import type { RouteLocationNormalizedLoaded } from "vue-router";
|
||||
|
|
@ -43,13 +44,17 @@ export default defineComponent({
|
|||
route: RouteLocationNormalizedLoaded;
|
||||
activeBrand: TypeBrand|null;
|
||||
activeRange: TypeRange|null;
|
||||
chickenRun: boolean;
|
||||
konami: KonamiCode|null;
|
||||
} {
|
||||
return {
|
||||
timeout: undefined,
|
||||
loading: true,
|
||||
route: useRoute(),
|
||||
activeBrand: null,
|
||||
activeRange: null
|
||||
activeRange: null,
|
||||
chickenRun: false,
|
||||
konami: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -80,6 +85,14 @@ export default defineComponent({
|
|||
dataJson.fonts.forEach(font => this.injectFontFace(font.font_name, font.font));
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.konami = new KonamiCode(() => {
|
||||
this.$nextTick(() => {
|
||||
this.chickenRun = true;
|
||||
setTimeout(() => {this.chickenRun = false;}, 12000);
|
||||
});
|
||||
});
|
||||
},
|
||||
beforeUnmount() {
|
||||
clearTimeout(this.timeout);
|
||||
},
|
||||
|
|
|
|||
BIN
assets/pictures/chicken_run/chicken1.png
Normal file
BIN
assets/pictures/chicken_run/chicken1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
assets/pictures/chicken_run/chicken2.png
Normal file
BIN
assets/pictures/chicken_run/chicken2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
assets/pictures/chicken_run/chicken3.png
Normal file
BIN
assets/pictures/chicken_run/chicken3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
149
components/ChickenRun.vue
Normal file
149
components/ChickenRun.vue
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
<template>
|
||||
<div
|
||||
ref="container"
|
||||
:class="{
|
||||
'chicken-run position-absolute top-0 left-0 h-100 w-100': true,
|
||||
'd-none': !runAnimation.runAnimation
|
||||
}"
|
||||
>
|
||||
<div ref="chickenA">
|
||||
<img
|
||||
v-for="(i) of data.chickenMultiplier"
|
||||
:key="i"
|
||||
src="assets/pictures/chicken_run/chicken1.png"
|
||||
alt="Poulet 1"
|
||||
class="img-fluid chicken"
|
||||
>
|
||||
</div>
|
||||
<div ref="chickenB">
|
||||
<img
|
||||
v-for="(i) of data.chickenMultiplier"
|
||||
:key="i"
|
||||
src="assets/pictures/chicken_run/chicken2.png"
|
||||
alt="Poulet 2"
|
||||
class="img-fluid chicken"
|
||||
>
|
||||
</div>
|
||||
<div ref="chickenC">
|
||||
<img
|
||||
v-for="(i) of data.chickenMultiplier"
|
||||
:key="i"
|
||||
src="assets/pictures/chicken_run/chicken3.png"
|
||||
alt="Poulet 3"
|
||||
class="img-fluid chicken"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
function makeNewPosition() {
|
||||
const containerRect = container.value!.getBoundingClientRect();
|
||||
// Get viewport dimensions (remove the dimension of the div)
|
||||
const h = containerRect.height - 10;
|
||||
const w = containerRect.width - 10;
|
||||
|
||||
const nh = Math.floor(Math.random() * h);
|
||||
const nw = Math.floor(Math.random() * w);
|
||||
|
||||
return [nh, nw];
|
||||
|
||||
}
|
||||
|
||||
function animateDiv(target: HTMLElement) {
|
||||
const newq = makeNewPosition();
|
||||
const oldq = target.getBoundingClientRect();
|
||||
const speed = calcSpeed([oldq.top, oldq.left], newq);
|
||||
|
||||
const promise = Promise.all([target.animate({
|
||||
top: `${newq[0]}px`,
|
||||
left: `${newq[1]}px`
|
||||
}, speed).finished]);
|
||||
if(runAnimation.runAnimation) {
|
||||
promise.then(() => animateDiv(target));
|
||||
} else {
|
||||
data.runningAnimation = false;
|
||||
}
|
||||
}
|
||||
|
||||
function calcSpeed(prev: number[], next:number[]) {
|
||||
const x = Math.abs(prev[1] - next[1]);
|
||||
const y = Math.abs(prev[0] - next[0]);
|
||||
|
||||
const greatest = x > y ? x : y;
|
||||
const speed = Math.ceil(greatest / data.speedModifier);
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
function setRandomStartCoord(container: DOMRect, el: HTMLElement) {
|
||||
el.style.setProperty("top", `${Math.floor(Math.random() * container.height)}px`);
|
||||
el.style.setProperty("left", `${Math.floor(Math.random() * container.width)}px`);
|
||||
}
|
||||
|
||||
function animateElements(elements: NodeListOf<ChildNode>) {
|
||||
const containerRect = container.value!.getBoundingClientRect();
|
||||
(Array.from(elements))
|
||||
.filter((el) => el.nodeType !== Node.TEXT_NODE)
|
||||
.forEach((el) => {
|
||||
setRandomStartCoord(containerRect, el as HTMLElement);
|
||||
animateDiv(el as HTMLElement);
|
||||
});
|
||||
}
|
||||
|
||||
const data = reactive<{
|
||||
runningAnimation: boolean;
|
||||
speedModifier: number;
|
||||
chickenMultiplier: number;
|
||||
}>({
|
||||
runningAnimation: false,
|
||||
speedModifier: 0.6,
|
||||
chickenMultiplier: 1,
|
||||
});
|
||||
|
||||
const runAnimation = defineProps({
|
||||
runAnimation: {
|
||||
type:Boolean,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const container = ref<HTMLDivElement>();
|
||||
const chickenA = ref<HTMLDivElement>();
|
||||
const chickenB = ref<HTMLDivElement>();
|
||||
const chickenC = ref<HTMLDivElement>();
|
||||
|
||||
const animate = () => {
|
||||
if(!data.runningAnimation) {
|
||||
data.runningAnimation = true;
|
||||
data.chickenMultiplier = Math.floor(Math.random() * 4) + 1;
|
||||
nextTick(() => {
|
||||
animateElements(chickenA.value!.childNodes);
|
||||
animateElements(chickenB.value!.childNodes);
|
||||
animateElements(chickenC.value!.childNodes);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if(runAnimation.runAnimation) {
|
||||
animate();
|
||||
}
|
||||
|
||||
watch(runAnimation, () => {
|
||||
if (runAnimation.runAnimation) {
|
||||
animate();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.chicken-run {
|
||||
.chicken {
|
||||
width: 5vw;
|
||||
height: auto;
|
||||
position:fixed;
|
||||
top: 5rem;
|
||||
left: 5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Reference in a new issue