Skip to content

Commit

Permalink
Product images carousel
Browse files Browse the repository at this point in the history
  • Loading branch information
royduin committed Aug 17, 2021
1 parent 647334e commit 91e4997
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 51 deletions.
36 changes: 29 additions & 7 deletions resources/js/components/Product/Images.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
<script>
export default {
data: () => ({
images: false,
opened: false,
images: config.product.images,
active: 0,
zoomed: false,
}),
render() {
return this.$scopedSlots.default({
images: this.images,
opened: this.opened,
toggle: this.toggle,
active: this.active,
zoomed: this.zoomed,
toggleZoom: this.toggleZoom,
change: this.change,
})
},
Expand All @@ -25,9 +28,28 @@
},
methods: {
toggle(index, event) {
this.opened = this.opened === false ? index : false
event.currentTarget.firstChild.src = event.currentTarget.href
toggleZoom() {
this.zoomed = !this.zoomed
if (this.zoomed) {
document.addEventListener('keyup', this.keyPressed)
} else {
document.removeEventListener('keyup', this.keyPressed)
}
},
keyPressed() {
if (event.keyCode == 37 && this.active) { // left
this.active--
} else if (event.keyCode == 39 && this.active != this.images.length-1) { // right
this.active++
} else if (event.keyCode == 27) { // esc
this.toggleZoom()
}
},
change(index) {
this.active = index
},
}
}
Expand Down
4 changes: 2 additions & 2 deletions resources/views/product/overview.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
<h1 class="font-bold text-4xl mb-5">{{ $product->name }}</h1>

<div class="flex flex-col sm:flex-row mb-5">
<div class="sm:w-2/3 sm:mr-5">
<div class="sm:w-1/2 sm:mr-5">
@include('rapidez::product.partials.images')
</div>
<div class="sm:w-1/3">
<div class="sm:w-1/2">
<div class="p-3 my-5 sm:mt-0 bg-gray-200 rounded prose prose-green max-w-none">
{!! $product->description !!}
</div>
Expand Down
86 changes: 44 additions & 42 deletions resources/views/product/partials/images.blade.php
Original file line number Diff line number Diff line change
@@ -1,59 +1,61 @@
<images>
<div slot-scope="{ images, opened, toggle }">
<div v-if="!images" class="{{ in_array(count($product->images), [0, 1]) ? '' : 'grid gap-3 grid-cols-2' }}">
@forelse($product->images as $image)
<a
href="{{ config('rapidez.media_url').'/catalog/product'.$image }}"
class="flex items-center justify-center border rounded p-5 {{ count($product->images) == 1 ? 'h-96' : 'h-48 sm:h-64 md:h-80 lg:h-96' }}"
:class="{ 'fixed inset-0 bg-white !h-full z-10 cursor-[zoom-out]': opened === {{ $loop->index }} }"
v-on:click.prevent="toggle({{ $loop->index }}, $event)"
>
<picture class="contents">
<source srcset="/storage/resizes/450/catalog/product{{ $image }}.webp" type="image/webp">
<img
src="/storage/resizes/450/catalog/product{{ $image }}"
alt="{{ $product->name }}"
class="max-h-full max-w-full"
loading="lazy"
/>
</picture>
</a>
@empty
<x-rapidez::no-image class="rounded h-96"/>
@endforelse
<images v-cloak>
<div slot-scope="{ images, active, zoomed, toggleZoom, change }">
<div class="relative" v-if="images.length">
<a
:href="config.media_url + '/catalog/product' + images[active]"
class="flex items-center justify-center"
:class="zoomed ? 'fixed inset-0 bg-white !h-full z-10 cursor-[zoom-out]' : 'border rounded p-5 h-[450px]'"
v-on:click.prevent="toggleZoom"
>
<picture v-if="!zoomed" class="contents">
<source :srcset="'/storage/resizes/450/catalog/product' + images[active] + '.webp'" type="image/webp">
<img
:src="'/storage/resizes/450/catalog/product' + images[active]"
alt="{{ $product->name }}"
class="max-h-full max-w-full"
loading="lazy"
/>
</picture>
<img
v-else
:src="config.media_url + '/catalog/product' + images[active]"
alt="{{ $product->name }}"
class="max-h-full max-w-full"
loading="lazy"
/>
</a>

<button class="top-1/2 z-10 -translate-y-1/2 left-3" :class="zoomed ? 'fixed' : 'absolute'" v-if="active" v-on:click="change(active-1)">
<x-heroicon-s-chevron-left class="h-8 w-8"/>
</button>

<button class="top-1/2 z-10 -translate-y-1/2 right-3" :class="zoomed ? 'fixed' : 'absolute'" v-if="active != images.length-1" v-on:click="change(active+1)">
<x-heroicon-s-chevron-right class="h-8 w-8"/>
</button>
</div>
<x-rapidez::no-image v-else class="rounded h-96"/>

{{--
We've some duplication here and that's because on the first load we want to display the
images as fast as possible. But when we change product options they've to change.
So the first load we use Blade and when options change we use Vue.
--}}
<div v-cloak v-else :class="[0, 1].includes(images.length) ? '' : 'grid gap-3 grid-cols-2'">
<div v-if="images.length > 1" class="flex" :class="zoomed ? 'fixed z-10 bottom-0' : ' flex-wrap mt-3'">
<a
:href="config.media_url + '/catalog/product' + image"
v-for="(image, index) in images"
class="flex items-center justify-center border rounded p-5"
:class="{
'h-96': images.length == 1,
'h-48 sm:h-64 md:h-80 lg:h-96': images.length != 1,
'fixed inset-0 bg-white !h-full z-10 cursor-[zoom-out]': opened === index
}"
v-on:click.prevent="toggle(index, $event)"
href="#"
v-for="(image, imageId) in images"
class="flex items-center justify-center border rounded p-2 mr-3 mb-3 h-[100px] w-[100px]"
:class="active == imageId ? 'border-primary' : ''"
@click.prevent="change(imageId)"
>
<picture class="contents">
<source :srcset="'/storage/resizes/450/catalog/product' + image + '.webp'" type="image/webp">
<source :srcset="'/storage/resizes/100x100/catalog/product' + image + '.webp'" type="image/webp">
<img
:src="'/storage/resizes/450/catalog/product' + image"
:src="'/storage/resizes/100x100/catalog/product' + image"
alt="{{ $product->name }}"
class="max-h-full max-w-full"
loading="lazy"
/>
</picture>
</a>
<x-rapidez::no-image v-if="images.length == 0" class="rounded h-96"/>
</div>

<div v-if="opened !== false" class="fixed top-3 right-3 z-10 pointer-events-none">
<div v-if="zoomed" class="fixed top-3 right-3 z-10 pointer-events-none">
<x-heroicon-o-x class="h-6 w-6"/>
</div>
</div>
Expand Down

0 comments on commit 91e4997

Please sign in to comment.