“PK creative Spring Festival, I am participating in the” Spring Festival Creative submission contest “, please see: Spring Festival Creative Submission Contest”

Some time ago, I saw someone making fun of the zoom function of the boiling point column picture (but now it seems to be revised). I have a little time to think about how I will do if I come to realize this function. It is also convenient for us to sweep the dedication of happiness together during the Chinese New Year.

1. Implementation scheme

I’ve been looking at Vue3.0 recently, so this plugin decides to implement vue3.0+typescript.

2. Implementation idea

The main function of this plug-in is: click a small picture to display the enlarged version of the current picture in full screen. And can drag, the mouse can also control the zoom in and out of the picture.

The overall UI layout was decided to be based on Elemental-Plus’s El-Dialog, showing a mask layer with a transparent background.

3. Implementation code

/ / HTML
<div class="picview">
    <el-dialog
      v-model="picture"
      :close-on-click-modal="false"
      :fullscreen="true"
      custom-class="picture"
    >
      <div v-loading.fullscreen.lock="loading" ref="myPic" class="main" @click="close($event)">
        <img
          v-show="isPicShow"
          :src="src"
          :width="picW"
          :height="picH"
          :style="{ transform: picTransform, top: picTop ,left:picLeft }"
          @load="scalePic"
          @error="setImgError"
          @mousedown.prevent="mousedown($event)"
          @mousemove.prevent="mousemove($event)"
          @mouseup.prevent="mouseup($event)"
        >
      </div>
    </el-dialog>
  </div>
Copy the code
/ / js parts
import { defineEmit, ref, watch, toRefs } from 'vue'
const props = defineProps({
  src: {
    type: String.default: ' '
  },
  width: {
    type: String.default: ' '
  },
  height: {
    type: String.default: ' '
  },
  showPicture: {
    type: Boolean.default: false}})const emit = defineEmit(['update:showPicture'])

const { showPicture } = toRefs(props)

const loading = ref(false)
const picture = ref(false)
const picW = ref(0)
const picH = ref(0)
const isPicShow = ref(false)
const picTransform = ref(' ')
const picTop = ref(' ')
const picLeft = ref(' ')
let scale = 1,
  roted = 0,
  isMoving = false,
  disX = 0,
  disY = 0

const myPic: Ref = ref(null)

watch(showPicture, (newVal, oldVal) = > {
  picture.value = newVal;
})


const scalePic = function() {
  loading.value = false;
  scale = 1;
  roted = 0;
  picTransform.value = 'scale(1)';
  countImg();
  window.onresize = function() {
    countImg();
  };
  document.body.onmousewheel = function(event: any) {
    event = event || window.event;
    if (picture.value === true) {
      if (event.deltaY > 0) {
        scale = scale > 0.2 ? scale - 0.1 : scale;
      } else {
        scale += 0.1;
      }
      picTransform.value = `scale(${scale}) rotate(${roted}deg)`}}; }const rotePic = function() {
  roted = Number(roted) + 90;
  picTransform.value = `scale(${scale}) rotate(${roted}deg)`
}
const close = function(e: any) {
  if (e.target === myPic.value.childNodes[0]) {
    return;
  }
  //
  emit('update:showPicture'.false);
  // showPicture.value = false
  e.stopPropagation();
}
const mousedown = function(e: any) {
  let oDiv = myPic.value.childNodes[0];
  isMoving = true;
  disX = e.clientX - oDiv.offsetLeft;
  disY = e.clientY - oDiv.offsetTop;
}
const mousemove = function(e) {
  if (
    isMoving &&
    e.clientY > 0 &&
    e.clientY < myPic.value.clientHeight &&
    e.clientX > 0 &&
    e.clientX < myPic.value.clientWidth
  ) {
    picTop.value = e.clientY - disY + 'px';
    picLeft.value = e.clientX - disX + 'px'; }}const mouseup = function() {
  isMoving = false;
  return false;
}
const countImg = function() {
  const cpicW = myPic.value.childNodes[0].naturalWidth;
  const cpicH = myPic.value.childNodes[0].naturalHeight;
  let Width = myPic.value.offsetWidth;
  let Height = myPic.value.offsetHeight;
  if (Width / Height <= cpicW / cpicH) {
    if (Width > cpicW) {
      Width = cpicW;
    }
    picW.value = Width;
    picH.value = (Number(cpicH) * Width) / Number(cpicW);
    picTop.value = `${(Height - picH.value) / 2}px`;
    picLeft.value = `${(myPic.value.offsetWidth - picW.value) / 2}px`;
    isPicShow.value = true;
  } else {
    if (Height > cpicH) {
      Height = cpicW;
    }
    picH.value = Height;
    picW.value = (Number(cpicW) * Height) / Number(cpicH);
    picLeft.value = `${(Width - picW.value) / 2}px`;
    picTop.value = `${(myPic.value.offsetHeight - picH.value) / 2}px`;
    isPicShow.value = true; }}const setImgError = function() {
  loading.value = false;
}
Copy the code

Once the component is implemented, we can transform the current component into a plug-in that we can use for vue3.0 projects.

4. Encapsulate plug-ins

// imageView.vue writes our component
import imageView from './lib/imageView.vue'

// Define our plug-in
const myPlugin = {    
    // The plug-in has an install method
    // The first argument to the method is the Vue passed in, and the second argument can be the plug-in's custom argument
    install (Vue: any) {
        // Register it as a vUE component. 'imageView' is the component name. ImageView is the component we developed
        Vue.component('imageView', imageView)    
    }
}

// Finally export the plug-in and use the plug-in in main.js via vue.use ()
export default myPlugin
Copy the code

The specific process of plug-in development is not described here, interested in children’s shoes can turn over the previous article.

5. Use plug-ins

// main.ts
import imageView from 'lmuy-image-view'

createApp(App).use(imageView).mount('#app')

/ / in the page
<lmuy-image-view
  :src="src"
  :show-picture="item.dialogVisible"
  @update:show-picture="closeImage"/>
Copy the code

The effect picture is shown below, which achieves the function of enlarging the picture. And easy to use, simple operation. Boiling point amplification can be done this way, and the New Year’s day when we pass up those hidden in the corner of the small professional blessing, in our plug-in display, is not a good we sweep out ~

The current plug-in has been uploadednpmOn, interested children’s shoes can searchlmuy-image-viewTake a look.