diracleo / vue-enlargeable-image

A Vue component that, when clicked, will enlarge an image from thumbnail to full version using a smooth animation.
15 stars 2 forks source link

Nuxt #1

Open hvitis opened 3 years ago

hvitis commented 3 years ago

Great repo! The best enlarge package out there. Thank you!

I was struggling a bit with registering on Nuxt but finally made it:

//enlarge.js
import Vue from "vue";
import EnlargeableImage from "@diracleo/vue-enlargeable-image";
Vue.config.productionTip = false;

// Globally register your component
Vue.component("enlargeable-image", EnlargeableImage);
//nuxt.config.js

/*
** Plugins to load before mounting the App
*/
plugins: [
    ...
    { src: "@/plugins/enlarge", mode: "client", ssr: false },
    ....  
],
hvitis commented 3 years ago

Btw. what a great piece of code! Works great, thank you!

diracleo commented 3 years ago

You're welcome! So glad to hear it's working for you, and thanks for posting your code for integration with Nuxt

keshprad commented 3 years ago

@hvitis @diracleo This works well when I run the nuxt dev script, but it doesn't seem to work in production when I run nuxt generate and nuxt start. Does anyone know how I can get this working for Static Site with Nuxt?

boyet007 commented 3 years ago

well done

lcherone commented 2 years ago

complains in nuxt if you use a linter, as various issues, == vs === etc, also not sure why you have done var self = this, throughout, suspect its to do with the setTimeout callbacks, in which case you can use .bind(this) etc.

Fixed code, would PR but not bothered :)

<template>
  <div :class="{ 'enlarge-image': true, active: state !== 'delarged' }">
    <div
      ref="slot"
      class="slot"
      v-on="$props.trigger === 'click' ? { click: enlarge } : { mouseenter: enlarge, mouseleave: reset }"
    >
      <slot>
        <img :src="$props.src" class="default" alt>
      </slot>
    </div>
    <div class="full" :style="styles" :class="state" v-on="$props.trigger === 'click' ? { click: reset } : {}">
      <img v-if="state !== 'enlarged'" :src="$props.src" alt>
      <img v-if="state === 'enlarged'" :src="$props.srcLarge" alt>
    </div>
  </div>
</template>

<script>
export default {
  name: 'EnlargeableImage',
  props: {
    src: {
      type: String,
      default: '',
      required: true
    },
    srcLarge: {
      type: String,
      default: '',
      required: true
    },
    animationDuration: {
      type: String,
      default: '700'
    },
    trigger: {
      type: String,
      default: 'click'
    }
  },
  data () {
    return {
      state: this.state,
      styles: this.styles
    }
  },
  mounted () {
    this.$nextTick(this.init)
  },
  methods: {
    init () {
      this.state = 'delarged'
      this.delay = 50
      this.adjust_top = 0
      this.wait = false
      let transition_seconds = parseInt(this.$props.animationDuration) / 1000
      if (transition_seconds === 0) {
        this.delay = 0
      }
      transition_seconds = transition_seconds.toFixed(2)
      this.transition_value =
        'width ' +
        transition_seconds +
        's, height ' +
        transition_seconds +
        's, top ' +
        transition_seconds +
        's, left ' +
        transition_seconds +
        's, background-color ' +
        transition_seconds +
        's'
      this.styles = {
        transition: this.transition_value
      }
      if (this.$props.trigger === 'hover') {
        this.styles.pointerEvents = 'none'
      }
    },
    enlarge () {
      const rect = this.$refs.slot.getBoundingClientRect()
      this.styles = {
        position: 'fixed',
        left: Math.round(rect.left) + 'px',
        top: Math.round(rect.top + this.adjust_top) + 'px',
        width: Math.round(rect.right - rect.left) + 'px',
        height: Math.round(rect.bottom - rect.top) + 'px',
        backgroundImage: 'url(' + this.$props.src + ')',
        transition: this.transition_value
      }
      if (this.$props.trigger === 'hover') {
        this.styles.pointerEvents = 'none'
      }
      this.state = 'enlarging'
      if (typeof this.timer !== 'undefined') {
        clearTimeout(this.timer)
      }
      this.timer = setTimeout(
        function () {
          this.$emit('enlarging')
          this.styles = {
            backgroundImage: 'url(' + this.$props.src + ')',
            transition: this.transition_value
          }
          if (this.$props.trigger === 'hover') {
            this.styles.pointerEvents = 'none'
          }
          if (typeof this.timer !== 'undefined') {
            clearTimeout(this.timer)
          }
          this.timer = setTimeout(
            function () {
              this.state = 'enlarged'
              this.$emit('enlarged')
            }.bind(this),
            this.$props.animationDuration
          )
        }.bind(this),
        this.delay
      )
    },
    reset () {
      if (this.state !== 'delarging') {
        const rect = this.$refs.slot.getBoundingClientRect()
        if (typeof this.timer !== 'undefined') {
          clearTimeout(this.timer)
        }
        this.timer = setTimeout(
          function () {
            this.state = 'delarging'
            this.$emit('delarging')
            this.styles = {
              backgroundImage: 'url(' + this.$props.src + ')',
              position: 'fixed',
              left: Math.round(rect.left) + 'px',
              top: Math.round(rect.top + this.adjust_top) + 'px',
              width: Math.round(rect.right - rect.left) + 'px',
              height: Math.round(rect.bottom - rect.top) + 'px',
              transition: this.transition_value
            }
            if (this.$props.trigger === 'hover') {
              this.styles.pointerEvents = 'none'
            }
            if (typeof this.timer !== 'undefined') {
              clearTimeout(this.timer)
            }
            this.timer = setTimeout(
              function () {
                this.state = 'delarged'
                this.$emit('delarged')
              }.bind(this),
              this.$props.animationDuration
            )
          }.bind(this),
          0
        )
      } else {
        this.enlarge()
      }
    }
  }
}
</script>