已经第六章了,也差不多接近尾声,如果你从第一章耐心follow到本章结束,那你便能掌握canvas的大部分知识点(当然如果要精通,还是得多靠练习,做一些小案例)。

今天我们要学习的是canvas的变形转换方法。

缩放方法scale()

在canvas中,如果我们需要缩放当前绘图对象,可以利用 scale() 来实现,其语法为

ctx.scale( s_width, s_height );

s_width 和 s_height 表示要缩放的宽度或高度的缩放倍数,注意这两个参数的值不再是像素值而是缩放倍数,比如1表示不缩放、0.5表示缩小50%、2.3表示放大2.3倍。我们来个例子:

<canvas id="myCanvas" width="400" height="350" style="border:solid 1px #CCC;">
您的浏览器不支持canvas,建议使用最新版的Chrome
</canvas> <script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://images.cnblogs.com/cnblogs_com/vajoy/558869/o_avatar.jpg";
img.onload = function(){
ctx.globalAlpha = 0.3; //设置全局透明度
ctx.drawImage(img,0,0);
ctx.scale(1.2,1.2);
ctx.drawImage(img,0,0);
ctx.scale(1.2,1.2);
ctx.drawImage(img,0,0);
}
</script>

注意我们这里动用了 ctx.globalAlpha 属性,它表示全局透明度,其值为0-1,1表示不透明,0表示彻底透明。我们上方代码设置全局透明度为0.3,表示后续绘制出来的任何对象其透明度都只有30%。效果如下:

要注意的一点是,在canvas对当前绘图对象进行缩放时,其缩放中心点是画布(0,0)的坐标原点。不仅仅是缩放,后续我们要介绍的其它变形方法,均是以画布(0,0)坐标点为变形中心点的。

我们可以看下这个例子:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://images.cnblogs.com/cnblogs_com/vajoy/558869/o_avatar.jpg";
img.onload = function(){
ctx.globalAlpha = 0.5;
ctx.drawImage(img,10,10);
ctx.scale(2,2);
ctx.drawImage(img,10,10);
}

可以看到,由于相对画布左上角的原点做了2倍缩放,故绘制的第二张图片(即被放大2倍的图片)距离画布左上角的距离,是第一张的两倍距离。

也就是说,第二次的 ctx.drawImage(img,10,10) 中的距离参数也同样做了放大,实际在画布上开始绘制的坐标变成了(10*2, 10*2),即(20,20)。

旋转方法rotate()

我们可以通过 rotate() 方法对当前绘制对象进行旋转,该方法只有一个参数:

ctx.rotate(angle);

参数angle指要旋转的度数,还记得我们在第三章提到,度数要使用 Math.PI 为基准,你可以把一个 Math.PI 理解为180度,如下我们来把一张图片旋转30度(1/6*Math.PI):

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://images.cnblogs.com/cnblogs_com/vajoy/558869/o_avatar.jpg";
img.onload = function(){
ctx.globalAlpha = 0.5;
ctx.drawImage(img,10,10);
ctx.rotate(1/6*Math.PI);
ctx.drawImage(img,10,10);
}

于是图片会相对画布左上角原点做顺时针30度的旋转,如果你希望逆时针旋转,可以将度数设为负值,比如 ctx.rotate(-1/6*Math.PI);

位移方法translate()

在画布绘制了一个对象后,我们可以通过 translate() 方法对画布坐标进行相对X轴或Y轴方向的位移。其语法为:

ctx.translate( t_x, t_y );

t_x表示在x轴方向上的位移量,t_y表示在y轴方向上的位移量。我们来个示例:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://images.cnblogs.com/cnblogs_com/vajoy/558869/o_avatar.jpg";
img.onload = function(){
ctx.globalAlpha = 0.5;
ctx.drawImage(img,10,60);
ctx.globalAlpha = 1;
ctx.translate(50,-30); //在x轴方向做50px的向右位移,在y轴方向做30px的向上位移
ctx.drawImage(img,10,60);
}

可以看到,新绘制的对象(不透明的图片)相对第一张图片(半透明的)在X轴、Y轴方向分别偏移了50px和-30px。

不过我们介绍 translate() 的时候表示该方法是对画布坐标进行相对X轴或Y轴方向的位移,这个怎么理解?

上方的代码里,两次drawImage时,其开始绘制的坐标都是(10,60),我们先试着修改一下,把第二次绘图代码改为ctx.drawImage(img,30,30):

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://images.cnblogs.com/cnblogs_com/vajoy/558869/o_avatar.jpg";
img.onload = function(){
ctx.globalAlpha = 0.5;
ctx.drawImage(img,10,60);
ctx.globalAlpha = 1;
ctx.translate(50,-30);
ctx.drawImage(img,30,30); //修改参数,让开始绘制的坐标跟上方的不同
}

