|
@@ -1,15 +1,195 @@
|
|
|
-<script lang="ts">
|
|
|
-import {defineComponent} from 'vue'
|
|
|
+<script>
|
|
|
+import { defineComponent } from 'vue'
|
|
|
+import Player from '@/components/Player.vue'
|
|
|
+import { config } from '@/main.js'
|
|
|
+import { animate, createSpring } from 'animejs'
|
|
|
|
|
|
export default defineComponent({
|
|
|
-name: "VideoFeed"
|
|
|
+ name: 'VideoFeed',
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ player1: null,
|
|
|
+ player2: null,
|
|
|
+ config,
|
|
|
+ animating: false,
|
|
|
+ feedIndex: 0,
|
|
|
+ currentPlayer: "player1",
|
|
|
+ stiffness: 550,
|
|
|
+ damping: 15
|
|
|
+ }
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ feed: {
|
|
|
+ type: Object,
|
|
|
+ required: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ scrollDown() {
|
|
|
+ if(this.animating) return;
|
|
|
+ if (this.feedIndex >= this.feed.length - 1) {
|
|
|
+ console.log("Reached end of feed");
|
|
|
+ this.animating = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.animating = true;
|
|
|
+ const screenHeight = window.innerHeight;
|
|
|
+ const inactivePlayer = this.currentPlayer === "player1" ? ".player2" : ".player1";
|
|
|
+ const activePlayer = this.currentPlayer === "player1" ? ".player1" : ".player2";
|
|
|
+ const nextIndex = this.feedIndex + 1; // calculate this early!
|
|
|
+
|
|
|
+ // Move the inactive player down
|
|
|
+ animate(inactivePlayer, {
|
|
|
+ translateY: screenHeight,
|
|
|
+ duration: 0
|
|
|
+ });
|
|
|
+
|
|
|
+ if (this.currentPlayer === "player1") {
|
|
|
+ this.player2 = this.feed[nextIndex];
|
|
|
+ } else {
|
|
|
+ this.player1 = this.feed[nextIndex];
|
|
|
+ }
|
|
|
+
|
|
|
+ // animate players
|
|
|
+ animate(activePlayer, {
|
|
|
+ translateY: [0, -screenHeight],
|
|
|
+ duration: 500,
|
|
|
+ ease: createSpring({stiffness: this.stiffness, damping: this.damping})
|
|
|
+ });
|
|
|
+
|
|
|
+ animate(inactivePlayer, {
|
|
|
+ translateY: [screenHeight, 0],
|
|
|
+ duration: 500,
|
|
|
+ ease: createSpring({stiffness: this.stiffness, damping: this.damping})
|
|
|
+ }).then(() => {
|
|
|
+ const nextPlayer = this.currentPlayer === "player1" ? "player2" : "player1";
|
|
|
+ this.feedIndex = nextIndex;
|
|
|
+ this.currentPlayer = nextPlayer;
|
|
|
+ this.animating = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ scrollUp() {
|
|
|
+ if(this.animating) return;
|
|
|
+ if (this.feedIndex <= 0) {
|
|
|
+ console.log("Reached beginning of feed");
|
|
|
+ this.animating = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.animating = true;
|
|
|
+ const screenHeight = window.innerHeight;
|
|
|
+ const inactivePlayer = this.currentPlayer === "player1" ? ".player2" : ".player1";
|
|
|
+ const activePlayer = this.currentPlayer === "player1" ? ".player1" : ".player2";
|
|
|
+ const nextIndex = this.feedIndex - 1; // calculate this early!
|
|
|
+
|
|
|
+ // Move the inactive player up
|
|
|
+ animate(inactivePlayer, {
|
|
|
+ translateY: -screenHeight,
|
|
|
+ duration: 0
|
|
|
+ });
|
|
|
+
|
|
|
+ if (this.currentPlayer === "player1") {
|
|
|
+ this.player2 = this.feed[nextIndex];
|
|
|
+ } else {
|
|
|
+ this.player1 = this.feed[nextIndex];
|
|
|
+ }
|
|
|
+
|
|
|
+ // animate players
|
|
|
+ animate(activePlayer, {
|
|
|
+ translateY: [0, screenHeight],
|
|
|
+ duration: 500,
|
|
|
+ ease: createSpring({stiffness: this.stiffness, damping: this.damping})
|
|
|
+ });
|
|
|
+
|
|
|
+ animate(inactivePlayer, {
|
|
|
+ translateY: [-screenHeight, 0],
|
|
|
+ duration: 500,
|
|
|
+ ease: createSpring({stiffness: this.stiffness, damping: this.damping})
|
|
|
+ }).then(() => {
|
|
|
+ const nextPlayer = this.currentPlayer === "player1" ? "player2" : "player1";
|
|
|
+ this.feedIndex = nextIndex;
|
|
|
+ this.currentPlayer = nextPlayer;
|
|
|
+ this.animating = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ handleScroll(event) {
|
|
|
+ if(this.animating) return;
|
|
|
+
|
|
|
+ if(event.deltaY > 0) {
|
|
|
+ this.scrollDown();
|
|
|
+ } else {
|
|
|
+ this.scrollUp();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ created () {
|
|
|
+ // initial setup for players
|
|
|
+ this.player1 = this.feed[this.feedIndex];
|
|
|
+ this.player2 = this.feed[this.feedIndex + 1];
|
|
|
+ document.addEventListener("DOMContentLoaded", () => {
|
|
|
+ animate(".player2", {
|
|
|
+ translateY: window.innerHeight,
|
|
|
+ duration: 1
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ document.addEventListener("wheel", this.handleScroll);
|
|
|
+ },
|
|
|
+ components: { Player },
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
+ <div id="player-container">
|
|
|
+ <Player
|
|
|
+ class-name="player1 player-wrapper"
|
|
|
+ :video="player1?.id ?? 1"
|
|
|
+ :key="player1?.id ?? 1"
|
|
|
+ :information="{
|
|
|
+ title: player1?.title ?? '',
|
|
|
+ description: player1?.description ?? '',
|
|
|
+ likes: player1?.likes ?? 13242,
|
|
|
+ dislikes: player1?.dislikes ?? 13242,
|
|
|
+ comments: player1?.comments ?? 13242,
|
|
|
+ shares: player1?.shares ?? 13242,
|
|
|
+ author: player1?.author?.username ?? 'john clapper',
|
|
|
+ authorAvatar: `${config.serverURL}/account/${player1?.author?.id ?? 1}/picture`,
|
|
|
+ }"
|
|
|
+ />
|
|
|
|
|
|
+ <Player
|
|
|
+ class-name="player2 player-wrapper"
|
|
|
+ :video="player2?.id ?? 1"
|
|
|
+ :key="player2?.id ?? 1"
|
|
|
+ :information="{
|
|
|
+ title: player2?.title ?? '',
|
|
|
+ description: player2?.description ?? '',
|
|
|
+ likes: player2?.likes ?? 13242,
|
|
|
+ dislikes: player2?.dislikes ?? 13242,
|
|
|
+ comments: player2?.comments ?? 13242,
|
|
|
+ shares: player2?.shares ?? 13242,
|
|
|
+ author: player2?.author?.username ?? 'johnclapper',
|
|
|
+ authorAvatar: `${config.serverURL}/account/${player2?.author?.id ?? 1}/picture`,
|
|
|
+ }"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<style scoped>
|
|
|
+.player-wrapper {
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ height: 100vh;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.player1 {
|
|
|
+ position: absolute;
|
|
|
+}
|
|
|
|
|
|
+.player2 {
|
|
|
+ position: absolute;
|
|
|
+}
|
|
|
</style>
|