《HTML5游戏编程核心技术与实战》一2.4 坐标变换

简介: 在绘制图像的过程中,经常可能需要对图像进行旋转、缩放等变形处理,canvas也提供了一系列的API帮助我们完成这些操作。

本节书摘来异步社区《HTML5游戏编程核心技术与实战》一书中的第2章,第2.4节,作者: 向峰 责编: 杨海玲,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.4 坐标变换

HTML5游戏编程核心技术与实战
在绘制图像的过程中,经常可能需要对图像进行旋转、缩放等变形处理,canvas也提供了一系列的API帮助我们完成这些操作。

关于画布的坐标变换,canvas提供了以下常用的API,这些API的操作必须要在绘制之前调用,否则不会产生任何效果。

translate (x, y):平移,把画布的原点坐标移动到(x, y)位置,x表示将坐标原点向左移x个像素,y表示将坐标原点向下移动y个像素。正常情况下canvas的原点坐标位于左上角,那么我们可以通过translate方法移动原点的坐标,比如以下代码就把原点坐标移动到了canvas的中间位置:

context.translate(canvas.width0.5, canvas.height0.5);

scale (x, y):缩放,把画布放大。x表示水平方向放大倍数,y表示垂直方向放大倍数,如果需要缩小,将这两个参数设置为0~1之间的数就可以了,比如context.scale (0.5, 0.5)表示把图形缩小一半。
rotate (angle):把图形进行旋转。angle表示旋转的角度,旋转的中心点是原点,旋转是以顺时针方向进行,angle设置成负数就是逆时针旋转。需要注意的是angle是以弧度表示,比如要顺时针旋转90度可以使用context.rotate (Math.PI*0.5)。
transform (m11, m12, m21, m22, dx, dy):把当前的矩阵乘上如图2-20所示的矩阵,做矩阵叠加操作。
setTransform (m11, m12, m21, m22, dx, dy):设置当前的变换矩阵为图2-20所示的矩阵。
以下代码在canvas的中间位置绘制了棵小树:
w1

代码中,首先计算出canvas的中心坐标(cx, cy),然后把canvas画布原点移动到点(cx, cy)。由于画布的原点移动到点(cx, cy)位置,那么,drawImage (img, dx, dy)表示的是把图片以(dx, dy)为左上角开始绘制。所以,如果要绘制到中央,需要偏移半个宽度和高度,即使用坐标点(−w/2, −h/2)。最终效果如图2-21所示,黑线表示canvas的边框。


2_20_21

rotate方法描述的是图像绕原点旋转,假设要实现绕某一个图像的中心点旋转,如何实现呢?对了,我们可以先把画布的原点移动到图像的中心点,然后就可以进行旋转操作了。

以下代码绘制了在画布中央,一个绕自身中心旋转并且放大了一倍的小树。
w2

这段代码中,我们定义了一个draw方法,用于绘制图像,在绘制图像的过程中,首先保存当前的绘图状态,然后把画布移动到中心,进行旋转和放大,最后恢复画布状态。注意,如果不进行保存和恢复状态的操作,则由于使用这些变换操作都将改变当前变换矩阵的状态,从而影响下一次的变换。

定义了draw方法后,设置了一个定时器,每30毫秒改变全局的角度,形成一个旋转的动画,具体的效果如图2-22所示。


2_22

本质上,前面所介绍的rotate()、scale()、translate()等方法最终都会转换成矩阵的形式进行操作,这种对应如下所示:

translate(x, y)  transform(1, 0, 0, 1, x, y)
scale(x, y)  transform(sx, 0, 0, sy, 0, 0)
rotate(deg)  transform(cos(deg), sin(deg), -sin(deg), cos(deg), 0, 0)

由于本质上这些变换操作都会进行矩阵和三角函数的相关运算,特别是旋转操作,所以这些变换操作将消耗更多的时间,特别是在手持设备上使用更为明显。

相关文章
|
6月前
|
前端开发
【HTML实战】把爱心代码放在自己的网站上是一种什么体验?
【HTML实战】把爱心代码放在自己的网站上是一种什么体验?
|
7月前
|
移动开发 前端开发 Shell
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
|
9月前
|
容器
layui框架实战案例(23):在layui-tab-content中layui-progress-bar在html拼接中不显示lay-percent的解决方案
layui框架实战案例(23):在layui-tab-content中layui-progress-bar在html拼接中不显示lay-percent的解决方案
214 0
|
3月前
|
前端开发 JavaScript
HTML实战演练之比心
HTML实战演练之比心
|
3月前
|
人工智能 JavaScript 前端开发
HTML实战演练之贪吃蛇美食大作战
HTML实战演练之贪吃蛇美食大作战
|
7月前
|
XML C语言 数据格式
七、使用BeautifulSoup4解析HTML实战(一)
七、使用BeautifulSoup4解析HTML实战(一)
|
9月前
|
开发框架 JSON 数据可视化
Python Flask Echarts数据可视化图表实战晋级笔记(1)HTML页面渲染与参数传递
Python Flask Echarts数据可视化图表实战晋级笔记(1)HTML页面渲染与参数传递
144 1
|
9月前
|
前端开发
Echarts实战案例代码(49):基于不支持立体漏斗图Funnel的HTML+CSS解决方案
Echarts实战案例代码(49):基于不支持立体漏斗图Funnel的HTML+CSS解决方案
102 0
|
10月前
|
JavaScript
Html|Vue实战小项目-购物车
Html|Vue实战小项目-购物车
96 0
|
10月前
|
负载均衡 前端开发 JavaScript
【Node.js实战】一文带你开发博客项目之联调(导入HTML、Nginx反向代理、CORS解决跨域、与前端联调)
【Node.js实战】一文带你开发博客项目之联调(导入HTML、Nginx反向代理、CORS解决跨域、与前端联调)
168 1