效果如下:

那么对于这个效果的理解,我们可以看做“画布的坐标系统”在X轴、Y轴方向分别偏移了50px和-30px。来张分析图加深理解:

变形方法transform()

如果你是一名Transformer(变形金刚)的热衷者,那么你对transform这个单词自然也很了解。

在canvas中,我们可以对当前绘图对象进行矩阵变形。我们先来看一下Adobe Fireworks里一个实用工具——扭曲工具的效果:

而 transform() 正是实现这种在水平方位或垂直方位做缩放、倾斜、偏移的效果。对应这些效果,它的参数有六个:

ctx.transform(a,b,c,d,e,f);

参数含义如下:

乍一看这参数貌似很混乱,其实不然,它是遵从数学矩阵公式规则的(点此查看详细):

其中,x和y是元素最开始的坐标,x’ 和y’则是通过矩阵变换后得到新的坐标。通过3×3的变换矩阵,对原先的坐标施加变换,就能得到新的坐标了。

我们来个实例,让图片在原位置上缩小一倍、水平倾斜45度、垂直偏移50px:

<canvas id="myCanvas" width="260" height="400" style="border:solid 1px #CCC;">
您的浏览器不支持canvas,建议使用最新版的Chrome
</canvas> <script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://images.cnblogs.com/cnblogs_com/vajoy/558869/o_avatar.jpg";
img.onload = function(){
ctx.globalAlpha = 0.5;
ctx.drawImage(img,0,0);
ctx.globalAlpha = 1;
ctx.transform(0.5,1,0,0.5,0,50); //变形
ctx.drawImage(img,0,0);
}
</script>

注意此处的“水平倾斜45度”,我们是给参数b赋值1,而不是Math.PI之类的角度值。

在CSS 3中,transform: skew(θx, θy); 就等价于 transform: matrix(tan(θx),0,0,tan(θy),0,0); 而transform()里的倾斜参数也是相当于 tan(倾斜角度) 计算后的值,由于 tan(45°)=1 ,故我们给参数b赋值1来实现水平倾斜45度的效果。

最后要介绍的是 setTransform() 方法,它跟 transform() 有着一样的参数、实现着一样的方法,不过 setTransform() 会重置所有曾设置过的变形数值。

怎么理解 transform() 跟 setTransform() 的区别呢?我们来看个例子:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://images.cnblogs.com/cnblogs_com/vajoy/558869/o_avatar.jpg";
img.onload = function(){
ctx.globalAlpha = 0.5;
ctx.drawImage(img,0,0);
ctx.globalAlpha = 1;
ctx.scale(0.5,0.5); //缩小至0.5倍
ctx.transform(0.5,0,0,0.5,0,0); //变形,再要求缩小至0.5倍
ctx.drawImage(img,0,300);
}

执行后可以看到,transform() 在原有的缩小了0.5倍的基础上,又把图片继续再缩小0.5倍,也就是画出来的第二张图片是第一张的1/4:

我们把 transform() 换成 setTransform() 试试:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://images.cnblogs.com/cnblogs_com/vajoy/558869/o_avatar.jpg";
img.onload = function(){
ctx.globalAlpha = 0.5;
ctx.drawImage(img,0,0);
ctx.globalAlpha = 1;
ctx.scale(0.5,0.5); //缩小至0.5倍
ctx.setTransform(0.5,0,0,0.5,0,0); //变形,再要求缩小至0.5倍
ctx.drawImage(img,0,300);
}

可以看到 setTransform() 重置了“缩放”效果,即一开始的 scale(0.5,0.5) 效果被pass掉了,你可以试着把 scale() 改为  scale(3.5,3.5),但它不会其任何作用。

你也可以做多次尝试,你会发现 setTransform() 会很好地重置、覆盖掉之前设置过的 scale()、translate()、transform() 变形数值。

本章就介绍到这,共勉~

