You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHPRad项目中Canvas背景图不显示及按钮误提交表单问题求助

PHPRad中Canvas使用问题的解决方案

问题说明

  • 自定义视图添加的Script未生效,Canvas背景的线上图片完全不显示
  • 点击「Free Drawing」和「Remove」按钮时,即使添加了event.preventDefault(),仍会自动提交表单

原代码参考

JS代码

alert('testing if the script is well connected')

const canvas = document.getElementById(\"corolla-canvas\");
const ctx = canvas.getContext(\"2d\");

const img = new Image();
img.src = \"https://i.ibb.co/QF5k508/Removal-69.png\";
img.onload = function () {
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};

let isDrawing = false;
let isErasing = false;

const drawButton = document.getElementById(\"corollax-draw\");
const removeButton = document.getElementById(\"corollax-remove\");

drawButton.addEventListener(\"click\", function () {
  removeButton.disabled = false;
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  canvas.addEventListener(\"mousedown\", startDrawing);
  canvas.addEventListener(\"mousemove\", draw);
  canvas.addEventListener(\"mouseup\", endDrawing);
});

removeButton.addEventListener(\"click\", function () {
  drawButton.disabled = false;
  ctx.globalCompositeOperation = \"destination-out\";
  canvas.addEventListener(\"mousedown\", startErasing);
  canvas.addEventListener(\"mousemove\", erase);
  canvas.addEventListener(\"mouseup\", endErasing);
});

function startDrawing(e) {
  isDrawing = true;
  ctx.beginPath();
  ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
}

function draw(e) {
  if (isDrawing) {
    ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
    ctx.stroke();
  }
}

function endDrawing(e) {
  isDrawing = false;
}

function startErasing(e) {
  isErasing = true;
  ctx.beginPath();
  ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
}

function erase(e) {
  if (isErasing) {
    ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
    ctx.stroke();
  }
}

function endErasing(e) {
  isErasing = false;
  ctx.globalCompositeOperation = \"source-over\";
}

drawButton.addEventListener(\"click\", function (event) {
  event.preventDefault();
  removeButton.disabled = false;
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  canvas.addEventListener(\"mousedown\", startDrawing);
  canvas.addEventListener(\"mousemove\", draw);
  canvas.addEventListener(\"mouseup\", endDrawing);
});

removeButton.addEventListener(\"click\", function (event) {
  event.preventDefault();
  drawButton.disabled = false;
  ctx.globalCompositeOperation = \"destination-out\";
  canvas.addEventListener(\"mousedown\", startErasing);
  canvas.addEventListener(\"mousemove\", erase);
  canvas.addEventListener(\"mouseup\", endErasing);
});

HTML代码

<div class=\"canvases\">
                <!-- Corolla Canvas -->
                <div class=\"corolla-canvas\">
                  <input type=\"hidden\" name=\"corolla_data\" value=\"\" />
                  <div class=\"buttons-container\">
                    <button id=\"corollax-draw\" class=\"form-button\">
                      Free Drawing
                    </button>
                    <button id=\"corollax-remove\" disabled=\"disabled\">Remove</button>
                  </div>
                  <canvas
                    id=\"corolla-canvas\"
                    width=\"650px\"
                    height=\"330px\"
                    name=\"corolla_data\"
                  ></canvas>
                </div>
                  </canvas>
                </div>

分步解决方案

1. 解决Canvas图片不显示 & Script未生效问题

  • DOM加载时机修正:JS代码要等DOM完全加载后再执行,否则可能找不到Canvas元素。用DOMContentLoaded事件包裹所有JS逻辑。
  • Canvas属性修正:Canvas的width和height属性不需要加px单位,直接写数值即可,否则会导致绘制尺寸异常。
  • 图片加载优化:添加img.crossOrigin = "anonymous"确保跨域图片能正常加载,同时增加onerror事件排查加载失败原因。
  • 移除重复事件绑定:原代码给按钮重复绑定了两次click事件,导致逻辑冲突,合并成一次绑定即可。

2. 解决按钮自动提交表单问题

  • 设置按钮类型:HTML中button默认类型是submit,在表单内点击会触发提交。给按钮加上type="button",从根源避免默认提交行为。
  • 确保preventDefault()生效:合并重复的事件绑定后,event.preventDefault()会在唯一的click事件处理中执行,避免因重复绑定导致的失效。

修正后的完整代码

HTML代码

<div class="canvases">
    <!-- Corolla Canvas -->
    <div class="corolla-canvas">
        <input type="hidden" name="corolla_data" value="" />
        <div class="buttons-container">
            <!-- 添加type="button"防止默认提交 -->
            <button id="corollax-draw" class="form-button" type="button">
                Free Drawing
            </button>
            <button id="corollax-remove" disabled="disabled" type="button">Remove</button>
        </div>
        <!-- 移除width/height的px单位 -->
        <canvas
            id="corolla-canvas"
            width="650"
            height="330"
            name="corolla_data"
        ></canvas>
    </div>
</div>
<!-- 移除原HTML中多余的闭合标签 -->

JS代码

// 等待DOM加载完成后执行脚本
document.addEventListener('DOMContentLoaded', function() {
    alert('testing if the script is well connected');

    const canvas = document.getElementById("corolla-canvas");
    if (!canvas) {
        console.error('Canvas元素未找到');
        return;
    }
    const ctx = canvas.getContext("2d");

    const img = new Image();
    // 允许跨域加载图片
    img.crossOrigin = "anonymous";
    img.src = "https://i.ibb.co/QF5k508/Removal-69.png";
    
    img.onload = function () {
        console.log('图片加载成功');
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    };
    
    img.onerror = function() {
        console.error('图片加载失败,请检查地址或跨域设置');
    };

    let isDrawing = false;
    let isErasing = false;

    const drawButton = document.getElementById("corollax-draw");
    const removeButton = document.getElementById("corollax-remove");

    // 绘制按钮点击逻辑(只绑定一次)
    drawButton.addEventListener("click", function (event) {
        event.preventDefault();
        removeButton.disabled = false;
        
        // 图片加载完成后再重绘背景
        if (img.complete) {
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        }

        // 移除擦除相关事件,避免冲突
        canvas.removeEventListener("mousedown", startErasing);
        canvas.removeEventListener("mousemove", erase);
        canvas.removeEventListener("mouseup", endErasing);
        
        // 添加绘制事件监听
        canvas.addEventListener("mousedown", startDrawing);
        canvas.addEventListener("mousemove", draw);
        canvas.addEventListener("mouseup", endDrawing);
    });

    // 擦除按钮点击逻辑(只绑定一次)
    removeButton.addEventListener("click", function (event) {
        event.preventDefault();
        drawButton.disabled = false;
        ctx.globalCompositeOperation = "destination-out";

        // 移除绘制相关事件,避免冲突
        canvas.removeEventListener("mousedown", startDrawing);
        canvas.removeEventListener("mousemove", draw);
        canvas.removeEventListener("mouseup", endDrawing);
        
        // 添加擦除事件监听
        canvas.addEventListener("mousedown", startErasing);
        canvas.addEventListener("mousemove", erase);
        canvas.addEventListener("mouseup", endErasing);
    });

    // 绘制相关函数
    function startDrawing(e) {
        isDrawing = true;
        ctx.beginPath();
        ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
    }

    function draw(e) {
        if (isDrawing) {
            ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
            ctx.stroke();
        }
    }

    function endDrawing(e) {
        isDrawing = false;
    }

    // 擦除相关函数
    function startErasing(e) {
        isErasing = true;
        ctx.beginPath();
        ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
    }

    function erase(e) {
        if (isErasing) {
            ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
            ctx.stroke();
        }
    }

    function endErasing(e) {
        isErasing = false;
        ctx.globalCompositeOperation = "source-over";
    }
});

内容的提问来源于stack exchange,提问作者Tshepo Moeletsi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:37:00