ZetCode

JavaScript Canvas drawImage 教程

最后修改于 2025 年 4 月 3 日

在本文中,我们将探讨 JavaScript 中的 Canvas drawImage 方法。此方法对于在 HTML canvas 元素上绘制图像至关重要。掌握 drawImage 方法是创建丰富图形和可视化效果的关键。

基本定义

drawImage 方法允许您将图像、视频或其他 canvas 元素绘制到 canvas 上。它提供了多种重载方法以适应不同的用例。您可以绘制整个图像,也可以只绘制其一部分。

该方法可以对 Canvas 上的图像进行缩放、裁剪和定位。它适用于 HTMLImageElement、HTMLVideoElement、HTMLCanvasElement 和 ImageBitmap。

基本图像绘制

此示例演示了如何在 Canvas 上绘制简单图像。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Basic Canvas drawImage</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    const img = new Image();
    img.src = 'image.jpg';
    
    img.onload = function() {
        ctx.drawImage(img, 50, 50);
    };
</script>

</body>
</html>

在此基本示例中,我们创建一个 canvas 元素并获取其 2D 渲染上下文。我们创建一个 Image 对象并将其源设置为“image.jpg”。

drawImage 方法在图像加载后将其绘制在 (50,50) 的位置。这展示了在 Canvas 上绘制图像的最简单方法。

缩放图像

此示例展示了如何在绘制图像时对其进行缩放。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Scaling Image</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    const img = new Image();
    img.src = 'image.jpg';
    
    img.onload = function() {
        // Draw image scaled to 200x150
        ctx.drawImage(img, 50, 50, 200, 150);
    };
</script>

</body>
</html>

在这里,我们使用了 drawImage 的扩展版本,其中包括宽度和高度参数。图像将被缩放到适合这些尺寸。

原始图像绘制在 (50,50) 的位置,但调整为 200 像素宽和 150 像素高。这演示了 Canvas 上的基本图像缩放。

裁剪并绘制图像的一部分

此示例演示了如何裁剪并绘制图像的一部分。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Cropping Image</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="300"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    const img = new Image();
    img.src = 'image.jpg';
    
    img.onload = function() {
        // Draw a 100x100 portion of the image starting at (20,20)
        // Then scale it to 200x200 on canvas at (50,50)
        ctx.drawImage(img, 20, 20, 100, 100, 50, 50, 200, 200);
    };
</script>

</body>
</html>

此示例使用了 drawImage 中参数最多的九个参数的版本。它裁剪源图像的一部分,并将其缩放后绘制到 Canvas 上。

图像后的前四个参数指定源矩形(裁剪区域)。后四个参数指定目标矩形(位置和大小)。

绘制视频帧

此示例展示了如何将视频帧绘制到 Canvas 上。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Video to Canvas</title>
</head>
<body>

<video id="myVideo" width="320" height="240" controls>
    <source src="movie.mp4" type="video/mp4">
</video>
<canvas id="myCanvas" width="320" height="240"></canvas>

<script>
    const video = document.getElementById('myVideo');
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    video.addEventListener('play', function() {
        function drawFrame() {
            if (video.paused || video.ended) return;
            
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
            requestAnimationFrame(drawFrame);
        }
        drawFrame();
    });
</script>

</body>
</html>

此示例捕获视频帧并实时将其绘制到 Canvas 上。我们为 play 事件添加了一个事件监听器以启动绘制过程。

drawFrame 函数使用 drawImage 将当前视频帧复制到 Canvas。它使用 requestAnimationFrame 继续绘制帧。

创建精灵表动画

此示例演示了如何从精灵表中创建动画。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Sprite Animation</title>
</head>
<body>

<canvas id="myCanvas" width="200" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    const spriteSheet = new Image();
    spriteSheet.src = 'sprites.png';
    
    let frame = 0;
    const frameWidth = 50;
    const frameHeight = 50;
    const totalFrames = 8;
    
    spriteSheet.onload = function() {
        setInterval(animate, 100);
    };
    
    function animate() {
        // Clear canvas
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        // Calculate current frame position
        const sx = (frame % 4) * frameWidth;
        const sy = Math.floor(frame / 4) * frameHeight;
        
        // Draw current frame
        ctx.drawImage(
            spriteSheet,
            sx, sy, frameWidth, frameHeight,
            75, 75, frameWidth, frameHeight
        );
        
        // Advance to next frame
        frame = (frame + 1) % totalFrames;
    }
</script>

</body>
</html>

此示例通过循环浏览精灵表的帧来创建动画。精灵表假定为 4 列 2 行的帧网格。

animate 函数计算每帧的源位置,并将其居中绘制在 Canvas 上。动画每 100 毫秒循环一次。

来源

MDN Canvas drawImage 文档

在本文中,我们探讨了在 HTML Canvas 上绘制图像的各种技术。掌握 drawImage 方法对于在 Web 应用程序中创建丰富的图形和动画至关重要。

作者

我叫 Jan Bodnar,是一名热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出 所有 JS Canvas 教程