搜索
首页web前端H5教程canvas API ,通俗的canvas基础知识(四)

今天要讲的内容是canvas的转换功能,前面的内容没用看的同学可以出门右转,先看看前面的基础知识,废话不多说,开始进入正题吧!
何为转换功能?熟悉css3的同学都知道,css3里面有transform,translate,scale,rotate,animation等等,这就是css3的转换功能,同样,canvas也支持,但是只是支持部分,那我们来看看,都支持哪些,和css3相比,有什么区别?
1、scale

scale(scaleWidth,scaleHeight)  缩放当前绘图

参数:scaleWidth 表示缩放当前绘图的宽度,取值如0.5 = 50% ,1 = 100% , 2 = 200%以此类推 ; scaleHeight 表示缩放当前绘图的高度,取值如0.5 = 50% ,1 = 100% , 2 = 200%以此类推
我们可以先看看css3是什么表现:
css3 scale(sx,sy)  sx,sy分别表示向横坐标和纵坐标的缩放向量,取值如0.5 = 50% ,1 = 100% , 2 = 200%以此类推 基本上跟canvas是一样,只是说法不一样而已,那既然用法是一样的,我们就来试一下:

ctx.strokeStyle = 'red';
ctx.strokeRect(5,5,50,50);
ctx.scale(2,2);
ctx.strokeRect(5,5,50,50);
ctx.scale(2,2);
ctx.strokeRect(5,5,50,50);



canvas API ,通俗的canvas基础知识(四)

咦,你会看到一个很奇怪的现象,它不是从定位的原点开始缩放的,而是偏移了原点,实际上是不仅仅是图形缩放了,就连图形的边距也缩放了,且缩放的倍数与图形倍数一致,我们看一下css3的scale会有什么样的表现:

.box{
    width:50px;
    height:50px;
    border:1px solid #000;
    margin:20px;
}
.box:hover{
    -webkit-transform:scale(2,2);
}



canvas API ,通俗的canvas基础知识(四)

canvas API ,通俗的canvas基础知识(四)

css3的表现是以图形的中心点为原点,然后向四周缩放,由此我们得到canvas 的scale与css3的scale的不同点之一;

不同点之二就是,css3的scale,如果x,y轴的缩放倍数一样的话,是可以缩写成一个参数的,如:

.box:hover{
    -webkit-transform:scale(2);
}


效果是一样一样的,但是canvas的2个参数即使缩放倍数一样,也是不能进行简写的,必须2个参数都写才能运行;

说到这里,我想起来在canvasAPI开篇的时候留了一个悬念,就是canvas画布的宽高设置必须在canvas标签属性上设置,而不能在css里设置,这是为什么呢?下面大家来看一个例子:

第一组,我们用css来定义canvas的宽高,标签属性上不设样式:

