Maison  >  Article  >  interface Web  >  API Canvas, bases populaires du Canvas (3)

API Canvas, bases populaires du Canvas (3)

黄舟
黄舟original
2017-03-16 13:45:171533parcourir

Le texte intégral explique comment dessiner des triangles, des cercles et d'autres graphiques associés. Les étudiants qui ne le connaissent pas peuvent sortir et tourner à droite, lire d'abord le texte précédent, puis continuer avec nos graphiques - les courbes.

Les étudiants qui ont étudié les mathématiques ou qui sont relativement familiers avec js connaissent tous la courbe de Bézier. Bien sûr, en mathématiques, il s'agit d'une connaissance profonde. La courbe de Bézier en js est généralement utilisée pour l'animation et se reflète en fait dans d'autres. endroits, comme l'outil plume dans Photoshop, l'outil Bézier dans CorelDraw, etc. Cela se reflète également dans le canevas

Bien sûr, si vous dessinez simplement une courbe, vous pouvez également utiliser la méthode précédente :

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
    
ctx.arc(100,100,100,0,90*Math.PI/180,false);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(103,103);
ctx.arcTo(183,83,162,182,40);
ctx.stroke();



API Canvas, bases populaires du Canvas (3)

Si vous souhaitez tracer une ligne courbe, ce sera difficile, alors le protagoniste suivant apparaît :

quadraticCurveTo(cpx,cpy,x,y) Courbe de Bézier quadratique

Paramètres : cpx, cpy représente le premier point de contrôle, x , y représente le point final

plus le point de départ, ce qui signifie que 3 points contrôlent une courbe. En fait, cela est similaire à l'utilisation de arcTo. La différence est que arcTo doit spécifier le rayon de l'arc, car il s'agit de 2 Dessinez une courbe formée par le point tangent. d'un cercle et d'une droite dans la droite. Quel est le principe de tracé de cette courbe de Bézier quadratique ? Faisons un dessin ensemble :

API Canvas, bases populaires du Canvas (3)

La règle générale de la courbe quadratique de Bézier : en partant du point de départ, plus la courbe est proche du point de contrôle, plus la courbe est raide , puis lentement En s'éloignant du point de contrôle, la courbe deviendra de plus en plus lisse jusqu'au point final, et cette courbe sera tangente au point de départ et au point final

Est-ce que ce point de contrôle est un peu comme un aimant, attirant cette courbe ? Le sport, comme dit le proverbe, entendre est pire que voir, essayons :

ctx.moveTo(50,50);
ctx.lineTo(70,120);
ctx.lineTo(200,80);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(50,50);
ctx.quadraticCurveTo(70,120,200,80);
ctx.stroke();


API Canvas, bases populaires du Canvas (3)

API Canvas, bases populaires du Canvas (3)

Regardez, est-ce comme ça ? Bien sûr, il existe une formule pour le degré de courbure, mais nous n'avons pas besoin de nous en soucier. Nous devons juste nous rappeler une chose : la. La courbe est plus proche du point de contrôle, plus la courbe est raide, et plus on s'éloigne du point de contrôle, plus la courbe est raide Ping, oh !

Rappelez-moi encore une fois, comprenez-vous la différence entre arcTo et quadraticCurveTo maintenant ?

Présentons maintenant la courbe de Bézier cubique :

bezierCurveTo(cpx1,cpy1,cpx2,cpy2,x,y) Courbe de Bézier cubique

Paramètres : cpx1, cpy1 représente le premier point de contrôle, cpx2, cpy2 représente le deuxième point de contrôle x, y représente le point final

incluant le point de départ, ainsi que 4 points pour déterminer une courbe, ceci est similaire au Bézier quadratique Le principe du La courbe est la même, avec juste un point de contrôle en plus. L'essence est toujours la même : la courbe est plus proche du point de contrôle, plus la courbe est raide, et la courbe est plus éloignée du point de contrôle, plus la courbe est plate.

Commençons par un exemple simple (Faire une forme en U) :

ctx.moveTo(20,20);
ctx.bezierCurveTo(20,100,200,100,200,20);
ctx.stroke();



API Canvas, bases populaires du Canvas (3)

API Canvas, bases populaires du Canvas (3)