HTML5- Canvas入门(六)的更多相关文章

  1. HTML5 canvas入门

    HTML5 Canvas入门 <canvas> 标签定义图形,比如图表和其他图像,您必须使用脚本来绘制图形.在画布上(Canvas)画一个红色矩形,渐变矩形,彩色矩形,和一些彩色的文字. ...

  2. HTML5 Canvas 绘制六叶草

    注意: context.arc(横坐标,纵坐标,弧半径,起始角度,终止角度,逆顺时针);这个函数挺难用,主要原因是最后参数和角度的关系.不管文档怎么说,按我的实际经验,逆顺时针=false时,是逆时针 ...

  3. html5 Canvas绘制图形入门详解

    html5,这个应该就不需要多作介绍了,只要是开发人员应该都不会陌生.html5是「新兴」的网页技术标准,目前,除IE8及其以下版本的IE浏览器之外,几乎所有主流浏览器(FireFox.Chrome. ...

  4. HTML5 canvas绘制线条曲线

    HTML5 canvas入门 线条例子 1.简单线条 2.三角形 3.填充三角形背景颜色 4.线条颜色以及线条大小 5.二次贝塞尔曲线 6.三次贝塞尔曲线 <!doctype html> ...

  5. Canvas入门笔记-实现极简画笔

    今天学习了Html5 Canvas入门,已经有大神写得很详细了http://www.cnblogs.com/tim-li/archive/2012/08/06/2580252.html#8 在学习过后 ...

  6. HTML5 Canvas 六角光阑动态效果

    光阑是光具组件中光学元件的边缘.框架或特别设置的带孔屏障,本人实现了结构比较简单的六角光阑,效果有点像宇航员在徐徐张开的飞船舷窗中看到逐渐完整的地球,下面四张图可以感受一下. 当然看动态效果才能真正体 ...

  7. HTML5 Canvas 画图入门

    HTML5 Canvas 画图入门 HTML5 Canvas 画图入门,仅供学习參考 <!DOCTYPE html> <html> <head> <meta ...

  8. 《html5 从入门到精通》读书笔记(一)

    今天看了<html5 从入门到精通>这本书,感觉阅读下来很舒心,不像阅读其他书籍很揪心.html增加的知识点,我觉得非常有价值,看完几章记录了一些内容,不但能巩固,也为下次遗忘知识点做好准 ...

  9. 赠书:HTML5 Canvas 2d 编程必读的两本经典

    赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ...

  10. 03.Web大前端时代之:HTML5+CSS3入门系列~H5功能元素

    Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 2.功能元素 1.hgroup 对网页或区段(secti ...

随机推荐

  1. python访问MS SqlServer(通过pyodbc)

    #!/usr/bin/env python # -*- coding: utf-8 -*- import pyodbc class MSSQL: """ 封装pyodbc ...

  2. WriteableBitmap 给透明的控件截图的问题

    在WP开发中,我们经常会用到截取某一部分区域,然后分享到微博等等,Writeablebitmap 是一个很好的辅助,但是它本身也有一个限制:只有一个 SaveJpeg 方法,因此透明的区域无法保存,都 ...

  3. SQL参数化查询自动生成SqlParameter列表

    string sql = @"INSERT INTO stu VALUES (@id,@name) "; 参数化查询是经常用到的,它可以有效防止SQL注入.但是需要手动去匹配参数@ ...

  4. 20个高级Java面试题汇总

    程序员面试指南:https://www.youtube.com/watch?v=0xcgzUdTO5MJava面试问题集合指南:https://www.youtube.com/watch?v=GnR4 ...

  5. 《转》Unity3D研究院编辑器之5.3JSON的序列化

    Unity5.3 的一项新功能就是Json的序列化,支持嵌套使用,可以把json字符串转成对象,把对象转成json字符串. using UnityEngine; using UnityEditor; ...

  6. [资料分享]组件方式开发 Web App全站

  7. 基于ThinkPHP3的微信平台开发_1

    微信公众平台是个好东西,具体的就不说了,我直接说技术>_< 下图为目录结构一览: 微信开发 - 文件目录结构 平台功能: 此次开发的平台是面向多微信公众号.微信多公众号主(下面简称号主)的 ...

  8. 【系统篇】从int 3探索Windows应用程序调试原理

    探索调试器下断点的原理 在Windows上做开发的程序猿们都知道,x86架构处理器有一条特殊的指令——int 3,也就是机器码0xCC,用于调试所用,当程序执行到int 3的时候会中断到调试器,如果程 ...

  9. 使用系统自带的GCD的timer倒计时模板语句遇到的小坑。。

    今天折腾了下系统gcd的 但是如果不调用这句dispatch_source_cancel()那么这个timer根本不工作....解决方法如下: 实现一个倒计时用自带的gcd如此简洁.. 原因可能是如果 ...

  10. 转载:Hadoop排序工具用法小结

    本文转载自Silhouette的文章,原文地址:http://www.dreamingfish123.info/?p=1102 Hadoop排序工具用法小结 发表于 2014 年 8 月 25 日 由 ...