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

如何在自定义GIF上方用JavaScript绘制图形及其他图片?

问题描述

我有一段JavaScript代码,可在DOM中绘制随机方形元素,但这些元素始终显示在GIF图片下方。我尝试设置z-index等布局参数来将元素置于图片上方,但并未产生任何效果。

恳请协助实现点击时在该GIF上方绘制元素的效果;我最终还希望能在GIF的指定区域内,点击绘制其他各类图片,若能提供这部分的解决方案我将万分感激!

(代码包含过往尝试遗留的未使用元素)


现有代码

HTML 文件

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="div.css" />
</head>
<body>
    <div style="cursor: pointer;" id="boxy" >
        <img src="bg.gif" alt="unfinished bingo card" onclick="create()" />
    </div>
</div>
    <script>
        var body = document.getElementsByTagName("body")[0];
        var canvas = document.createElement("canvas");
        canvas.height = 1300;
        canvas.width = 1300;
        var context = canvas.getContext("2d");
        body.appendChild(canvas);

        var rects = [];

        function create() {
            //  Opacity
            context.globalAlpha = 0.7;
            var color = '#' + Math.round(0xffffff * Math.random()).toString(16);
            context.fillStyle = color;

            //Each rectangle's size is (20 ~ 100, 20 ~ 100)
            var coordx = Math.random() * canvas.width;
            var coordy = Math.random() * canvas.width;
            var width = Math.random() * 80 + 20;
            var height = Math.random() * 80 + 20;

            var rect = {
                x: coordx,
                y: coordy,
                w: width,
                h: height
            }

            var ok = true;
            rects.forEach(function (item) {
                if (isCollide(rect, item)) {
                    console.log("collide");
                    ok = false;
                } else {
                    console.log("no collision");
                }
            })

            if (ok) {
                context.fillRect(coordx, coordy, width, height);
                rects.push(rect);
            } else {
                console.log('rect dropped');
            }

            console.log(rects);
        }

        function isCollide(a, b) {
            return !(
                ((a.y + a.h) < (b.y)) ||
                (a.y > (b.y + b.h)) ||
                ((a.x + a.w) < b.x) ||
                (a.x > (b.x + b.w))
            );
        }
        document.getElementById('boxy').addEventListener('click', create);
        document.getElementById('canvas').style.position = "relative";
        document.getElementById('canvas').style.zIndex = "10";
    </script>
</body>
</html>

div.css 文件

#my-div {
    width: 1300px;
    height: 1300px;
    z-index: -1;
}
a.fill-div {
    display: block;
    height: 100%;
    width: 100%;
    text-decoration: none;
}

#boxy {
    display: inline-block;
    height: 100%;
    width: 100%;
    text-decoration: none;
    z-index: -1;
}

.canvas {
    display: inline-block;
    height: 100%;
    width: 100%;
    text-decoration: none;
    z-index: 10;
}

解决方案

一、让Canvas元素显示在GIF上方

问题根源有两点:

  1. 动态创建的Canvas未设置id="canvas",导致后续通过getElementById设置样式的代码无效
  2. Canvas与GIF的布局未做层级绑定,无法实现覆盖效果

修改步骤:

  1. 给动态创建的Canvas添加id:
canvas.id = "canvas";
  1. 设置Canvas的绝对定位,让它覆盖在GIF容器上方:
canvas.style.position = "absolute";
canvas.style.top = "0";
canvas.style.left = "0";
canvas.style.zIndex = "10";
  1. 修改#boxy的CSS,设置为相对定位作为Canvas的定位参考:
#boxy {
    display: inline-block;
    position: relative;
    height: 100%;
    width: 100%;
    text-decoration: none;
}

二、在GIF指定区域内绘制图片

要实现点击指定区域绘制图片,需完成以下操作:

  1. 获取点击位置相对于GIF的坐标
  2. 判断点击是否在目标区域内
  3. 在对应位置绘制目标图片

具体代码修改

首先更新create函数,处理点击坐标与区域判断:

function create(e) {
    const img = document.querySelector('#boxy img');
    // 获取GIF的视口位置,计算点击相对坐标
    const imgRect = img.getBoundingClientRect();
    const clickX = e.clientX - imgRect.left;
    const clickY = e.clientY - imgRect.top;

    // 定义GIF上的指定区域(示例为中间500x500区域)
    const targetArea = {
        x: (img.width - 500) / 2,
        y: (img.height - 500) / 2,
        w: 500,
        h: 500
    };

    // 判断点击是否在指定区域内
    if (clickX >= targetArea.x && clickX <= targetArea.x + targetArea.w &&
        clickY >= targetArea.y && clickY <= targetArea.y + targetArea.h) {
        // 创建并加载要绘制的图片
        const drawImg = new Image();
        drawImg.src = 'your-target-image.png'; // 替换为你的图片路径
        drawImg.onload = function() {
            // 在点击位置绘制图片(可自定义尺寸)
            context.drawImage(drawImg, clickX - 25, clickY - 25, 50, 50);
        };
    } else {
        // 不在指定区域时,继续绘制随机方形(可选保留)
        context.globalAlpha = 0.7;
        const color = '#' + Math.round(0xffffff * Math.random()).toString(16);
        context.fillStyle = color;
        const width = Math.random() * 80 + 20;
        const height = Math.random() * 80 + 20;
        // 确保方形在GIF范围内
        context.fillRect(clickX - width/2, clickY - height/2, width, height);
    }
}

同时,确保Canvas尺寸与GIF一致,避免坐标偏差:

// 等GIF加载完成后同步Canvas尺寸
const img = document.querySelector('#boxy img');
img.onload = function() {
    canvas.width = img.width;
    canvas.height = img.height;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:30:22