Comme le montre l'image ci-dessus, non. Le premier est un rendu et le second est un schéma. La courbe commence à partir du point de départ et il y a un point de contrôle en dessous. Plus la courbe est raide. la position de la ligne tangente entre le deuxième point de contrôle et la courbe sera atteinte car elle est contrôlée par deux. Affectée par les points, la courbe commence à devenir lentement plate, car les deux points de contrôle sont juste symétriques, donc au milieu , la courbe devient horizontale, puis continue d'être affectée par les deux points de contrôle, le deuxième point de contrôle devenant de plus en plus important, connaissant la position du point tangent entre le premier point de contrôle et la courbe, la courbe continue. être affecté par le deuxième point de contrôle, et la force est inversée, jusqu'à ce qu'elle atteigne le point final, euh, je ne comprends pas, d'accord, je ne comprends tout simplement pas si vous ne comprenez pas, rappelez-vous juste cette phrase de conclusion !

L'exemple classique est le diagramme sinusoïdal (utilisant 2 courbes de Bézier, une U positive et une U inversée) :

ctx.beginPath();
ctx.moveTo(20,150);
ctx.bezierCurveTo(20,50,150,50,150,150);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(150,150);
ctx.bezierCurveTo(150,250,280,250,280,150);
ctx.stroke();



API Canvas, bases populaires du Canvas (3)

API Canvas, bases populaires du Canvas (3)

Bien sûr, je ne sais pas si les courbes cubiques de Bézier peuvent dessiner des diagrammes en forme de U, mais n'importe quelle courbe peut être dessinée, tant que vous ne le pouvez pas pensez-y, il n'y a rien que vous ne puissiez dessiner. , Haha, développons notre imagination !



On dit que ceux qui peignent ne devraient pas toujours faire des peintures à l'encre. J'aime les couleurs, les couleurs colorées. Eh bien, la toile peut aussi être utilisée pour définir des dégradés comme le CSS3, donc d'abord. enfin, l'arc-en-ciel n'est pas loin, hé hé

Voyons d'abord comment définir le dégradé de CSS3, puis comparons le dégradé du canevas. Nous savons tous que les dégradés sont divisés en dégradés linéaires et radiaux. dégradés. Pour dégradé, comparons un par un :

Dégradé linéaire :

.box1{
    width:500px;
    height:50px;
    background: -webkit-linear-gradient(left, red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%);
}



API Canvas, bases populaires du Canvas (3)

css3可以指定颜色,支持各种颜色格式,且可以指定颜色所在位置,不仅如此,css3还可以指定渐变的方向:

.box1{
    width:500px;
    height:50px;
    background: -webkit-linear-gradient(45deg , red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%);
}



API Canvas, bases populaires du Canvas (3)

方向可以用角度来定义,45度角是从左下到右上进行渐变

径向渐变:

.box2{
    width:300px;
    height:200px;
    background:-webkit-radial-gradient(red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%);
}



API Canvas, bases populaires du Canvas (3)
  渐变原点为中心,渐变颜色为百分百之间的颜色渐变

可以看出,径向渐变是以中心为原点,一圈一圈向外扩散,同样支持自定义颜色,支持各种颜色格式,支持指定位置,也是可以设置原点和渐变方式(圆形,椭圆):

.box2{
    width:300px;
    height:200px;
    background:-webkit-radial-gradient(bottom left, ellipse,red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%);
}



API Canvas, bases populaires du Canvas (3)
 原点左下,渐变形状为椭圆

.box2{
    width:300px;
    height:200px;
    background:-webkit-radial-gradient(bottom left, circle,red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%);
}



API Canvas, bases populaires du Canvas (3)
   原点左下,渐变形状为圆形

以上只是简单列举一下css3的渐变样式,当然css3的渐变肯定不止这些,这里主要是想对比一下canvas的渐变样式,顺便科普一下!

canvas的渐变相对要简单一些,没有那么多的花花肠子:

createLinearGradient(x1,y1,x2,y2)   创建线性渐变

参数:x1,y1 表示渐变起始点   x2,y2 表示渐变结束点

createRadialGradient(x1,y1,r1,x2,y2,r2)  创建径向渐变

参数:x1,y1 表示渐变开始圆心坐标,r1表示渐变开始圆的半径  x2,y2 表示渐变结束圆心坐标,r2表示渐变结束圆的半径

gradient.addColorStop(stop,color)  规定gradient 对象中的颜色和位置

参数: stop 取值0-1之间,表示渐变中开始与结束之间的位置   color表示渐变颜色

注意,这里添加渐变颜色的对象并不是context,而是gradient

怎么用呢?看线性渐变一个小例子:

这个科普一个误区:

ctx.fillRect(50,50,200,50);
var line = ctx.createLinearGradient(50,50,200,50);
line.addColorStop(0,'red');
line.addColorStop(0.2 ,'#0F0');
line.addColorStop(0.5 ,'rgb(51,102,255)');
line.addColorStop(1 ,'rgba(204,255,0,0.8)');





这样是错误的,什么都出不来!

