]> _ Git - pmi.git/commitdiff
Large image popups + better image handling for products. WIP #3074
authorStephen Cameron <stephen@cubedesigners.com>
Wed, 9 Oct 2019 17:01:28 +0000 (19:01 +0200)
committerStephen Cameron <stephen@cubedesigners.com>
Wed, 9 Oct 2019 17:01:28 +0000 (19:01 +0200)
14 files changed:
app/Models/Product.php
package.json
public/images/vendor/blueimp-gallery/error.png [new file with mode: 0644]
public/images/vendor/blueimp-gallery/error.svg [new file with mode: 0644]
public/images/vendor/blueimp-gallery/loading.gif [new file with mode: 0644]
public/images/vendor/blueimp-gallery/play-pause.png [new file with mode: 0644]
public/images/vendor/blueimp-gallery/play-pause.svg [new file with mode: 0644]
public/images/vendor/blueimp-gallery/video-play.png [new file with mode: 0644]
public/images/vendor/blueimp-gallery/video-play.svg [new file with mode: 0644]
resources/js/components/ProductGallery.vue
resources/views/pages/product-detail.blade.php
routes/backpack/custom.php
tailwind.config.js
yarn.lock

index 606eb691b01659aeccecab43785b0e236ad002d6..54fce9bf76a9cf5518d2c1abb293df771465f55d 100644 (file)
@@ -8,6 +8,7 @@ use Cubist\Util\Json;
 use Illuminate\Support\Facades\App;
 use Illuminate\Support\Str;
 use Spatie\MediaLibrary\Models\Media;
+use Spatie\Image\Manipulations;
 
 class Product extends CubistMagicPageModel
 {
@@ -144,6 +145,20 @@ class Product extends CubistMagicPageModel
         $this->addSpecifications();
     }
 
