Add simple 360 viewer

This commit is contained in:
2020-10-03 19:50:17 +03:00
parent c84a4e4e5f
commit b5a9aa9b0c
5 changed files with 111 additions and 6 deletions

View File

@@ -1 +1 @@
[{"name":"Album 1 name","description":"Album 2 description","protected":false,"coverFileName":"IMG_20200811_060850.jpg","photoDescription":{"IMG_20200811_060850.jpg":"Description 1","IMG_20200811_074445.jpg":"Description 2"},"folderName":"album_1","files":["IMG_20200811_060850.jpg","IMG_20200811_074445.jpg","IMG_20200811_080037.jpg","IMG_20200811_081746.jpg","IMG_20200811_084017.jpg"],"files_360":["photo.jpg"]}]
[{"name":"Album 1 name","description":"Album 2 description","protected":false,"coverFileName":"IMG_20200811_060850.jpg","photoDescription":{"IMG_20200811_060850.jpg":"Description 1","IMG_20200811_074445.jpg":"Description 2"},"folderName":"album_1","files":["IMG_20200811_060850.jpg","IMG_20200811_074445.jpg","IMG_20200811_080037.jpg","IMG_20200811_081746.jpg","IMG_20200811_084017.jpg"],"files_360":["360-Video-Featured-StudioBinder-Compressed.jpg","photo.jpg"]}]

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

View File

@@ -25,6 +25,9 @@ export default class Photo extends Vue {
@Prop({required: true})
public readonly album!: IAlbum;
@Prop({default: false})
public readonly t360!: boolean;
@Ref('element') public readonly element!: HTMLElement;
public height: string = '10px';
@@ -45,8 +48,9 @@ export default class Photo extends Vue {
}
get photoStyle() {
const folder = this.t360 ? "360_photos" : "photos";
return {
'background-image': `url('/pictures/albums/${this.album.folderName}/photos/${this.file}')`
'background-image': `url('/pictures/albums/${this.album.folderName}/${folder}/${this.file}')`
}
}
@@ -57,8 +61,12 @@ export default class Photo extends Vue {
}
onClick() {
if (this.t360) {
this.$emit('clickPhoto', this.album.files_360.indexOf(this.file));
} else {
this.$emit('clickPhoto', this.album.files.indexOf(this.file));
}
}
mounted() {
this.updateHeight();

1
src/types/vuejs-vr.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
declare module 'vuejs-vr';

View File

@@ -9,6 +9,11 @@
<Photo v-for="file in filesToShow" :key="file" :file="file" :album="album"
@clickPhoto="clickPhoto"></Photo>
</div>
<span>360*</span>
<div class="photos360" v-if="album !== null">
<Photo v-for="file in filesToShow360" :key="file" :file="file" :album="album"
@clickPhoto="clickPhoto360" :t360="true"></Photo>
</div>
</div>
<vue-gallery v-if="album !== null"
:options="options"
@@ -16,6 +21,14 @@
:index="index"
@close="index = null">
</vue-gallery>
<div class="pano-wrapper" v-if="index360 !== null">
<div class="pano-container">
<pano :source="source360"></pano>
</div>
<div class="pano-button pano-prev" @click="prev360"></div>
<div class="pano-button pano-next" @click="next360"></div>
<div class="pano-button pano-close" @click="index360 = null">×</div>
</div>
</div>
</template>
@@ -25,6 +38,8 @@ import { Vue, Component, Prop, Watch, Ref } from 'vue-property-decorator';
import VueGallery from 'vue-gallery';
import { Pano } from 'vuejs-vr';
import { StoreType } from '@/store';
import { IAlbum } from '@/store/albums/state';
@@ -38,13 +53,18 @@ import Photo from '@/components/Photo.vue';
LeftBlock,
Photo,
VueGallery,
Pano,
}
})
export default class AlbumPage extends Vue {
public filesToShow: string[] = [];
public filesToShow360: string[] = [];
public index: number | null = null;
public index360: number | null = null;
public options: object = {};
get album(): IAlbum | null {
@@ -98,7 +118,11 @@ export default class AlbumPage extends Vue {
this.album.files.forEach((item, index) => {
setTimeout(() => this.filesToShow.push(item), 300 * index);
})
});
this.album.files_360.forEach((item, index) => {
setTimeout(() => this.filesToShow360.push(item), 300 * index);
});
}
@Watch('album')
@@ -110,6 +134,38 @@ export default class AlbumPage extends Vue {
this.index = index;
}
clickPhoto360(index: number) {
this.index360 = index;
}
get source360() {
if (this.index360 === null)
return '';
const filename = this.album!.files_360[this.index360];
return `/pictures/albums/${this.album!.folderName}/360_photos/${filename}`;
}
next360() {
const newIndex = this.index360! + 1;
if (newIndex >= this.album!.files_360.length) {
this.index360 = 0;
} else {
this.index360 = newIndex;
}
}
prev360() {
const newIndex = this.index360! - 1;
if (newIndex! < 0) {
this.index360 = this.album!.files_360.length - 1;
} else {
this.index360 = newIndex;
}
}
mounted() {
this.updateFiles();
@@ -124,6 +180,47 @@ export default class AlbumPage extends Vue {
vertical-align: top;
}
.pano-wrapper {
position: fixed;
top: 0;
width: 100%;
height: 100%;
z-index: 200;
background-color: rgba(0, 0, 0, 0.9);
}
.pano-container {
margin-top: 5%;
margin-left: 5%;
width: 90%;
height: 85%;
}
.pano-button {
position: fixed;
padding: 1em;
color: white;
}
.pano-prev {
top: 45%;
left: -3%;
font-size: 3em;
}
.pano-next {
top: 45%;
right: -3%;
font-size: 3em;
}
.pano-close {
top: -3%;
right: -1%;
font-size: 2em;
}
@media (max-width: 961px) {
.photos-wrapper {
width: calc(100vw);
@@ -137,12 +234,11 @@ export default class AlbumPage extends Vue {
}
}
.photos {
.photos, .photos360 {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
</style>
<style>