ホームページ  >  記事  >  ウェブフロントエンド  >  Canvas API、一般的な Canvas の基本 (2)

Canvas API、一般的な Canvas の基本 (2)

黄舟
黄舟オリジナル
2017-03-16 13:45:231596ブラウズ

上で線を引くこと、長方形を描くこと、テキストを書くことについて話しました。まだ読んでいない場合は、外に出て左に進んでください。ここでさらに複雑なプロパティとメソッドを見てみましょう。

それについて話す前に、まだ触れていない属性がいくつかあるので、三角形を描くことから始めましょう。

上記を読めば、賢い若者は間違いなく、三角形はとても単純で、直線よりも点が 1 つ多いだけだと思う​​でしょう。それで、若者はそれを始めました:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.stroke();


ああ、なぜポリラインなのでしょうか?三角形には点が 3 つしかありません。閉店してないからでしょうか?それから、もう 1 つ付け加えさせてください:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.lineTo(50,50);
ctx.stroke();

はは、私は確かにあなたと同じくらい機知に富んでいます!このアイデアは実際には正しい解決策です。実際、三角形を描画する別の方法があります。それは 3 つの点だけを必要とします:

closePath() を使用する場合です。一般的に、それらはペアであると言われています

beginPath() がパスを開始します

この人間の宝のペアの一般的な使用法は次のとおりです:

ctx.beginPath();

ctx.closePath();

まず、道路を開始します ジン、書き込みます描きたい内容を入力して、道を終了します。これはボックスに相当します。これを行う利点は、描画プロセス中のスタイルの汚染を回避できることです。それ?さて、以下をご覧ください:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
//第一个三角
ctx.strokeStyle='red';
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.lineTo(50,50);
ctx.stroke();
//第二个三角
ctx.strokeStyle='green';
ctx.moveTo(150,50);
ctx.lineTo(200,100);
ctx.lineTo(150,200);
ctx.lineTo(150,50);
ctx.stroke();

図に示すように、最初の三角形の色を赤、2 番目の三角形の色を緑にしたいとしましたが、結果はすべて緑になり、目の鋭い生徒も同様にできます。ほら、最初の三角形は 2 色あるように見えますが、色も 2 つ重なっているように見えます。オーケー、変更しましょう、あなたはそれを見ています:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
//第一个三角
ctx.strokeStyle='red';
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.lineTo(50,50);
//ctx.stroke();
//第二个三角
ctx.strokeStyle='green';
ctx.moveTo(150,50);
ctx.lineTo(200,100);
ctx.lineTo(150,200);
//ctx.lineTo(150,50);
ctx.stroke();

最初の三角形も 2 番目の三角形の左側も描かないで、それから見てみましょう:

最初の三角形には二重色はありません。話しましょう 2 回描画され、1 回は赤、もう 1 回は緑が削除されました。これは私たちが望んでいることではありません。

それから、一組の人間の宝物を使って見てみましょう:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
//第一个三角
ctx.beginPath();
ctx.strokeStyle='red';
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.lineTo(50,50);
ctx.closePath();
ctx.stroke();
//第二个三角
ctx.beginPath();
ctx.strokeStyle='green';
ctx.moveTo(150,50);
ctx.lineTo(200,100);
ctx.lineTo(150,200);
ctx.lineTo(150,50);
ctx.closePath();
ctx.stroke();

これが私たちが望むものです、あなたはあなたのもので遊び、私はお互いに干渉せずに私のもので遊びます(三角形を描くのに必要なのは3点だけだと言いました。自慢 B、4 ポイントを使用していることがわかります)、ああ、そうです。

closePath()メソッドは、現在点から開始点までのパスを作成するメソッドの説明です。つまり、このメソッドを使用すると、beginPath()の位置にブラシを移動できます。この理論によれば、三角形を描くとき、​​3 番目の点に到達したら、closePath() メソッドを使用してブラシを開始点に戻し、線を閉じます。効果を見てみましょう:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.strokeStyle='red';
ctx.moveTo(50,50);
ctx.lineTo(100,100);
ctx.lineTo(50,200);
ctx.closePath();
ctx.stroke();

ほら、3 つしかありません。これはポリラインではなく、点ですよね? このスキルは、後で説明する任意のファン チャートや不規則な図形に使用できます。

こんにちは。あなたの線はすべて 1 ピクセルです。孫悟空の黄金の棍棒と同じにすることはできません。もっと大きくする必要がありますし、どんどん小さくする必要もあります。誰がそんなこと言ったの? 私は魔法の武器を持っています、そして世界は無敵です!

私の魔法の武器は次のとおりです:

lineWidth は現在の線幅を設定または返します