+    // Image handling
+    public function registerMediaConversions(Media $media = null) {
+
+        parent::registerMediaConversions($media);
+
+        $this->addMediaConversion('thumb')
+            ->width(300)
+            ->height(300);
+
+        $this->addMediaConversion('large')
+            ->fit(Manipulations::FIT_MAX, 1200, 1000); // Don't enlarge small images
+    }
+
+
     protected static function _getRelatedEntities()
     {
         if (null === self::$_specifications) {
@@ -345,7 +360,7 @@ class Product extends CubistMagicPageModel
     {
         if ($this->images) {
 
-            $image = $this->getFirstMediaUrl($this->images);
+            $image = $this->getFirstMediaUrl($this->images, 'thumb');
 
             if ($image) {
                 return $image;
index 3a73abb88b1817b95f21bb61d3583da030e484e2..41c7aa649b8be4a4d29619a6a59dbc2583c66b26 100644 (file)
@@ -42,6 +42,7 @@
         "tippy.js": "^4.3.5",
         "unorm": "^1.6.0",
         "vue": "^2.6.10",
+        "vue-gallery": "^2.0.0",
         "vue-slide-up-down": "^1.7.2",
         "vue-slider-component": "^3.0.40",
         "vue-template-compiler": "^2.6.10"
diff --git a/public/images/vendor/blueimp-gallery/error.png b/public/images/vendor/blueimp-gallery/error.png
new file mode 100644 (file)
index 0000000..a5577c3
Binary files /dev/null and b/public/images/vendor/blueimp-gallery/error.png differ
diff --git a/public/images/vendor/blueimp-gallery/error.svg b/public/images/vendor/blueimp-gallery/error.svg
new file mode 100644 (file)
index 0000000..184206a
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64">
+       <circle cx="32" cy="32" r="25" stroke="red" stroke-width="7" fill="black" fill-opacity="0.2"/>
+       <rect x="28" y="7" width="8" height="50" fill="red" transform="rotate(45, 32, 32)"/>
+</svg>
diff --git a/public/images/vendor/blueimp-gallery/loading.gif b/public/images/vendor/blueimp-gallery/loading.gif
new file mode 100644 (file)
index 0000000..90f28cb
Binary files /dev/null and b/public/images/vendor/blueimp-gallery/loading.gif differ
diff --git a/public/images/vendor/blueimp-gallery/play-pause.png b/public/images/vendor/blueimp-gallery/play-pause.png
new file mode 100644 (file)
index 0000000..ece6cfb
Binary files /dev/null and b/public/images/vendor/blueimp-gallery/play-pause.png differ
diff --git a/public/images/vendor/blueimp-gallery/play-pause.svg b/public/images/vendor/blueimp-gallery/play-pause.svg
new file mode 100644 (file)
index 0000000..a7f1f50
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="15">
+       <polygon points="2,1 2,14 13,7" stroke="black" stroke-width="1" fill="white"/>
+       <rect x="17" y="2" width="4" height="11" stroke="black" stroke-width="1" fill="white"/>
+       <rect x="24" y="2" width="4" height="11" stroke="black" stroke-width="1" fill="white"/>
+</svg>
diff --git a/public/images/vendor/blueimp-gallery/video-play.png b/public/images/vendor/blueimp-gallery/video-play.png
new file mode 100644 (file)
index 0000000..353e3a5
Binary files /dev/null and b/public/images/vendor/blueimp-gallery/video-play.png differ
diff --git a/public/images/vendor/blueimp-gallery/video-play.svg b/public/images/vendor/blueimp-gallery/video-play.svg
new file mode 100644 (file)
index 0000000..b5ea206
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64" height="64">
+       <circle cx="32" cy="32" r="25" stroke="white" stroke-width="7" fill="black" fill-opacity="0.2"/>
+       <polygon points="26,22 26,42 43,32" fill="white"/>
+</svg>
index 67332176b52a0f2fb9e775018cfeb87f66ddc27c..3fc25709a8142c9cde84365be4499b5f7d355b0b 100644 (file)
@@ -1,32 +1,51 @@
 <template>
     <div class="product-gallery" v-show="images.length > 0">
         <div class="product-gallery-main">
-            <div class="product-gallery-main-image" :style="`background-image:url(${images[currentImage]})`"></div>
+            <div class="product-gallery-main-image cursor-zoom-in" :style="`background-image:url(${thumbnails[currentImage]})`" @click="lightboxImage = currentImage"></div>
         </div>
         <div class="grid grid-cols-3 grid-gap-sm" v-show="images.length > 1">
-            <div v-for="(image, i) in images"
+            <div v-for="(thumb, i) in thumbnails"
                  :key="i"
-                 :style="`background-image:url(${image})`"
+                 :style="`background-image:url(${thumb})`"
                  :class="{ 'product-gallery-current' : currentImage === i }"
                  class="product-gallery-thumb"
                  @click="currentImage = i"
             >
             </div>
         </div>
+        <!-- Options reference: https://github.com/blueimp/Gallery#options -->
+        <lightbox-gallery
+            :options="{ closeOnSlideClick: true }"
+            :images="images"
+            :index="lightboxImage"
+            @close="lightboxImage = null"
+        >
+            <template v-slot:close>×</template>
+        </lightbox-gallery>
     </div>
 </template>
 
 <script>
+    import VueGallery from 'vue-gallery';
 
     export default {
 
+        components: {
+            'lightbox-gallery': VueGallery
+        },
+
         props: {
             images: {
+                type: Array,
                 required: true,
+            },
+            thumbnails: {
+                type: Array
             }
         },
         data: () => ({
             currentImage: 0,
+            lightboxImage: null,
         }),
 
         computed: {
@@ -34,7 +53,8 @@
         },
 
         created() {
-
+            // Fallback to using images if thumbnails not passed
+            this.thumbnails = this.thumbnails || this.images;
         },
 
         mounted() {
index fff60f027fb926a5cce2dd762421d412f212f9af..de17a7b7171631dee15b3b54be8cf3d748331295 100644 (file)
@@ -24,7 +24,8 @@
 
             {{-- Product images --}}
             <product-gallery
-                :images='@json($product->getImageURLList('images', '', [$product->getEntity()->image_fallback]))'
+                :thumbnails='@json($product->getImageURLList('images', 'thumb', [$product->getEntity()->image_fallback]))'
+                :images='@json($product->getImageURLList('images', 'large', [$product->getEntity()->image_fallback]))'
                 class="flex-grow"
                 style="max-width: 348px">
             </product-gallery>
index 53bcf04be3c79c2c9464e807c3498f1dc17b46a8..63455e102c092da2c05abca316e4e837bdaea54d 100644 (file)
@@ -24,6 +24,11 @@ Route::group([
         Route::match(['delete'], 'page/{id}/media/{mediaId}', 'PageCrudController@deleteMedia');
         Route::match(['post'], 'page/{id}/media/reorder', 'PageCrudController@reorderMedia');
     });
+    CRUD::resource('product', 'ProductCrudController')->with(function () {
+        Route::match(['post'], 'product/{id}/media', 'ProductCrudController@uploadMedia');
+        Route::match(['delete'], 'product/{id}/media/{mediaId}', 'ProductCrudController@deleteMedia');
+        Route::match(['post'], 'product/{id}/media/reorder', 'ProductCrudController@reorderMedia');
+    });
     CRUD::resource('producttype', 'ProductTypeCrudController')->with(function () {
         Route::match(['post'], 'producttype/{id}/media', 'ProductTypeCrudController@uploadMedia');
         Route::match(['delete'], 'producttype/{id}/media/{mediaId}', 'ProductTypeCrudController@deleteMedia');
index 304dfb0b0b0c120609f6036eabc64692340c801f..fed49ec56962b3db9f2294834c5809374b9a3570 100644 (file)
@@ -28,6 +28,9 @@ module.exports = {
                     'dark': '#6B7287',
                 }
             },
+            cursor: {
+                'zoom-in': 'zoom-in'
+            },
             fontSize: {
                 '6xl': '3.75rem' // Only override this value
             },
index 58f33845e8563de23feeb291cc8d7a5a5ff02d2d..e84315d01e52e30dc0c8c4646d6a899a90715f1e 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
@@ -1283,6 +1283,11 @@ bluebird@^3.0.5, bluebird@^3.1.1, bluebird@^3.5.3:
   resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f"
   integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==
 
+blueimp-gallery@^2.33.0:
+  version "2.35.0"
+  resolved "https://registry.yarnpkg.com/blueimp-gallery/-/blueimp-gallery-2.35.0.tgz#96d5792138e3365ce83d0a4afd84a7f803612b29"
+  integrity sha512-/dT0K8Vh2FlmKW+PILbygoZ4ramOBM8x2e85JTHOXImI2v2flaBBInQNu7nPonCkWLFejfsf54oHdty1QQslog==
+
 blueimp-tmpl@^2.5.5:
   version "2.5.7"
   resolved "https://registry.yarnpkg.com/blueimp-tmpl/-/blueimp-tmpl-2.5.7.tgz#33fb12c139d65512ae40afbd8e2def8d9db96490"
@@ -8100,6 +8105,13 @@ vue-class-component@^7.0.1:
   resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.1.0.tgz#b33efcb10e17236d684f70b1e96f1946ec793e87"
   integrity sha512-G9152NzUkz0i0xTfhk0Afc8vzdXxDR1pfN4dTwE72cskkgJtdXfrKBkMfGvDuxUh35U500g5Ve4xL8PEGdWeHg==
 
+vue-gallery@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/vue-gallery/-/vue-gallery-2.0.0.tgz#07d29e9169701d7d19b6b5f643038f1d50606329"
+  integrity sha512-6BCItrHwH0v0p2T8Pf6iAUGOi7sZtDt/WLn+DiRznfMec/WPPjT/udBABChkyGGzdn/FBHoF768ITAjLDXfMLw==
+  dependencies:
+    blueimp-gallery "^2.33.0"
+
 vue-hot-reload-api@^2.3.0:
   version "2.3.3"
   resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz#2756f46cb3258054c5f4723de8ae7e87302a1ccf"