canvas{ background:#fff; width:300px; height:300px; }


ctx.strokeStyle = 'red';
ctx.strokeRect(5,5,50,50);


canvas API ,通俗的canvas基础知识(四)

咦,这是什么鬼?

第二组,我们用canvas标签属性来设宽高,不用css设置:

<canvas width="300" height="300" id="canvas">
        <span>亲,您的浏览器不支持canvas,换个浏览器试试吧!</span>
</canvas>



canvas API ,通俗的canvas基础知识(四)

明显是在标签属性上设置的宽高是正常的,为什么css设置宽高会出现这种诡异的状况,原因是canvas本身是有默认宽高的(宽300,高150),如果在css中设置宽高,会让canvas认为,现在canvas的宽度倍自动缩放了,缩放比例为css设置的宽度/300,高的也一样,那么就可以理解了,现在css设置的宽度是300,高的是300,那么就会缩放宽=300/300,高缩放=300/150,高的自然就被拉高了一倍,所以这才是必须在canvas的属性上设置宽高的原因

我们回到scale,我们来给给一个动态图,来看看scale的变化过程:

var timer = null;
ctx.strokeStyle = &#39;red&#39;;
timer = setInterval(function(){
    ctx.beginPath();
    ctx.scale(1.5,1.5);
    ctx.strokeRect(5,5,50,50);
    ctx.closePath();
},500)


canvas API ,通俗的canvas基础知识(四)

可以从这个gif图中可以看出,scale的变化是在前面的一次绘图的基础上再次缩放,然后再缩放,有人说,你这个定时器是本来就是原来的基础上再缩放一次,理所应该就是这样,但是这个效果不好看,能不能我设一个参数,然后让它累加,慢慢的缩放,且只有一个图形呢?

嗯,这里就需要解释一个方法叫clearRect(),表示在指定的范围内清除样式,这里如果需要只有一个图形,那么就必须在下一次绘制图形之前清除掉前面的一次绘图,因为中间的时间极短,就感觉是连续的,我们先介绍一下这个clearRect()方法吧:

clearRect(x,y,w,h) 参数:w,y表示需要清除的矩形的左上角坐标,w,h表示需要清除的矩形的宽高

从参数可以看出,它是可以清除局部区域的像素的,如果区域设为画布,则是清除整个画布了,好了,让我们一起来写一下你想要的那种效果:

var timer = null;
        var num = 1;
        ctx.strokeStyle = &#39;red&#39;;
        timer = setInterval(function(){
            
            if(parseInt(num) >=5){
                clearInterval(timer);
                num =5;    
            }else{
                num +=0.1;
            }
            ctx.clearRect(0,0,canvas.clientWidth,canvas.clientHeight);
            ctx.save();
            ctx.beginPath();
            ctx.scale(num,num);
            ctx.strokeRect(5,5,50,50);
            ctx.closePath();
            ctx.restore();
        },500)


canvas API ,通俗的canvas基础知识(四)

看上图,现在就可以安安静静看它是怎么缩放的了,边距和图形一起缩放,比例也是一样的,这里的效果之所以没有和上面的gif图一样,在上一次缩放的基础上缩放,是因为这一对活宝:save()和restore(),这对活宝上一篇已经讲过了,如果还是不熟悉的同学出门右转,找到API的第3篇,这里的这一对主要功能是保存当前的路径,不被其他的路径污染,这对活宝和clearRect()在做运动的时候是非常有用的,这里终点提示一下!

2、rotate

rotate(angle)  旋转当前绘图  参数:angle表示旋转角度,这里需要填写弧度(弧度和角度的关系,在前面就已经讲过了,不熟悉的同学可以找到API的第2篇)

同样我们看一下css3 rotate的表现:

.box{
    width:50px;
    height:50px;
    border:1px solid #000;
    margin:20px;
}
.box:hover{
    -webkit-transform:rotate(30deg);
}


canvas API ,通俗的canvas基础知识(四)

可以看到css3的旋转是以中心为原点进行旋转,切接受的参数直接就是角度,而不是弧度,那canvas的rotate的表现是什么呢?

ctx.fillStyle = &#39;red&#39;;
ctx.fillRect(0,0,150,50);
ctx.beginPath();
ctx.rotate(30*Math.PI/180);
ctx.strokeRect(0,0,150,50);
ctx.closePath();


canvas API ,通俗的canvas基础知识(四)
  红色为初始图形,黑色为旋转图形,这是将图形坐标设置画布左上角的地方的

ctx.fillStyle = &#39;red&#39;;
ctx.fillRect(50,50,150,50);
ctx.beginPath();
ctx.rotate(30*Math.PI/180);
ctx.strokeRect(50,50,150,50);
ctx.closePath();


canvas API ,通俗的canvas基础知识(四)
  图形坐标设置50,50处

ctx.fillStyle = &#39;red&#39;;
ctx.fillRect(100,100,150,50);
ctx.beginPath();
ctx.rotate(30*Math.PI/180);
ctx.strokeRect(100,100,150,50);
ctx.closePath();


canvas API ,通俗的canvas基础知识(四)
图形坐标设在100,100处

从这个3组效果中,我们可以得出这样的结论:

1、canvas的旋转原点并不是以自身的中心为原点,而是以画布的左上角为原点,3张图的比较可以看出来

2、图形的旋转原点也不是其自身的中心,而是其左上角为原点

这里说了2个原点,可能不好理解哈,几个例子,比如地球,它即绕太阳转,自己本身也转,那么它让太阳转就是我们说的第一点,图形绕画布旋转,准确的来说,也是图形的左上角绕画布左上角旋转,太阳的自转就是我们说的第2点,它自己本身的旋转,只不过canvas图形中的自转不是以中心为原点的旋转,其中心在左上角,这应该就明白看吧!

3、translate

translate(x,y)  重新映射画布上的 (0,0) 位置,这怎么理解?通俗的将,就是重新定义坐标原点,默认原点是(0,0),用此方法会将原点改成(x,y)

参数:x 添加到水平坐标(x)上的值  y添加到垂直坐标(y)上的值

定义不好理解,那我们就用例子来理解:

ctx.fillRect(10,10,100,100);
//设置新原点
ctx.translate(110,110);
ctx.fillRect(10,10,100,100);


首先我们画了一个100*100的矩形,图形坐标(10,10),因为默认原点是画布左上角,所以此图形在距离左上角(10,10)的位置,理论上说,我们再画一个一模一样的矩形,坐标也一样,2图形是会覆盖的,但是我们现在重新设置原点(110,110),刚好在第一个图形的右下角,这样方便观察,然后再画一个坐标和大小一模一样的矩形,我们来看看效果:

canvas API ,通俗的canvas基础知识(四)

第二个矩形就刚好是以(110,110)为新的原点,然后距离新原点(10,10)的距离画了一个矩形,恩,这就是translate的作用

css3也是有translate的,我们不妨也来对比一下,下面我写一个css3的translate的例子:

.box{
    width:150px;
    height:150px;
    border:1px solid #000;
    margin:20px;
}
.box:hover{
    -webkit-transform: translate(100px,0);
}


canvas API ,通俗的canvas基础知识(四)

从gif图可以看出,css3的translate是以自身中心为原点进行平移,但是不会改变原点坐标,所以,canvas的translate跟css3的translate又不一样


4、transform

transform(a,b,c,d,e,f)   替换当前的变换矩阵

参数:

a:水平缩放绘图

b:水平倾斜绘图

c:垂直倾斜绘图

d:垂直缩放绘图

e:水平移动绘图

f:垂直移动绘图

参数很多,但是看这参数的解释,还是很好理解,我们都知道css3的transform是一个集合,其中包含:scale,rotate,translate,skew和matrix,并且其中的matrix(矩阵)是可以转换成前面的任何效果的,换句话说,就是matrix(矩阵)可以包含前面的任何效果,包括自身,而canvas中的transform就是扮演css3的matrix的角色,只是跟css3的效果不一样而已,前面已经对比过了,具体的原理我们在这里就不说了,如果不清楚的,可以看一下css3的matrix是什么个原理,canvas的transform跟他的原理差不多!css3 matrix看这里


scale转成transform公式可得:

context.scale(sx, sy)

缩放我直接用公式来解释:

x’=sx*x

y’=sy*y

(其中,sx 和sy分别表示在x轴和y轴上的缩放倍数,x和y默认为1)

matrix(sx*x,0,0,sy*y,0,0) --> context.transform(sx*x,0,0,sy*y,0,0) -->context.transform(sx,0,0,sy,0,0)

ctx.fillRect(10,10,100,100);
//缩放
ctx.transform(2,0,0,2,0,0);
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);


canvas API ,通俗的canvas基础知识(四)

rotate转化成transform

rotate(a*Math.PI/180)

公式推导就不推了,直接拿过来了

context.transform(cos(a),sin(a),-sin(a),cos(a),0,0)  (a为角度)

--> context.transform(Math.cos(a*Math.PI/180),Math.sin(a*Math.PI/180),-Math.sin(a*Math.PI/180),Math.cos(a*Math.PI/180),0,0)

ctx.fillRect(10,10,100,100);
//旋转
ctx.transform(Math.cos(30*Math.PI/180),Math.sin(30*Math.PI/180),-Math.sin(30*Math.PI/180),Math.cos(30*Math.PI/180),0,0);
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);



canvas API ,通俗的canvas基础知识(四)

translate转化成transform

translate(tx,ty)

context.transform(1,0,0,1,tx,ty)

ctx.fillRect(10,10,100,100);
//平移
ctx.transform(1,0,0,1,110,110);
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);



canvas API ,通俗的canvas基础知识(四)



skew转化成transform

虽然canvas没有skew方法,但是transform依然可以做出来

context.transform(1,tan(ay),tan(ax),1,0,0) (ax,ay表示x方向,y方向的倾斜角度)

-->context.transform(1,Math.tan(ay*Math.PI/180),Math.tan(ax*Math.PI/180),1,0,0)

ctx.fillRect(10,10,100,100);
//倾斜
ctx.transform(1,Math.tan(30*Math.PI/180),Math.tan(30*Math.PI/180),1,0,0)
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);



canvas API ,通俗的canvas基础知识(四)

那么,如果我想实现平移,旋转,倾斜加放大呢,怎么做?那就分开写呗:

ctx.fillRect(10,10,100,100);
//综合
ctx.transform(1,0,0,1,110,110);//平移
ctx.transform(Math.cos(10*Math.PI/180),Math.sin(10*Math.PI/180),-Math.sin(10*Math.PI/180),Math.cos(30*Math.PI/180),0,0);//旋转
ctx.transform(0.5,0,0,0.5,0,0);//缩放
ctx.transform(1,Math.tan(30*Math.PI/180),Math.tan(30*Math.PI/180),1,0,0);//倾斜
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);


canvas API ,通俗的canvas基础知识(四)

5、setTransform

setTransform(a,b,c,d,e,f)  当前的变换矩阵重置为单位矩阵,用法与transform相同

参数:

a:水平缩放绘图

b:水平倾斜绘图

c:垂直倾斜绘图

d:垂直缩放绘图

e:水平移动绘图

f:垂直移动绘图

怎么理解这个方法呢?

当我们用transform时,前面的变换方法会影响到后面的变换方法,我们俗称污染,比如:

//缩放
ctx.transform(2,0,0,2,0,0);
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);
ctx.beginPath();
//旋转
ctx.transform(Math.cos(30*Math.PI/180),Math.sin(30*Math.PI/180),-Math.sin(30*Math.PI/180),Math.cos(30*Math.PI/180),0,0);
ctx.fillStyle="green";
ctx.fillRect(10,10,100,100);


前面的一个图形我想让它放大2倍,后面的我不想让它放大,而是想让它旋转30度,结果:

canvas API ,通俗的canvas基础知识(四)

后面的图形也放大了2倍,这不是我们想要的结果,有人会说,我用save()和restore()不就可以了吗?

//缩放
ctx.save();
ctx.transform(2,0,0,2,0,0);
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);
ctx.restore();
ctx.beginPath();
//旋转
ctx.transform(Math.cos(30*Math.PI/180),Math.sin(30*Math.PI/180),-Math.sin(30*Math.PI/180),Math.cos(30*Math.PI/180),0,0);
ctx.fillStyle="green";
ctx.fillRect(10,10,100,100);


如果你用这2个方法,我就不得不给你赞一个,说明前面的你看进去了

canvas API ,通俗的canvas基础知识(四)

但是我想说的是,我们有更好的方法,就是我们现在要讲的这个--setTransform

//缩放
ctx.setTransform(2,0,0,2,0,0);
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);
ctx.beginPath();
//旋转
ctx.setTransform(Math.cos(30*Math.PI/180),Math.sin(30*Math.PI/180),-Math.sin(30*Math.PI/180),Math.cos(30*Math.PI/180),0,0);
ctx.fillStyle="green";
ctx.fillRect(10,10,100,100);



canvas API ,通俗的canvas基础知识(四)

效果跟上面的一样,官方解释是该变换只会影响 setTransform() 方法调用之后的绘图,当然,如果你把transform和setTransform一起混用,那也是会污染的:

//缩放
ctx.setTransform(2,0,0,2,0,0);
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);
ctx.beginPath();
//旋转
ctx.transform(Math.cos(30*Math.PI/180),Math.sin(30*Math.PI/180),-Math.sin(30*Math.PI/180),Math.cos(30*Math.PI/180),0,0);
ctx.fillStyle="green";
ctx.fillRect(10,10,100,100);



canvas API ,通俗的canvas基础知识(四)

要是把这2方法调个个看看:

//缩放
ctx.transform(2,0,0,2,0,0);
ctx.fillStyle="red";
ctx.fillRect(10,10,100,100);
ctx.beginPath();
//旋转        
ctx.setTransform(Math.cos(30*Math.PI/180),Math.sin(30*Math.PI/180),-Math.sin(30*Math.PI/180),Math.cos(30*Math.PI/180),0,0);
ctx.fillStyle="green";
ctx.fillRect(10,10,100,100);


canvas API ,通俗的canvas基础知识(四)

看看,效果就又不一样了,所以,在用这些变换方法的时候,必须要弄清楚他们的作用范围和顺序,才能做出我们想要的效果,也不会污染其他的效果,这点,需谨记了!

好了,变换部分就讲完了,感谢大家的关注,如有将的不对的地方,希望能踊跃指正,不甚感谢!

 以上就是canvas API ,通俗的canvas基础知识(四) 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

相关文章:

canvas API 介绍,常见的canvas基础知识(一)

canvas API 介绍,常见的canvas基础知识(二)

canvas API 介绍,常见的canvas基础知识(三)

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
H5:网络标准和技术的发展H5:网络标准和技术的发展Apr 15, 2025 am 12:12 AM

Web标准和技术从HTML4、CSS2和简单的JavaScript演变至今,经历了显着的发展。 1)HTML5引入了Canvas、WebStorage等API,增强了Web应用的复杂性和互动性。 2)CSS3增加了动画和过渡功能,使页面效果更加丰富。 3)JavaScript通过Node.js和ES6的现代化语法,如箭头函数和类,提升了开发效率和代码可读性,这些变化推动了Web应用的性能优化和最佳实践的发展。

H5是HTML5的速记吗?探索细节H5是HTML5的速记吗?探索细节Apr 14, 2025 am 12:05 AM

H5不仅仅是HTML5的简称,它代表了一个更广泛的现代网页开发技术生态:1.H5包括HTML5、CSS3、JavaScript及相关API和技术;2.它提供更丰富、互动、流畅的用户体验,能在多设备上无缝运行;3.使用H5技术栈可以创建响应式网页和复杂交互功能。

H5和HTML5:网络开发中常用的术语H5和HTML5:网络开发中常用的术语Apr 13, 2025 am 12:01 AM

H5与HTML5指的是同一个东西,即HTML5。HTML5是HTML的第五个版本,带来了语义化标签、多媒体支持、画布与图形、离线存储与本地存储等新功能,提升了网页的表现力和交互性。

H5指的是什么?探索上下文H5指的是什么?探索上下文Apr 12, 2025 am 12:03 AM

H5referstoHTML5,apivotaltechnologyinwebdevelopment.1)HTML5introducesnewelementsandAPIsforrich,dynamicwebapplications.2)Itsupportsmultimediawithoutplugins,enhancinguserexperienceacrossdevices.3)SemanticelementsimprovecontentstructureandSEO.4)H5'srespo

H5:工具,框架和最佳实践H5:工具,框架和最佳实践Apr 11, 2025 am 12:11 AM

H5开发需要掌握的工具和框架包括Vue.js、React和Webpack。1.Vue.js适用于构建用户界面,支持组件化开发。2.React通过虚拟DOM优化页面渲染,适合复杂应用。3.Webpack用于模块打包,优化资源加载。

HTML5的遗产:当前了解H5HTML5的遗产:当前了解H5Apr 10, 2025 am 09:28 AM

HTML5hassignificantlytransformedwebdevelopmentbyintroducingsemanticelements,enhancingmultimediasupport,andimprovingperformance.1)ItmadewebsitesmoreaccessibleandSEO-friendlywithsemanticelementslike,,and.2)HTML5introducednativeandtags,eliminatingthenee

H5代码:可访问性和语义HTMLH5代码:可访问性和语义HTMLApr 09, 2025 am 12:05 AM

H5通过语义化元素和ARIA属性提升网页的可访问性和SEO效果。1.使用、、等元素组织内容结构,提高SEO。2.ARIA属性如aria-label增强可访问性,辅助技术用户可顺利使用网页。

H5与HTML5相同吗?H5与HTML5相同吗?Apr 08, 2025 am 12:16 AM

"h5"和"HTML5"在大多数情况下是相同的,但它们在某些特定场景下可能有不同的含义。1."HTML5"是W3C定义的标准,包含新标签和API。2."h5"通常是HTML5的简称,但在移动开发中可能指基于HTML5的框架。理解这些区别有助于在项目中准确使用这些术语。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前By尊渡假赌尊渡假赌尊渡假赌

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具