使い方は?兄が私に金の棍棒をくれました:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
vartimer=null;
varnum=1;
ctx.moveTo(150,50);
ctx.strokeStyle='gold';
setInterval(function(){
if(num==100){
clearInterval(timer);
num=1;
}else{
num++;
};
ctx.lineTo(150,100+num*2);
ctx.lineWidth=num;
ctx.stroke();
},100)

金の棍棒、大きい、大きい、大きい、大きい、大きい、ははは~~~

まあ、真剣に考えてください、このアーティファクトを使用すると、任意のワイヤーフレーム、線の幅、中空の三角形、中空の長方形など、もちろん、中空のテキストについては聞かないでください、わかりません~

線については、他に 2 つの属性があります:
lineJoin 2 本の線が交差する角のタイプ
パラメータ:
miter : 鋭角、デフォルト
bevel: ベベル
round: 丸い角

これはどういう意味ですか? 中空の長方形を例に挙げます:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.lineWidth=10;
ctx.beginPath();
ctx.lineJoin='miter';
ctx.strokeRect(100,10,80,80);
ctx.closePath();
ctx.beginPath();
ctx.lineJoin='round';
ctx.strokeRect(100,110,80,80);
ctx.closePath();
ctx.beginPath();
ctx.lineJoin='bevel';
ctx.strokeRect(100,210,80,80);
ctx.closePath();

右側はポリライン効果です

ポリライン効果には、別の効果があります。属性:

miterLimit は、マイターの最大長を指定します。どのような意味です?右側の折れ線グラフを見てください。鋭い角の下部グループはマイターと呼ばれます。一般的な意味は、鋭い角の長さが miterLimit の値より小さい場合に指定されます。この値より大きい場合、その形状は lineJoin='bevel' と同じになり、このメソッドはデフォルト値の lineJoin="miter" が設定されている場合にのみ機能します。例を示します:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.lineWidth=10;
ctx.lineJoin="miter";
ctx.beginPath();
ctx.miterLimit=19;
ctx.moveTo(20,20);
ctx.lineTo(150,27);
ctx.lineTo(20,34);
ctx.stroke();

ctx.beginPath();
ctx.miterLimit=18;
ctx.moveTo(20,120);
ctx.lineTo(150,127);
ctx.lineTo(20,134);
ctx.stroke();
ctx.beginPath();
ctx.lineJoin="bevel";
ctx.moveTo(20,220);
ctx.lineTo(150,227);
ctx.lineTo(20,234);
ctx.stroke();

図に示すように、miterLimit の値が 19 以上の場合、鋭い角は正常に表示されます。18 未満の場合、鋭い角は切り詰められます。効果は lineJoin='bevel' と設定するのと同じです。どのような効果があるかは後でわかります。

もう 1 つ:

lineCap は線の終点スタイルを設定または返します。これは線を設定するためのものであることに注意してください。

パラメータ:
バットのデフォルト。線の両端に直線エッジを追加します。
round は、線の両端に丸いワイヤー キャップを追加します。
square は、線の両端に正方形の線のキャップを追加します。
どういう意味ですか?セリフについては、金の棍棒を例に挙げます。忘れて、セリフを使ってみましょう (金の棍棒を見ると笑いたくなります)

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.lineWidth=10;
ctx.beginPath();
ctx.lineCap='butt';
ctx.moveTo(50,50);
ctx.lineTo(200,50);
ctx.stroke();

ctx.beginPath();
ctx.lineCap='round';
ctx.moveTo(50,100);
ctx.lineTo(200,100);
ctx.stroke();

ctx.beginPath();
ctx.lineCap='square';
ctx.moveTo(50,150);
ctx.lineTo(200,150);
ctx.stroke();

最後の 2 つは最初のものよりも少し長いことがわかります。正確にはどれくらいですか?説明するために絵を描きます:

圆角和方脚的原理其实是这样的,很明显多出的一部分的宽度就是线条的一半的长度,所以要精确计算其长度,此小细节需谨记!

现在我们来讲讲画圆及其相关的图形:

arc(x,y,r,sAngle,eAngle,counterclockwise)

什么意思?x,y表示坐标点表示圆心坐标,r表示半径,sAngle表示开始弧度,eAngle表示结束弧度,counterclockwise表示顺时针还是逆时针方式,默认为顺时针false,逆时针为true

注意,这里的角度是用弧度表示的,不是直接写角度,那问题来了,一般我们知道一个圆弧是多少度,怎么知道它是多少弧度呢?总感觉弧度太抽象,嗯嗯,我也有同感,那我们就来科普一下弧度的算法吧,列几个公式(初中,高中的数学,都还给老师了):

1弧度=r;
360°=2∏;
周长C=2∏r;
那么一周的弧度数=2∏r/r=2∏=360°
则1°=2∏*1°/360°=∏*1°/180°(弧度)
90°=∏*90°/180°(弧度)

