IT俱乐部 JavaScript 前端实现图片或视频预览的三种方法总结

前端实现图片或视频预览的三种方法总结

一、上传到OSS或者服务器

缺点:

1.大文件上传时间过长

2.如果用户只是预览则会浪费服务端存储

二、使用FileReader对象转换File对象为base64

三、通过blob协议实现预览

附:前端自定义封装图片预览组件(支持多张图片预览 缩放)

封装图片预览组件:

Preview Image
<
>
export default { props: { images: { type: Array, required: true, }, }, data() { return { showOverlay: false, currentIndex: 0, currentImageUrl: '', scale: 1, initialMouseX: 0, initialScale: 1, isDragging: false, }; }, methods: { openPreview() { this.showOverlay = true; this.currentImageUrl = this.images[this.currentIndex]; this.$refs.previewWrapper.style.display = 'flex'; setTimeout(() => { this.$refs.previewWrapper.style.opacity = 1; }, 10); }, closePreview() { this.showOverlay = false; setTimeout(() => { this.$refs.previewWrapper.style.opacity = 0; setTimeout(() => { this.$refs.previewWrapper.style.display = 'none'; }, 0); }, 0); }, nextImage() { this.currentIndex = (this.currentIndex + 1) % this.images.length; this.currentImageUrl = this.images[this.currentIndex]; }, prevImage() { this.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length; this.currentImageUrl = this.images[this.currentIndex]; }, imageLoaded() { // 可以在此处调整图片的居中或其它布局逻辑 }, }, mounted() { // 初始化时隐藏预览层 this.$refs.previewWrapper.style.display = 'none'; }, }; .image-preview { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 999; display: none; justify-content: center; align-items: center; opacity: 0; transition: opacity 0.7s ease-in-out; } .overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); cursor: pointer; } .preview-container { position: relative; text-align: center; overflow: hidden; max-width: 90%; max-height: 90vh; } .arrow { width: 50px; height: 50px; position: absolute; top: 50%; transform: translateY(-50%); background: rgba(255, 255, 255, 0.8); padding: 10px; border-radius: 50%; cursor: pointer; z-index: 1; opacity: 0.5; transition: opacity 0.3s; border: none; font-size: 20px; line-height: 50px; } .arrow:hover { opacity: 1; } .arrow-left { left: 10px; } .arrow-right { right: 10px; }

图片放大缩小依靠自定义指令实现:

自定义指定代码:src/utils/scale.js

export const initVWheelScale = (Vue) => {
    Vue.directive("wheelScale", (el, binding) => {
      const {
        maxScale = 5,
        minScale = 0.5,
        initScale = 1,
        cssVarName = "--scale",
      } = binding.arg || {}
      let currentScale = initScale || el.style.getPropertyValue(cssVarName) || 1
      setWheelScale(binding, {
        el,
        cssVarName,
        currentScale,
        minScale,
        maxScale,
      })
      if (el) {
        el.onwheel = (e) => {
          currentScale = el.style.getPropertyValue(cssVarName) || 1
   
          if (e.wheelDelta > 0) {
            currentScale = currentScale * 1 + 0.1
          } else {
            currentScale = currentScale * 1 - 0.1
          }
          setWheelScale(binding, {
            el,
            cssVarName,
            currentScale,
            minScale,
            maxScale,
          })
        }
      }
    })
  }
  // 设置 --scale 变量 缩放比例
  const setVarScale = (el, cssVarName, currentScale, minScale, maxScale) => {
    // 现在缩放范围
    if (currentScale > maxScale) {
      currentScale = maxScale
    } else if (currentScale  {
    let transformCssString = el.style.transform
    let regScaleGlobal = /scale(.*?[ )]*[)]+[ ]*/g //匹配 Scale属性 全局
    if (regScaleGlobal.test(transformCssString)) {
      transformCssString = transformCssString.replace(
        regScaleGlobal,
        ` scale(var(${cssVarName})) `
      )
    } else {
      transformCssString += " " + `scale(var(${cssVarName}))`
    }
    el.style.transform = transformCssString
  }
  export const setWheelScale = (binding = {}, options) => {
    const { el, cssVarName, currentScale, minScale, maxScale } = options
    const nowScale = setVarScale(el, cssVarName, currentScale, minScale, maxScale)
    setTransformCss(el, cssVarName)
    // 缩放改变回调函数
    const wheelScaleHandle = binding.value || null
    if (wheelScaleHandle instanceof Function) {
      wheelScaleHandle({
        el,
        cssVarName,
        maxScale,
        minScale,
        currentScale: nowScale,
        setScale: (_scale) => {
          setWheelScale(binding, { ...options, currentScale: _scale })
        },
        binding,
      })
    }
  }
   

main.js中全局注册自定义指令:

import { initVWheelScale} from "@/utils/scale.js"
initVWheelScale(Vue)

在图片预览组件中使用:

组件的使用:

import ImagePreview from '@/components/ImagePreview.vue'; // 引入你的图片预览组件 export default { components: { ImagePreview, }, data() { return { imageList: [ 'https://img1.baidu.com/it/u=582697934,2565184993&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=539', 'https://img2.baidu.com/it/u=3519181745,2349627299&fm=253&fmt=auto&app=120&f=JPEG?w=750&h=500', // 更多图片路径 ], }; }, methods: { openPreview() { this.$refs.imagePreview.openPreview(); }, }, };

效果:

总结 

到此这篇关于前端实现图片或视频预览的三种方法的文章就介绍到这了,更多相关前端图片或视频预览内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/navsub/js/12332.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部