Javascript HTML5画布:在图像上绘制的文本在图像更改时停止显示

Javascript HTML5画布:在图像上绘制的文本在图像更改时停止显示,javascript,jquery,css,canvas,html5-canvas,Javascript,Jquery,Css,Canvas,Html5 Canvas,因此,我有一个简单的图像编辑器,我使用画布绘制用户选择的图像和一些文本。也就是说,用户可以上传一幅图像,然后如果他们愿意,他们可以添加文本或只是改变图像的梯度 现在这个应用程序运行得非常好,只是有一个问题 如何发现问题?请执行以下操作: 上传一张随机图片 在输入字段中键入一些内容 上传并更改图像 您将看到文本消失 代码如下: const canvasTxt=window.canvasTxt.default; const canvas=document.getElementById('canva

因此,我有一个简单的图像编辑器,我使用画布绘制用户选择的图像和一些文本。也就是说,用户可以上传一幅图像,然后如果他们愿意,他们可以添加文本或只是改变图像的梯度

现在这个应用程序运行得非常好,只是有一个问题

如何发现问题?请执行以下操作:

  • 上传一张随机图片
  • 在输入字段中键入一些内容
  • 上传并更改图像
  • 您将看到文本消失

    代码如下:

    const canvasTxt=window.canvasTxt.default;
    const canvas=document.getElementById('canvas');
    const ctx=canvas?.getContext('2d');
    const btnDownload=document.querySelector('.btnDownload');
    const fileUpload=document.querySelector('.file upload');
    const text1=document.getElementById('text1');
    const textForm1=document.getElementById('text1-form');
    const text2=document.getElementById('text2');
    const textForm2=document.getElementById('text2-form');
    const text2ShadowColor=document.getElementById('text2ShadowColor');
    const text2ShadowOffsetY=document.getElementById('text2shadowoffy');
    const imageForm=document.getElementById('image-form');
    const imageGrad=document.getElementById('gradientcolor');
    const imagegradeopacity=document.getElementById('gradientopacity');
    $(fileUpload).on('change',函数(e){
    设imgObj=新图像();
    imgObj.onload=绘图;
    imgObj.onerror=失败;
    imgObj.src=URL.createObjectURL(this.files[0]);
    imgManipulation(e,imgObj);
    });    
    常量imgManipulation=(e,imgObj)=>{
    $(textForm1).on('change keyup input',updateCanvas);
    $(textForm2).on('change keyup input',updateCanvas);
    $(imageForm).on('change keyup input',updateCanvas');
    函数updateCanvas(e){
    e、 预防默认值();
    clearRect(0,0,canvas.width,canvas.height);
    ctx.drawImage(imgObj,0,0);
    createGradient($(imageGrad.val(),$(imageGradOpacity.val());
    //TEXT1基于用户输入的样式
    canvasTxt.fontSize=70;
    ctx.fillStyle=“白色”;
    canvasTxt.drawText(
    ctx,
    $(text1.val(),
    0, 
    0, 
    200, 
    200
    );
    //文本2样式
    canvasTxt.font=50;
    ctx.fillStyle=“白色”;
    canvasTxt.drawText(
    ctx,
    $(text2.val(),
    20, 
    20, 
    200, 
    200
    );
    }
    };
    函数hexToRgb(hex){
    var result=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(十六进制);
    返回结果{
    r:parseInt(结果[1],16),
    g:parseInt(结果[2],16),
    b:parseInt(结果[3],16)
    }:null;
    };
    函数createGradient(十六进制,alpha){
    常数r=hexToRgb(hex).r.toString();
    常数g=hexToRgb(hex).g.toString();
    常数b=hexToRgb(hex).b.toString();
    var gradient=ctx.createLinearGradient(800,0,0,0);
    addColorStop(0,`rgba(${r},${g},${b},${alpha})`);
    
    ctx.save()//出现计时问题

    在此代码中:

    $(fileUpload).on('change', function(e) {
          let imgObj          = new Image();
          imgObj.onload       = draw;
          imgObj.onerror      = failed;
          imgObj.src          = URL.createObjectURL(this.files[0]);
    
          imgManipulation( e, imgObj );
    });
    
    您要求在加载图像时执行draw函数。然后调用imgManipulation,它将正确地绘制文本,但在图像有机会加载之前立即调用。因此它写入文本(仍保存在输入元素中)但当加载图像并调用draw时,这会被覆盖

    由于draw只是将图像写入画布,而大多数图像都会覆盖包含文本的画布顶部

    因此,在加载新图像时,需要更新整个画布,包括文本

    注意:每次用户选择一个新图像时,都会创建一个新的img元素。最好只使用一个图像元素并指定新的源,否则长时间的用户会话可能会不必要地填满存储空间

    此代码段通过在加载新映像时设置超时并在发生超时时调用画布更新来说明计时问题。显然,对于生产版本,重构代码以便在加载(或已加载)的映像上进行更新是明智的

    text2的fontSize设置中还有一个问题,它试图将字体设置为50-这影响了后续重画时使用的fontSize,因此它已被更改为fontSize。text2还覆盖了text1的一部分,但这是另一个问题

    const canvasTxt=window.canvasTxt.default;
    const canvas=document.getElementById('canvas');
    const ctx=canvas?.getContext('2d');
    const btnDownload=document.querySelector('.btnDownload');
    const fileUpload=document.querySelector('.file upload');
    const text1=document.getElementById('text1');
    const textForm1=document.getElementById('text1-form');
    const text2=document.getElementById('text2');
    const textForm2=document.getElementById('text2-form');
    const text2ShadowColor=document.getElementById('text2ShadowColor');
    const text2ShadowOffsetY=document.getElementById('text2shadowoffy');
    const imageForm=document.getElementById('image-form');
    const imageGrad=document.getElementById('gradientcolor');
    const imagegradeopacity=document.getElementById('gradientopacity');
    让imgObj