假设我要把下面这张图片绘制到canvas上
方法1
代码如下
调用的是canvas drawImage(img, x, y)方法
img是要绘制的图片,绘制到画布的x,y位置
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>canvas一些知识</title>
</head>
<body>
<p>要使用的图片:</p>
<img id="img1" src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1597829802835&di=26c2e23a5cd92357989f923a4a14c5b8&imgtype=0&src=http%3A%2F%2Fb.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2F09fa513d269759ee14f75c95b3fb43166c22dfcc.jpg">
<p>画布:</p>
<canvas id="myCanvas" width="600" height="400" style="border:1px solid #d3d3d3;"> 您的浏览器不支持 HTML5 canvas 标签。
</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("img1");
img.onload = function () {
ctx.drawImage(img, 10, 10);
}
</script>
</body>
</html>
绘制结果
没有绘制完全,因为画布比原图小
方法2
那我们可以规定一下绘制到画布的大小
调用的是canvas drawImage(img, x, y,width, height)方法
// 前略。。。
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("img1");
img.onload = function () {
ctx.drawImage(img, 10, 10, 400, 300);
}
</script>
// 后略。。。
效果如下
那如果我只想绘制红框部分到画布呢?
方法3
调用方法和定义如下
// 前略。。。
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("img1");
img.onload = function () {
ctx.drawImage(img, 180, 120, 690, 570, 0, 0, 400, 300);
}
</script>
// 后略。。。
效果
拓展1
现在我们知道可以绘制原图的一部分到画布了
在我们开发过程中,经常会使用图集(精灵图)做加载优化
比如游戏的技能图标图集
然后有一个文件来记录每张图在图集中的位置
那我们就可以分别把每个图标绘制到画布上了
{"file":"skillimg.png","frames":{
"skill5304":{"x":57,"y":228,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5305":{"x":0,"y":228,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5501":{"x":171,"y":171,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5502":{"x":114,"y":171,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5503":{"x":57,"y":171,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5504":{"x":0,"y":171,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5505":{"x":171,"y":114,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5601":{"x":114,"y":114,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5602":{"x":57,"y":114,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5603":{"x":0,"y":114,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5604":{"x":171,"y":57,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5605":{"x":114,"y":57,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5301":{"x":57,"y":57,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5302":{"x":0,"y":57,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"skill5303":{"x":171,"y":0,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"dominateskill1":{"x":114,"y":0,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"dominateskill2":{"x":57,"y":0,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55},
"dominateskill3":{"x":0,"y":0,"w":55,"h":55,"offX":0,"offY":0,"sourceW":55,"sourceH":55}}}
拓展2
我们还可以实现序列帧动画
只要定时按顺序绘制图片即可
比如下面例子
记录每一帧的位置的文件
"mc": {
"r": {
"frameRate": 12,
"frames": [
{ "res": "155", "x": -72, "y": -115 },
{ "res": "156", "x": -72, "y": -116 },
{ "res": "157", "x": -75, "y": -114 },
{ "res": "158", "x": -76, "y": -113 },
{ "res": "159", "x": -74, "y": -115 },
{ "res": "160", "x": -74, "y": -117 },
{ "res": "161", "x": -74, "y": -116 },
{ "res": "162", "x": -73, "y": -112 }
]
}
},
"res": {
"155": { "x": 0, "y": 0, "w": 111, "h": 121 },
"156": { "x": 111, "y": 0, "w": 111, "h": 124 },
"157": { "x": 222, "y": 0, "w": 113, "h": 126 },
"158": { "x": 335, "y": 0, "w": 122, "h": 130 },
"159": { "x": 457, "y": 0, "w": 116, "h": 132 },
"160": { "x": 573, "y": 0, "w": 109, "h": 130 },
"161": { "x": 682, "y": 0, "w": 110, "h": 127 },
"162": { "x": 792, "y": 0, "w": 117, "h": 120 }
}
代码
// 前略。。。
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
var oldTime = 0;
var index = 0;
img.onload = function () {
let frameTime = 1000 / frameData.mc.r.frameRate;
let frames = frameData.mc.r.frames;
requestAnimationFrame(next);
function next() {
let curTime = new Date().getTime();
if (curTime - oldTime > frameTime) {
oldTime = curTime
index++;
if (index > frames.length - 1) {
index = 0;
}
ctx.clearRect(0, 0, c.width, c.height);
let res = frameData.res[frames[index].res];
ctx.drawImage(img, res.x, res.y, res.w, res.h, frames[index].x + 200, frames[index].y + 200, res.w, res.h);
}
requestAnimationFrame(next);
}
}
let frameData = {
"mc": {
"r": {
"frameRate": 12,
"frames": [
{ "res": "155", "x": -72, "y": -115 },
{ "res": "156", "x": -72, "y": -116 },
{ "res": "157", "x": -75, "y": -114 },
{ "res": "158", "x": -76, "y": -113 },
{ "res": "159", "x": -74, "y": -115 },
{ "res": "160", "x": -74, "y": -117 },
{ "res": "161", "x": -74, "y": -116 },
{ "res": "162", "x": -73, "y": -112 }
]
}
},
"res": {
"155": { "x": 0, "y": 0, "w": 111, "h": 121 },
"156": { "x": 111, "y": 0, "w": 111, "h": 124 },
"157": { "x": 222, "y": 0, "w": 113, "h": 126 },
"158": { "x": 335, "y": 0, "w": 122, "h": 130 },
"159": { "x": 457, "y": 0, "w": 116, "h": 132 },
"160": { "x": 573, "y": 0, "w": 109, "h": 130 },
"161": { "x": 682, "y": 0, "w": 110, "h": 127 },
"162": { "x": 792, "y": 0, "w": 117, "h": 120 }
}
}
img.src = "r.png"
</script>
// 后略。。。
效果