flex错误Error #2044: 未处理的 ErrorEvent:。 text=Error #3702: Context3D 不可用

本文介绍了解决Flash中出现的Error#2044及Error#3702的方法,通过在html-template的index.template.html文件中添加wmode参数设置为direct来解决3D上下文不可用的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Error #2044: 未处理的 ErrorEvent:。 text=Error #3702: Context3D 不可用

“Error #2044: 未处理的 ErrorEvent:。 text=Error #3702: Context3D 不可用”。

解决方法:找到项目文件夹中的html-template,并找到index.template.html,右键使用TextEditor编辑,在

 params.allowfullscreen=”true”;后面加上params.wmode = "direct";;

最好下面的embed也这样配置下 <param name="allowFullScreen" value="true" />后面加 <param name="wmode" value="direct" />

<template> <div class="news-images"> <div v-for="(img, idx) in images" :key="idx" class="news-img-wrap"> <!-- 上传进度显示 --> <div v-if="img.status === &#39;uploading&#39;" class="progress-overlay"> <van-circle v-model:current-rate="img.progress" :rate="100" :speed="10" size="120rem" :stroke-width="20" stroke-linecap="round" class="progress" > <span class="progress-text">{{ img.progress }}%</span> </van-circle> </div> <!-- 错误状态显示 --> <div v-if="img.status === &#39;error&#39;" class="error-overlay"> <van-icon name="warning" size="32rem" color="#ff4444" /> <span>上传失败</span> <van-button type="primary" size="small" @click="reUpload(idx)" style="margin-top: 16rem">重新上传</van-button> </div> <img :src="img.url" class="news-img" /> <div class="img-close" @click="removeImg(idx)"> <van-icon name="cross" size="32rem" color="#fff" /> </div> </div> <div v-if="images.length < maxCount" class="news-img-add" @click="onAddImg"> <van-icon name="plus" size="64rem" color="#bbb" /> </div> <!-- 隐藏的文件选择器 --> <input ref="fileInput" type="file" multiple accept="image/*" style="display: none" @change="handleFileChange" /> </div> </template> <script setup lang="ts"> import { apis } from &#39;@/api&#39; import System from &#39;@/utils/System&#39; import { showToast } from &#39;vant&#39; import { ref, onUnmounted } from &#39;vue&#39; const emit = defineEmits([&#39;update:modelValue&#39;]) const props = defineProps({ autoUpload: { type: Boolean, default: true }, maxCount: { type: Number, default: 9 }, modelValue: { type: Array as () => imgageItem[], default: () => [] } }) interface imgageItem { url: string progress: number status: &#39;pending&#39; | &#39;uploading&#39; | &#39;success&#39; | &#39;error&#39; file?: File } const fileInput = ref<HTMLInputElement | null>(null) const images = ref<imgageItem[]>(props.modelValue) const onAddImg = () => { fileInput.value?.click() } const removeImg = async (idx: number) => { images.value.splice(idx, 1) emit(&#39;update:modelValue&#39;, [...images.value]) } // const handleFileChange = async (e: Event) => { // const target = e.target as HTMLInputElement // const files = target.files // if (!files || files.length === 0) return // for (const file of Array.from(files)) { // if (images.value.length >= props.maxCount) break // try { // const reader = new FileReader() // console.log("🚀 ~ handleFileChange ~ reader:", reader) // reader.onload = (ev) => { // if (typeof ev.target?.result === &#39;string&#39;) { // const index = images.value.length // images.value.push({ // url: ev.target.result, // 临时预览URL // progress: 0, // status: &#39;pending&#39;, // file: file // }) // console.log("🚀 ~ handleFileChange ~ images.value:", images.value) // if (props.autoUpload) { // uploadFile(file, index) // } // reader.readAsDataURL(file) // } // } // // 清空 input // ;(e.target as HTMLInputElement).value = &#39;&#39; // // 更新父组件 // emit(&#39;update:modelValue&#39;, [...images.value]) // } catch (error) { // System.toast(&#39;图片处理失败&#39;) // console.error(&#39;文件处理错误:&#39;, error) // } // } // // 清空文件选择器 // ;(e.target as HTMLInputElement).value = &#39;&#39; // } const handleFileChange = (e: Event) => { const files = (e.target as HTMLInputElement).files if (files && files.length > 0) { Array.from(files).forEach((file) => { if (images.value.length >= 6) return const reader = new FileReader() reader.onload = (ev) => { if (typeof ev.target?.result === &#39;string&#39;) { const index = images.value.length images.value.push({ url: ev.target.result, // 临时预览URL progress: 0, status: &#39;pending&#39;, file: file }) // 开始上传 if (props.autoUpload) { uploadFile(file, index) } } } reader.readAsDataURL(file) }) emit(&#39;update:modelValue&#39;, [...images.value]) // 清空 input ;(e.target as HTMLInputElement).value = &#39;&#39; } } const uploadFile = async (file: File, index: number) => { // try { images.value[index].status = &#39;uploading&#39; // 调用API上传 const formData = new FormData() formData.append("file",file) const res: any = await apis.uploadFile({ file: formData.get(&#39;file&#39;) }, (progressEvent: { loaded: number; total: number }) => { if (progressEvent.total > 0) { images.value[index].progress = Math.round((progressEvent.loaded / progressEvent.total) * 100) } }) if (res.code === 200) { images.value[index].status = &#39;success&#39; images.value[index].url = res.data } else { images.value[index].status = &#39;error&#39; System.toast(&#39;图片上传失败&#39;) } emit(&#39;update:modelValue&#39;, [...images.value]) // } catch (error) { // images.value[index].status = &#39;error&#39; // System.toast(&#39;图片上传失败&#39;) // console.error(&#39;上传错误:&#39;, error) // emit(&#39;update:modelValue&#39;, [...images.value]) // } } // 自动上传全部待上传图片 const autoUploadAll = () => { images.value.forEach((img, index) => { if (img.status === &#39;pending&#39; && img.file) { uploadFile(img.file, index) } }) } // 重新上传指定失败图片 const reUpload = (index: number) => { if (images.value[index].status !== &#39;error&#39; || !images.value[index].file) return images.value[index].status = &#39;pending&#39; uploadFile(images.value[index].file!, index) } // 组件卸载时清理临时文件 onUnmounted(async () => {}) defineExpose({ autoUploadAll, reUpload }) </script> <style lang="less" scoped> .news-images { display: flex; flex-wrap: wrap; gap: 18.5rem; margin-bottom: 48rem; .news-img-wrap { position: relative; width: 216rem; height: 216rem; border-radius: 23rem; overflow: hidden; margin-bottom: 32rem; // 新增,保证多行间距 .progress-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 2; .progress { display: flex; align-items: center; justify-content: center; } .progress-text { color: #fff; font-size: 24rem; } } .error-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 2; span { color: #fff; font-size: 24rem; margin-top: 8rem; } } .news-img { width: 100%; height: 100%; object-fit: cover; border-radius: 24rem; } .img-close { position: absolute; top: 8rem; right: 8rem; background: rgba(0, 0, 0, 0.4); border-radius: 50%; width: 40rem; height: 40rem; display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 3; } } .news-img-add { width: 216rem; height: 216rem; background: #f6f6f6; border-radius: 23rem; display: flex; align-items: center; justify-content: center; cursor: pointer; margin-bottom: 32rem; // 保持添加按钮与图片对齐 .van-icon { font-weight: bold; } } } </style> 这个代码帮我解决
最新发布
07-05
<template> <view class="container"> <!-- 扫描区域 --> <view class="scan-area" v-if="isScanning"> <camera v-if="hasCameraPermission" :device-position="cameraPosition" @initdone="onCameraInit" class="camera"></camera> <!-- 扫描框 --> <view class="scan-box" :style="{ width: scanBoxSize + &#39;px&#39;, height: scanBoxSize + &#39;px&#39; }"> <view class="scan-line" :style="{ animation: &#39;scan &#39; + scanSpeed + &#39;s linear infinite&#39; }"></view> <view class="corner corner-top-left"></view> <view class="corner corner-top-right"></view> <view class="corner corner-bottom-left"></view> <view class="corner corner-bottom-right"></view> </view> <!-- 提示文字 --> <view class="scan-tip">请将二维码对准扫描框</view> <!-- 相册选择按钮 --> <view class="album-button" @click="selectFromAlbum"> <image src="@/static/icons/photofff.svg" mode="" class="album-img"></image> </view> <!-- 手电筒控制 --> <view class="torch-control" @click="toggleTorch"> <image src="@/static/icons/light4e86e7.svg" mode="" v-if="torchOn" class="torch-control-icon"></image> <image src="@/static/icons/ligntfff.svg" mode="" v-if="!torchOn" class="torch-control-icon"></image> <!-- <text class="torch-text">{{ torchOn ? &#39;关闭手电筒&#39; : &#39;打开手电筒&#39; }}</text> --> </view> </view> <!-- 结果显示 --> <view class="result-container" v-else-if="scanResult"> <view class="result-title">扫描结果</view> <view class="result-content">{{ scanResult }}</view> <button class="result-button" @click="startScan">重新扫描</button> </view> <!-- 错误提示 --> <view class="error-tip" v-if="errorMsg">{{ errorMsg }}</view> <!-- 权限申请 --> <!-- <view class="permission-modal" v-if="!hasCameraPermission && !permissionDenied"> <view class="permission-content"> <view class="permission-title">需要相机权限</view> <view class="permission-desc">请授予相机权限以使用扫描功能</view> <button class="permission-button" @click="requestCameraPermission">授予权限</button> </view> </view> --> <!-- 权限被拒绝提示 --> <view class="permission-modal" v-if="permissionDenied"> <view class="permission-content"> <view class="permission-title">权限被拒绝</view> <view class="permission-desc">请在设置中手动开启相机权限</view> <button class="permission-button" @click="openAppSettings">去设置</button> </view> </view> <!-- 隐藏的Canvas --> <!-- #ifdef MP-WEIXIN --> <canvas canvas-id="qr-canvas" class="hidden-canvas" /> <!-- #endif --> </view> </template> <script setup> import jsQR from &#39;jsqr&#39;; // 引入jsQR库 import { ref, onMounted, onUnmounted, nextTick } from &#39;vue&#39; // 状态变量 const isScanning = ref(false) const scanResult = ref(&#39;&#39;) const errorMsg = ref(&#39;&#39;) const hasCameraPermission = ref(false) const permissionDenied = ref(false) const torchOn = ref(false) const cameraPosition = ref(&#39;back&#39;) const scanBoxSize = ref(250) const scanSpeed = ref(2) const cameraContext = ref(null) const canvasContent = ref(null) // 生命周期钩子 onMounted(() => { checkCameraPermission() // 创建canvas上下文 canvasContent.value = uni.createCanvasContext(&#39;qr-canvas&#39;) }) onUnmounted(() => { stopScan() }) // 检查相机权限 const checkCameraPermission = () => { uni.getSetting({ success: (res) => { if (res.authSetting[&#39;scope.camera&#39;]) { hasCameraPermission.value = true startScan() } else { requestCameraPermission() } }, fail: () => { errorMsg.value = &#39;获取权限信息失败&#39; } }) } // 请求相机权限 const requestCameraPermission = () => { uni.authorize({ scope: &#39;scope.camera&#39;, success: () => { hasCameraPermission.value = true startScan() }, fail: () => { permissionDenied.value = true } }) } // 打开应用设置 const openAppSettings = () => { uni.openSetting({ success: (res) => { if (res.authSetting[&#39;scope.camera&#39;]) { hasCameraPermission.value = true permissionDenied.value = false startScan() } } }) } // 开始扫描 const startScan = () => { isScanning.value = true scanResult.value = &#39;&#39; errorMsg.value = &#39;&#39; nextTick(() => { cameraContext.value = uni.createCameraContext() startCameraScan() }) } // 停止扫描 const stopScan = () => { isScanning.value = false if (cameraContext.value) { cameraContext.value.stopPreview() } } // 开始相机扫描 const startCameraScan = () => { const listener = cameraContext.value.scanCode({ success: (res) => { scanResult.value = res.result isScanning.value = false }, fail: (err) => { errorMsg.value = &#39;扫描失败,请重试&#39; console.error(&#39;Scan failed:&#39;, err) // 继续扫描 setTimeout(startCameraScan, 1000) } }) } // 切换手电筒 const toggleTorch = () => { torchOn.value = !torchOn.value if (cameraContext.value) { cameraContext.value.switchTorch({ torch: torchOn.value ? &#39;on&#39; : &#39;off&#39;, success: () => {}, fail: (err) => { console.error(&#39;Switch torch failed:&#39;, err) torchOn.value = !torchOn.value errorMsg.value = &#39;手电筒切换失败&#39; } }) } } // 从相册选择图片 const selectFromAlbum = async () => { try { const res = await uni.chooseImage({ count: 1, sizeType: [&#39;compressed&#39;], // 压缩图片提高性能 sourceType: ["album"] }) const imagePath = res.tempFilePaths[0] errorMsg.value = "" //清除错误信息 // #ifdef APP-PLUS await decodeWithNativeAPI(imagePath) // #endif // #ifdef H5 || MP-WEIXIN await decodeWithJsQR(imagePath) // #endif } catch (err) { console.error(&#39;Choose image failed:&#39;, err) errorMsg.value = &#39;图片选择失败&#39; isScanning.value = true } // uni.chooseImage({ // count: 1, // sourceType: [&#39;album&#39;], // success: (res) => { // const imagePath = res.tempFilePaths[0] // uni.scanCode({ // onlyFromCamera: false, //允许从相册选择 // scanType: [&#39;qrCode&#39;], // path: imagePath, // 传入图片路径 // success: (scanRes) => { // scanResult.value = scanRes.result // isScanning.value = false // }, // fail: (err) => { // errorMsg.value = &#39;未能识别图片中的二维码&#39; // console.error(&#39;Scan from album failed:&#39;, err) // } // }) // }, // fail: (err) => { // console.error(&#39;Choose image failed:&#39;, err) // errorMsg.value = &#39;图片选择失败&#39; // } // }) } //使用jsQR解析二维码(微信小程序和H5) const decodeWithJsQR = (imagePath) => { return new Promise((resolve, reject) => { // 创建临时Image对象 const img = new Image() img.src = imagePath img.onload = async () => { try { // 设置Canvas尺寸(缩小尺寸提高性能) const canvasWidth = 300 const canvasHeight = 300 // 在Canvas上绘制图像 canvasContext.value.drawImage(img, 0, 0, canvasWidth, canvasHeight) await canvasContext.value.draw(true) // 获取图像数据 const res = await uni.canvasGetImageData({ canvasId: &#39;qr-canvas&#39;, x: 0, y: 0, width: canvasWidth, height: canvasHeight }) // 使用jsQR解析二维码 const qrCode = jsQR(res.data, res.width, res.height) if (qrCode) { scanResult.value = qrCode.data isScanning.value = false resolve() } else { errorMsg.value = &#39;未识别到二维码&#39; reject(&#39;未识别到二维码&#39;) } } catch (err) { console.error(&#39;Canvas操作失败:&#39;, err) reject(err) } } img.onerror = (err) => { console.error(&#39;图片加载失败:&#39;, err) reject(err) } }) } // 使用原生API解析二维码(APP) const decodeWithNativeAPI = (imagePath) => { return new Promise((resolve) => { // APP平台使用原生扫码API plus.barcode.decode( imagePath, (result) => { scanResult.value = result isScanning.value = false resolve() }, (error) => { console.error(&#39;原生解析错误:&#39;, error) errorMsg.value = &#39;二维码解析失败&#39; reject(error) }, &#39;QR&#39; // 只解析二维码 ) }) } // 相机初始化回调 const onCameraInit = (event) => { console.log(&#39;Camera initialized:&#39;, event) } </script> <style scoped lang="scss"> .container { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; position: relative; } .scan-area { position: relative; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .camera { width: 100%; height: 100%; position: absolute; top: 0; left: 0; } .scan-box { position: relative; border: 2px solid rgba(255, 255, 255, 0.7); box-shadow: 0 0 30px rgba(0, 255, 0, 0.5); } .scan-line { position: absolute; top: 0; left: 0; width: 100%; height: 2px; background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(0, 255, 0, 1) 50%, rgba(255, 255, 255, 0) 100%); } .corner { position: absolute; width: 30px; height: 30px; border-width: 4px; border-color: #00ff00; } .corner-top-left { top: -4px; left: -4px; border-left-style: solid; border-top-style: solid; border-radius: 4px 0 0 0; } .corner-top-right { top: -4px; right: -4px; border-right-style: solid; border-top-style: solid; border-radius: 0 4px 0 0; } .corner-bottom-left { bottom: -4px; left: -4px; border-left-style: solid; border-bottom-style: solid; border-radius: 0 0 0 4px; } .corner-bottom-right { bottom: -4px; right: -4px; border-right-style: solid; border-bottom-style: solid; border-radius: 0 0 4px 0; } .scan-tip { position: absolute; bottom: 500rpx; left: 0; right: 0; text-align: center; color: #fff; font-size: 16px; padding: 10px; border-radius: 8px; } .torch-control { position: absolute; bottom: 300rpx; right: 100rpx; text-align: center; background: rgba(193, 200, 210, .4); border-radius: 50px; width: 100rpx; height: 100rpx; display: flex; align-items: center; justify-content: center; .torch-control-icon { width: 60rpx; height: 60rpx; } } .torch-text { color: #fff; font-size: 16px; // background-color: rgba(0, 0, 0, 0.7); padding: 10px 20px; border-radius: 25px; cursor: pointer; } .result-container { width: 100%; text-align: center; padding: 20px; background-color: #fff; border-radius: 12px; margin-bottom: 20px; } .result-title { font-size: 20px; font-weight: bold; margin-bottom: 15px; } .result-content { font-size: 16px; margin-bottom: 20px; word-break: break-all; min-height: 60px; display: flex; align-items: center; justify-content: center; border: 1px solid #eee; padding: 10px; border-radius: 8px; } .result-button, .permission-button { background-color: #007aff; color: #fff; border: none; padding: 12px 20px; border-radius: 25px; font-size: 16px; width: 100%; margin-top: 15px; cursor: pointer; } .album-button { position: absolute; bottom: 300rpx; left: 100rpx; background: rgba(193, 200, 210, .4); border-radius: 50px; width: 100rpx; height: 100rpx; display: flex; align-items: center; justify-content: center; .album-img { width: 60rpx; height: 60rpx; } } .error-tip { color: #ff3b30; font-size: 14px; margin-top: 15px; position: absolute; bottom: 400rpx; left: 0; right: 0; } .permission-modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; // background-color: rgba(0, 0, 0, 0.7); display: flex; justify-content: center; align-items: center; z-index: 1000; } .permission-content { background-color: #fff; border-radius: 12px; padding: 30px 20px; width: 80%; max-width: 350px; text-align: center; } .permission-title { font-size: 18px; font-weight: bold; margin-bottom: 15px; } .permission-desc { font-size: 16px; margin-bottom: 25px; color: #666; } /* 隐藏的Canvas */ .hidden-canvas { position: absolute; top: -9999px; width: 300px; height: 300px; visibility: hidden; } @keyframes scan { 0% { transform: translateY(0); } 100% { transform: translateY(250px); } } </style>这段代码按照上述需求怎么修改,报错,vue3+uniapp开发的微信小程序,使用扫一扫,支持扫描相册中的图片
06-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值