脚本之家

电脑版
提示:原网页已由神马搜索转码, 内容由www.jb51.net提供.
您的位置:首页网络编程JavaScriptjavascript技巧→ 前端图片或视频预览

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

  更新时间:2024年06月27日 10:49:41  作者:chens123123 
在JavaScript中实现前端图片上传即时预览功能是一项常见的需求,特别是在网页交互设计中,这篇文章主要给大家介绍了关于前端实现图片或视频预览的三种方法,需要的朋友可以参考下

一、上传到OSS或者服务器

缺点:

1.大文件上传时间过长

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

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

<input type="file" id="videoInput">
<video src="" alt="预览" id="video" controls="controls">
<script>
const videoInput = document.getElementById('videoInput');
videoInput.addEventListener('change', e => {
previewByReader(e.target.files[0])
})
function fileToBase64(file: File): Promise<{ url: any, filename: string }> {
const fileReader = new FileReader()
fileReader.readAsDataURL(file)
var filename = file.name;
return new Promise((resolve, reject) => {
fileReader.addEventListener("loadend", (e: ProgressEvent<FileReader>) => {
var url: any = e.target!.result;
resolve({ url, filename })
}, false);
})
}
async function previewByReader (file) {
const {url} = await fileToBase64(file)
video.src = url
}
</script>

三、通过blob协议实现预览

<input type="file" id="videoInput">
<video src="" alt="预览" id="video" controls="controls" width="400" height="200">
<script>
const videoInput = document.getElementById('videoInput');
videoInput.addEventListener('change', e => {
previewByURL(e.target.files[0])
})
function previewByURL (file) {
video.src = URL.createObjectURL(file)
}
</script>

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

封装图片预览组件:

<template>
<div ref="previewWrapper" class="image-preview">
<div class="overlay" v-if="showOverlay" @click="closePreview"></div>
<div class="preview-container" v-wheelScale>
<img :src="currentImageUrl" alt="Preview Image" @load="imageLoaded" ref="previewImage">
</div>
<div class="arrow arrow-left" @click="prevImage" :disabled="currentIndex === 0">&lt;</div>
<div class="arrow arrow-right" @click="nextImage" :disabled="currentIndex === images.length - 1">&gt;</div>
</div>
</template>

<script>
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';
},
};
</script>

<style scoped>
.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;
}
</style>

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

自定义指定代码: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 < minScale) {
currentScale = minScale
}
let cssText = el.style.cssText
let cssTextList = cssText.split(";")
let isExist = false
let isExistIndex = -1
for (let index = 0; index < cssTextList.length; index++) {
const element = cssTextList[index]
if (element.includes(cssVarName + ":")) {
isExist = true
isExistIndex = index
break
}
}
if (isExist) {
cssTextList[isExistIndex] = `--scale: ${currentScale}`
} else {
cssTextList.push(`--scale: ${currentScale}`)
// el.setAttribute("style", `--scale: ${currentScale}`)
}
cssText = cssTextList.join(";")
el.style.cssText = cssText
return currentScale
}
// 设置 style.transform
const setTransformCss = (el, cssVarName) => {
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)

在图片预览组件中使用:

组件的使用:

<template>
<div>
<!-- ...其他内容 -->
<button @click="openPreview">预览图片</button>
<image-preview :images="imageList" ref="imagePreview"></image-preview>
</div>
</template>
<script>
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();
},
},
};
</script>

效果:

总结 

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

相关文章

    • 本文主要分享了原生js实现焦点轮播图效果的示例代码,并解析了实例中的注意点。具有一定的参考价值,下面跟着小编一起来看下吧
      2017-01-01
    • 下面小编就为大家带来一篇js实现页面跳转的五种方法推荐。小编觉得挺不错的。现在分享给大家。给大家参考一下。
      2016-03-03
    • eval()函数,这个函数可以把一个字符串当作一个JavaScript表达式一样去执行它。
      2010-03-03
    • 这篇文章主要为大家介绍了js贪吃蛇游戏实现思路,并分享贪吃蛇游戏源码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
      2016-04-04
    • 这篇文章主要介绍了JS基于MSClass和setInterval实现ajax定时采集信息并滚动显示的方法,涉及JavaScript页面元素定时滚动操作及ajax调用实现技巧,需要的朋友可以参考下
      2016-04-04
    • 这篇文章主要介绍了微信小程序拍照和摄像功能实现方法,结合实例形式分析了微信小程序拍照与摄影功能的原理、相关实现技巧与注意事项,需要的朋友可以参考下
      2019-02-02
    • js中的变量都是公用的没有静态变量,下面为大家介绍下变量的作用域闭包,需要的朋友可以参考下
      2014-05-05
    • 本文主要介绍了JS数组去重的4种方法。具有很好的参考价值。下面跟着小编一起来看下吧
      2017-03-03
    • xmlplus 是一个JavaScript框架,用于快速开发前后端项目。这篇文章主要介绍了xmlplus组件设计系列之列表,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
      2017-04-04
    • bootstrap-treeview.js1是一款强大的树菜单插件,本文给大家介绍bootstrap treeview的简单使用,涉及到使用要求及数据格式的介绍,本文介绍的非常详细,具有参考借鉴价值,感兴趣的朋友参考下
      2016-10-10

    最新评论