圆的初始位置是在最右边,跟我们自己手绘圆的起点有那么一点点的不一样,默认是顺时针方向,那角度就应该是如图所示的角度,要是还不清楚的话,我们画2半圆,分别表示顺时针和逆时针,这样就应该清楚了,哦,需要说明的一点就是,画用的方法跟画直线和矩形框的原理是一样的,只是画出了路径,并没有添墨水,仍需用黑白双煞:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.arc(80,100,50,0,180*Math.PI/180,false);
ctx.stroke();

ctx.beginPath();
ctx.arc(200,100,50,0,180*Math.PI/180,true);
ctx.stroke();

js里面是没有∏的,你懂的,但是有函数Math.PI,咦,这里为什么是圆弧而不是半圆啊,如果我要画一个半圆怎么弄呢?哈哈~,还记得上面三角形的那个折线吗?这个是一个原理,只是图形没有闭合而已,用closePath()就可以闭合了。

画一个扇形看看,这里我就闭合图形哈:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.arc(80,100,50,30*Math.PI/180,150*Math.PI/180,false);
ctx.closePath();
ctx.stroke();

当当当当~~~噗,喷了一口老血,怎么是一条小船,说好的扇子呢?再看看三角图形,瞬间就明白了,图形闭合不是以圆心为起始点的,而是初始弧度为起点,然后闭合的时候是回到初始点,就变成小船了,那怎么才能画出一个扇形呢?给个思路,这里暂时不给代码,以后有时间当小实例给到大家,如果我以圆心为起点,画2条直线,连到圆弧的起始点和结束点,是不是就是一个扇形了,哈哈~,不多说了,脑补一下吧,当然,圆弧的起始点的坐标和结束点的坐标计算还是有点费劲的

前面我们画的是空心的圆或弧,可否画实心的呢?貌似问的有点多余,上面说了用黑白双煞,好吧,直接给个一饼好了:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.arc(150,150,50,0,360*Math.PI/180,false);
ctx.fill();

咦,怎么这么像某岛国国旗,还好我用的是默认黑色,嘘嘘,都没看到哈~
还有一个方法可以画圆弧:
arcTo(x1,y1,x2,y2,r)创建两个切线之间的弧/曲线
参数:x1,y1表示第一个坐标,x2,y2表示第二个坐标,r表示曲线半径
两个切线之间的曲线,试试:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
ctx.lineTo(100,20);
ctx.arcTo(150,20,150,70,50);
ctx.lineTo(150,120);
ctx.stroke();

果然是要在两条线段之间写曲线,要是先写2条曲线,在写arcTo(),貌似就出不来了,这让我们想到了moveTo(),lineTo(),再写一个例子:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.moveTo(150,20);
ctx.arcTo(150,200,50,0,20);
ctx.stroke();

想试一下,要是只有一条切线,会怎样?

好大的一个鱼钩啊,看来这样也是可以的,要是没有切线,可否?

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.arcTo(150,200,50,0,20);
ctx.stroke();

额,狗带了,没反应,看来必须至少有一个切线才能画弧线,有个点都行,要求不算高,满足你。

感觉这里始终没有将清楚,arcTo()为什么会画出这样的曲线呢,我觉得有必要画一张图来表示:

它的绘图原理应该是这样的,起始点是圆弧的第一个切点,也是画笔的起始点,然后arcTo的两个坐标点分别是圆弧的起点和终点,这样3个点就形成了2天相交的线,然后以半径为r画一个圆,与这2条线相切,2个切点就是绘制的这条弧,而第二张图就是arcTo()所绘制的图形,为了证实这一点,我们写一个相近的图形来看看:

varcanvas=document.getElementById("canvas");
varctx=canvas.getContext("2d");
ctx.beginPath();
ctx.fillRect(100,100,5,5);
ctx.fillRect(180,80,5,5);
ctx.fillRect(160,180,5,5);
ctx.moveTo(62,112);
ctx.lineTo(182,82);
ctx.lineTo(162,182);
//这里是绘制切线弧
ctx.moveTo(103,103);
ctx.arcTo(183,83,162,182,40);
ctx.stroke();

对比这2组图,将生成的弧线用圆对比一下,会发现起点并不是切点,但基本思路是正确的,3点形成一个夹角,然后以r为圆心,画一个圆,从起点到第二个切点,就是arcTo()方法所绘制的图形。

今天就到这吧!讲的很混乱,东一脚西一脚的,希望你们能懂!最希望的是能对你们有帮助,那就再好不过了!

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

相关文章:

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

キャンバスAPI入門、キャンバス共通基礎知識(3)

キャンバスAPI入門、キャンバス共通基礎知識(4)

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。