照理说,应该是先创建一个图像,然后给这个图形加渐变色,一般的规律都如此,比如画画,比如css,但是canvas不一样,重点来了:canvas凡是设置样式的,必须放在绘图前面 ,怎么理解这句话?

绘图的方法: fill() , fillRect() , stroke() , strokeRect() , rect()

那设置:比如文字类字体,字体大小,字体颜色,字体阴影,渐变色  路径类如线条,矩形,圆形,背景,渐变等等

所以正确的格式是:

var line = ctx.createLinearGradient(50,50,200,50);
        line.addColorStop(0,'red');
        line.addColorStop(0.2 ,'#0F0');
        line.addColorStop(0.5 ,'rgb(51,102,255)');
        line.addColorStop(1 ,'rgba(204,255,0,0.8)');
        
        ctx.fillStyle = line;
        ctx.fillRect(50,50,200,50);



API Canvas, bases populaires du Canvas (3)

可以看到canvas一样可以自定义颜色,支持各种颜色格式,支持指定位置(用0-1的数,跟百分比类似),相比css3之下,我觉得canvas的渐变颜色区域更加准确!

好了,既然canvas能像css3一样设置渐变样式,那可不可以设置方向呢?怎么设?以上面的代码为例,我们画一张图:

API Canvas, bases populaires du Canvas (3)

图可能画的有点蒙啊,解释一下,第一张图表示我们上面的代码显示的效果,渐变方向是(50,50)——> (200,50),是一条水平线,表示方向是从左到右渐变,要是我将坐标方向设为(50,50)——> (200,100),如第二张图,那么渐变是否是从左上角到右下角呢?我们试一下:

var line = ctx.createLinearGradient(50,50,200,100);
line.addColorStop(0,'red');
line.addColorStop(0.2 ,'#0F0');
line.addColorStop(0.5 ,'rgb(51,102,255)');
line.addColorStop(1 ,'rgba(204,255,0,0.8)');
        
ctx.fillStyle = line;
ctx.fillRect(50,50,200,50);



API Canvas, bases populaires du Canvas (3)

API Canvas, bases populaires du Canvas (3)

可以看出角度是正确的,createLinearGradient的2个坐标就是为了指明渐变方向的,那么canvas的径向渐变会不会跟css3相同呢?我们写一个小例子:

var line = ctx.createRadialGradient(150,150,0,150,150,200);
line.addColorStop(0,'red');
line.addColorStop(0.2 ,'#0F0');
line.addColorStop(0.5 ,'rgb(51,102,255)');
line.addColorStop(1 ,'rgba(204,255,0,0.8)');
        
ctx.fillStyle = line;
ctx.fillRect(50,50,200,150);



API Canvas, bases populaires du Canvas (3)

可以看到,如果图形即使不是一个正方形,径向渐变的圆依然是正圆,与css3的渐变机制有点不一样(css3是椭圆,看上面的css3图),并且渐变区域是根据两个圆来决定的,我们改一下这2个圆的区域看看:

var line = ctx.createRadialGradient(150,150,50,150,150,100);
line.addColorStop(0,'red');
line.addColorStop(0.2 ,'#0F0');
line.addColorStop(0.5 ,'rgb(51,102,255)');
line.addColorStop(1 ,'rgba(204,255,0,0.8)');
        
ctx.fillStyle = line;
ctx.fillRect(50,50,200,150);



API Canvas, bases populaires du Canvas (3)

比对上面的图可以看出,下图在50-100的区间里是有渐变的,其他地方则是首尾的颜色填充,那么圆心在边角上呢?

var line = ctx.createRadialGradient(50,50,0,50,50,200);
line.addColorStop(0,'red');
line.addColorStop(0.2 ,'#0F0');
line.addColorStop(0.5 ,'rgb(51,102,255)');
line.addColorStop(1 ,'rgba(204,255,0,0.8)');
        
ctx.fillStyle = line;
ctx.fillRect(50,50,200,150);



API Canvas, bases populaires du Canvas (3)

效果跟css3的样式一样,颜色更加准确,如果2圆的圆心不一样,会有什么反应?

var line = ctx.createRadialGradient(50,50,0,150,150,200);
line.addColorStop(0,'red');
line.addColorStop(0.2 ,'#0F0');
line.addColorStop(0.5 ,'rgb(51,102,255)');
line.addColorStop(1 ,'rgba(204,255,0,0.8)');
        
ctx.fillStyle = line;
ctx.fillRect(50,50,200,150);


一个圆心在左上角,一个圆心在中间

API Canvas, bases populaires du Canvas (3)

咦,什么鬼,算了,如果想要正常的径向渐变,还是同圆心吧,不同圆心太诡异,hold 不住啊!

