JavaScript: 解决了<el-image>频繁加载图片出现白色边框问题

本文探讨了在频繁图片切换中遇到的canvas闪屏问题,通过引入双缓存技术解决清空画布导致的视觉延迟。同时,介绍了如何将图片缩放至canvas大小的方法,以提高用户体验。

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

问题描述

当频繁加载图片并渲染的时候,出现加载渲染图片的控件在两张图片切换的过程中出现白色闪烁的问题。

问题排查

查看源代码后,发现html中用 元素来显示图片的。 并且通过改变:src="jpgPath"的值来替换图片。
在这里插入图片描述
在这里插入图片描述

解决方法:

临时解决方法: 用canvas 绘制图片的方式来代替 。
新问题: 1. canvas 直接不断的绘制image,会出现闪屏的问题。
解决方法:使用双缓存解决 Canvas clearRect 引起的闪屏问题 : 使用双缓存解决问题

updateCanvas(){
    const canvas = document.getElementById('canvas'); // 获取页面中的 canvas
    const ctx = canvas.getContext('2d');
    
    const tempCanvas = document.createElement('canvas'); // 新建一个 canvas 作为缓存 canvas
    const tempCtx = tempCanvas.getContext('2d');
    tempCanvas.width = 1448; tempCanvas.height = 750; // 设置宽高
 
    // 开始绘制
    tempCtx.drawImage(bg,0,0); // 背景
    ... // 省略其他绘制过程
    
    // 缓存 canvas 绘制完成
    
    ctx.clearRect(0,0,1448,750); // 清空旧 canvas
    ctx.drawImage(tempCanvas,0,0); // 将缓存 canvas 复制到旧的 canvas
}

总结
重绘画布的时候,我们需要使用 clearRect 来清空画布,此时的画布是空的,开始重绘后,如果内容较多,时间也就相应的增加,因此视觉出现了空档期,我们就看到了闪屏的情况;
解决闪屏,其实就是怎么解决绘制时间较长的问题;
这里参考了图形图象处理编程中 双缓存 的概念,将绘制过程交给了 缓存 canvas,这样页面中的 canvas 就省去了绘制过程,而 缓存 canvas 并没有添加到页面,所以我们就看不到绘制过程,也就解决了闪屏的问题。

问题2 : 如何把图片缩放到canvas的大小
解决方法:在drawImage后面多添加两个参数值:canvas.width,canvas.height 就可以了。

 tempCtx.drawImage(img1,0,0,canvas.width,canvas.height);
 ctx.clearRect(0,0,canvas.width,canvas.height);
 ctx.drawImage(tempCanvas,0,0,canvas.width,canvas.height);

最终代码:

在这里插入图片描述

updateCanvas(jpgPath) {
                const canvas = document.getElementById('canvasImage');
                const ctx = canvas.getContext('2d');
                //canvas.width = 400;
                //canvas.height = 400;
                //canvas.style.border = '1px solid #ccc';

                const tempCanvas = document.createElement('canvas');
                const tempCtx = tempCanvas.getContext('2d');
                //tempCanvas.width = 400;
                //tempCanvas.height = 400;

                var img1 = new Image();
                img1.src= jpgPath;//只要设置了src属性,当前img对象立即去加载图片。
                //第二步,图片加载完成后,把图片绘制到canvas上
                img1.onload = function() {
                    tempCtx.drawImage(img1,0,0,canvas.width,canvas.height);

                    ctx.clearRect(0,0,canvas.width,canvas.height);
                    ctx.drawImage(tempCanvas,0,0,canvas.width,canvas.height);
                   
                };

                


            },
  // 获取当前帧的jpg路径
            getPicPath() {
                let _this = this;
                axios.get(this.apiUrl + '/get_frame_jpg')
                    .then(function (response) {
                        console.log(response.data.data.pcdPath);
                        _this.jpgPath = _this.pcdUrl + response.data.data.jpgPath
                        
                        _this.updateCanvas(_this.jpgPath);  //核心,就是改为canvas绘制图片。
                    })
                    .catch(function (error) {
                         console.log(2,error);
                    });
            },
<template> <div class="information_table-body animate__animated animate__fadeInDown"> <div class="animate__animated animate__fadeInDown t-borderStyle information_table"> <div class="t-chart-title" style="margin-bottom: 20px">人员考勤明细</div> <i class="el-icon-close close-table" @click="clear"></i> <div class="history-box"> <div class="t-table-title" style="margin-top: 6px"> <div class="title-num">序号</div> <div class="title-number-to title-num">姓名</div> <div class="title-number-to title-num" style="width: 120px;">身份证号</div> <div class="title-number-to title-num">打卡间</div> <!-- <div class="title-number-to title-num">打卡照片</div> --> <div class="title-number-to title-num">进出场</div> <div class="title-number-to title-num">工(小)</div> <div class="title-number-to title-num">合计工</div> </div> <div class="table-body table-body-information"> <div v-for="(employee, empIndex) in list" :key="empIndex" class="t-table-row"> <!-- 员工基础信息 --> <div class="title-number">{{ empIndex + 1 }}</div> <div class="title-number-to title-num">{{ employee.name }}</div> <div class="title-number-to title-num" style="width: 120px">{{ maskIdNumber(employee.identityNumber) }}</div> <!-- 打卡记录循环 --> <div v-for="(record, index) in employee.records" :key="index" class="sub-row"> <div class="title-number-to title-num">{{ record.dateTime }}</div> <!-- <div class="title-number-to title-num"> <el-image v-if="record.photo" style="width: 80px" :src="record.photo" /> </div> --> <div class="title-number-to title-num">{{ record.type }}</div> <div class="title-number-to title-num">{{ record.workHours }}</div> </div> <!-- 合计行 --> <div class="t-table-row total-row"> <div class="title-number-to title-nu
03-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值