那径向渐变能像css3一样可以设置椭圆吗?咳咳,我只能借用一句台词:臣妾做不到啊!

我们来一个炫酷的渐变应用:

ctx.font = "40px 微软雅黑";
var line = ctx.createLinearGradient(10,100,200,100);
line.addColorStop(0,'red');
line.addColorStop(0.2 ,'#0F0');
line.addColorStop(0.5 ,'rgb(51,102,255)');
line.addColorStop(1 ,'rgba(204,255,0,0.8)');
ctx.fillStyle = line;
ctx.fillText("狂拽炫酷吊炸天",10,100);


API Canvas, bases populaires du Canvas (3)

下面我们介绍另外一个与颜色有关的属性——透明!

globalAlpha = num    参数:num取值0-1之间   设置或返回绘图的当前透明值

有同学会问,按这个词的意思是全局透明,那么它是全局的吗?我也想问,那我们试一下:

ctx.fillStyle = "red";
ctx.fillRect(50,50,100,100);
ctx.globalAlpha = 0.5;
ctx.fillStyle = "green";
ctx.fillRect(100,100,100,100);
ctx.fillStyle = "blue";
ctx.fillRect(150,150,100,100);



API Canvas, bases populaires du Canvas (3)

可以看到,第一个没有变透明,后面2个变透明了,那么如果我将路径闭合,是否还会出现这样的效果:

ctx.beginPath();
ctx.fillStyle = "red";
ctx.fillRect(50,50,100,100);
ctx.closePath();
        
ctx.globalAlpha = 0.5;
        
ctx.beginPath();
ctx.fillStyle = "green";
ctx.fillRect(100,100,100,100);
ctx.closePath();
        
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.fillRect(150,150,100,100);
ctx.closePath();


API Canvas, bases populaires du Canvas (3)

结果是一样的,说明它是”人“如其名啊,果然是全局的,那么将它放入闭合路径中,会污染其他的路径吗?

ctx.beginPath();
ctx.globalAlpha = 0.5;
ctx.fillStyle = "red";
ctx.fillRect(50,50,100,100);
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = "green";
ctx.fillRect(100,100,100,100);
ctx.closePath();
        
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.fillRect(150,150,100,100);
ctx.closePath();



API Canvas, bases populaires du Canvas (3)

马蛋,简直是严重的核污染啊,穿透力如此之强?如果我只想让第一个透明,后面的不透明?我要怎么弄呢?

为了解决这个问题,我们需要引入2个方法,同样是一对活宝啊:

context.save()   保存当前环境的状态

context.restore() 返回之前保存过的路径状态和属性

怎么理解这对活宝呢?

可以这么理解:当设置了save()方法,就相当于将后面的绘图放在一个堆栈中,与世隔绝,知道看到restore(),就返回到原来的位置,举个例子哈,就像是一堆糖果,save()就是将一部分糖果装进盒子,restore()就是封闭盒子,继续捡糖果,但是盒子里的糖果就不会与其他糖果混合了,恩,可以这么理解,特别注意的是,restore()方法必须要有save()才起作用,你想啊,都没有盒子装糖果,怎么能封闭盒子呢

那咱们来看看他们的神奇技能:

ctx.save();
ctx.beginPath();
ctx.globalAlpha = 0.5;
ctx.fillStyle = "red";
ctx.fillRect(50,50,100,100);
ctx.closePath();
ctx.restore();

ctx.beginPath();
ctx.fillStyle = "green";
ctx.fillRect(100,100,100,100);
ctx.closePath();
        
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.fillRect(150,150,100,100);
ctx.closePath();



API Canvas, bases populaires du Canvas (3)

哎呀,瞬间觉得整个世界都完美了!在面对凶悍的全局变量,属性或方法时,我们可以用上面的这对活宝来避免它们对我们需要的部分的侵害(这里为什么要说侵害,会让人想污的),确实是好技能!

回到globalAlpha,它的用处还是有很多的,路径,图形,文字都可以设置透明,那我们来一个文字透明看看:

ctx.font = "40px 微软雅黑";
var line = ctx.createLinearGradient(10,100,200,100);
line.addColorStop(0,'red');
line.addColorStop(0.2 ,'#0F0');
line.addColorStop(0.5 ,'rgb(51,102,255)');
line.addColorStop(1 ,'rgba(204,255,0,0.8)');
ctx.fillStyle = line;
ctx.globalAlpha = 0.3;
ctx.fillText("狂拽炫酷吊炸天",10,100);


API Canvas, bases populaires du Canvas (3)

恩,今天就介绍到这里吧,后面的内容比较复杂,需要认真的准备,就这样吧!

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


相关文章:

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

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

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

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn