绘制圆弧
有两个方法可以绘制圆弧:
1、arc()
arc(x, y, radius, startAngle, endAngle, anticlockwise)
以(x, y) 为圆心,以r 为半径,从 startAngle 弧度开始到endAngle弧度结束。anticlosewise 是布尔值,true 表示逆时针,false 表示顺时针(默认是顺时针)。
- 角度转弧度公式为
Math.PI / 180 * deg
; - 弧度是以 x 轴正方向为基准,进行顺时针或逆时针进行旋转的;
- 当逆时针绘制时,如果要绘制一个 60 度的扇形,则角度值要用 360 减去 60 后的值。
绘制方向与角度的关系:
代码如下:
init();
var ctx;
function init() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (!canvas.getContext) return;
ctx = canvas.getContext("2d");
ctx.strokeRect(0,0,300,150);
draw();
}
function draw(){
//左侧,顺时针绘制
ctx.beginPath();
ctx.moveTo(70,70)
ctx.arc(70,70,50,Math.PI/180*0,Math.PI/180*60,);
ctx.fillStyle="blue";
ctx.fill();
//右侧,逆时针绘制
ctx.beginPath();
ctx.moveTo(200,70)
ctx.arc(200,70,50,Math.PI/180*0,Math.PI/180*60,true);
ctx.fillStyle="blue";
ctx.fill();
}
绘制一个笑脸:
代码如下:
init();
var ctx;
function init() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (!canvas.getContext) return;
ctx = canvas.getContext("2d");
ctx.strokeRect(0,0,300,150);
ctx.strokeStyle="orange"
draw();
}
function draw(){
//右边眼睛
ctx.beginPath();
ctx.arc(40,40,10,Math.PI/180*0,Math.PI/180*180,true);
ctx.stroke();
//右边眼睛
ctx.beginPath();
ctx.arc(70,40,10,Math.PI/180*0,Math.PI/180*180,true);
ctx.stroke();
//嘴巴
ctx.beginPath();
ctx.arc(55,50,20,Math.PI/180*20,Math.PI/180*160);
ctx.stroke();
//脸
ctx.beginPath();
ctx.arc(55,50,40,Math.PI/180*0,Math.PI/180*360);
ctx.stroke();
}
绘制环状图:
代码如下:
init();
var ctx;
function init() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (!canvas.getContext) return;
ctx = canvas.getContext("2d");
ctx.strokeRect(0,0,300,150);
draw();
}
//环状图
function draw(){
//外侧半圆弧线
ctx.beginPath();
ctx.arc(120,100,90,Math.PI/180*0,Math.PI/180*180,true);
ctx.fillStyle="red";
ctx.fill();
//内侧半圆弧线
ctx.beginPath();
ctx.arc(120,100,65,Math.PI/180*0,Math.PI/180*180,true);
ctx.fillStyle="white";
ctx.fill();
//外侧弧度弧线
ctx.beginPath();
ctx.moveTo(122,100)
ctx.arc(120,100,90,Math.PI/180*0,Math.PI/180*300,true);
ctx.fillStyle="blue";
ctx.fill();
//内侧弧度弧线
ctx.beginPath();
ctx.moveTo(120,100)
ctx.arc(120,100,65,Math.PI/180*0,Math.PI/180*300,true);
ctx.fillStyle="white";
ctx.fill();
}
2、arcTo()
arcTo(x1, y1, x2, y2, radius)
根据给定的控制点和半径画一段圆弧,最后再以直线连接两个控制点。x1,y1为第一个控制点坐标;x2,y2为第二个控制点坐标;radius为圆弧半径。
- 这个方法可以这样理解。绘制的弧形是由两条切线所决定。
- 第 1 条切线:起始点和控制点1决定的直线。
- 第 2 条切线:控制点1 和控制点2决定的直线。
- 其实绘制的圆弧就是与这两条直线相切的圆弧。
代码如下:
init();
var ctx;
function init() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (!canvas.getContext) return;
ctx = canvas.getContext("2d");
ctx.strokeRect(0,0,300,150);
ctx.strokeStyle="orange"
draw();
}
function draw(){
ctx.moveTo(90, 30);
ctx.arcTo(200, 30, 200, 150, 100);
ctx.stroke();
}
绘制贝塞尔曲线
贝塞尔曲线于 1962,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau 于 1959 年运用 de Casteljau 演算法开发,以稳定数值的方法求出贝兹曲线。
贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。
quadraticCurveTo()
二次贝塞尔曲线,quadraticCurveTo(x1,y1,x2,y2),前两个参数为控制点坐标,后两个参数为结束点坐标。
代码如下:
function draw() {
ctx.beginPath();
ctx.moveTo(25, 100);
ctx.quadraticCurveTo(20, 50, 100, 100);
ctx.stroke();
}
绘制圆角矩形
代码如下:
init();
var ctx;
function init() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (!canvas.getContext) return;
ctx = canvas.getContext("2d");
ctx.strokeRect(0, 0, 300, 150);
ctx.strokeStyle = "orange";
ctx.lineWidth=5;
draw();
}
function draw() {
var x=20,y=20;
var width=150,height=100;
var radius=20;
ctx.beginPath();
ctx.moveTo(x, y + radius);
ctx.lineTo(x, y + height - radius);
ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
ctx.lineTo(x + width - radius, y + height);
ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
ctx.lineTo(x + width, y + radius);
ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
ctx.lineTo(x + radius, y);
ctx.quadraticCurveTo(x, y, x, y + radius);
ctx.stroke();
}
绘制爱心:
代码如下:
init();
var ctx;
function init() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (!canvas.getContext) return;
ctx = canvas.getContext("2d");
ctx.strokeRect(0, 0, 300, 150);
ctx.strokeStyle = "orange";
ctx.lineWidth=5;
draw();
}
function draw() {
ctx.beginPath();
ctx.moveTo(75, 40);
ctx.bezierCurveTo(75, 37, 70, 25, 50, 25);
ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
ctx.bezierCurveTo(20, 80, 40, 102, 75, 120);
ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
ctx.bezierCurveTo(85, 25, 75, 37, 75, 40);
ctx.stroke();
}
绘制文本
canvas 提供了两种方法来渲染文本:
- fillText(text, x, y [, maxWidth]) ,指在指定的 (x,y) 位置填充指定的文本,最后一个参数绘制的最大宽度是可选的。
- strokeText(text, x, y [, maxWidth]) 在指定的 (x,y) 位置绘制文本边框,最后一个参数绘制的最大宽度是可选的。
设置文本样式:
- font = value 当前我们用来绘制文本的样式。这个字符串使用和 CSS font 属性相同的语法。 默认的字体是 10px sans-serif。
- textAlign = value 文本对齐选项。 可选的值包括:start, end, left, right or center。 默认值是 start。
值 | 描述 |
---|---|
start、left | start为默认值。文本在指定的位置开始,left表示文本左对齐。 |
end、right | 文本在指定的位置结束,right表示文本右对齐。 |
center | 文本的中心被放置在指定的位置 |
在指定位置的y值画一条线,各个值效果如下:
- textBaseline = value 基线对齐选项,可选的值包括:alphabetic, top, hanging, middle, ideographic, bottom。默认值是 alphabetic。
值 | 描述 |
---|---|
alphabetic | 默认。文本基线是普通的字母基线。 |
top | 文本基线是 em 方框的顶端。 |
hanging | 文本基线是悬挂基线。 |
middle | 文本基线是 em 方框的正中。 |
ideographic | 文本基线是表意基线。 |
bottom | 文本基线是 em 方框的底端。 |
在指定位置的x值画一条线,各个值效果如下:
- direction = value 文本方向。可能的值包括:ltr, rtl, inherit。默认值是 inherit。
- measureText(),将返回一个 TextMetrics 对象的宽度、所在像素,这些体现文本特性的属性。
代码如下:
init();
var ctx;
function init() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (!canvas.getContext) return;
ctx = canvas.getContext("2d");
ctx.strokeRect(0, 0, 300, 150);
draw();
}
function draw() {
ctx.fillStyle="red";
ctx.strokeStyle="blue";
ctx.font="40px 宋体";
ctx.textBaseline="top";
ctx.fillText("Canvas",50,20);
ctx.strokeText("Canvas",50,80);
var text=ctx.measureText("Canvas");
console.log(text);//打印结果如下
}
ctx.measureText() 打印结果:
案例:绘制对话气泡
代码如下:
init();
var ctx;
function init() {
let canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (!canvas.getContext) return;
ctx = canvas.getContext("2d");
ctx.strokeRect(0, 0, 300, 150);
draw();
}
function draw() {
ctx.strokeStyle = "orange";
ctx.lineCap="round";
ctx.lineWidth=5;
//绘制气泡
ctx.beginPath();
ctx.moveTo(75, 25);
ctx.quadraticCurveTo(25, 25, 25, 62.5);
ctx.quadraticCurveTo(25, 100, 50, 100);
ctx.quadraticCurveTo(50, 120, 30, 125);
ctx.quadraticCurveTo(60, 120, 65, 100);
ctx.quadraticCurveTo(125, 100, 125, 62.5);
ctx.quadraticCurveTo(125, 25, 75, 25);
ctx.stroke();
//绘制文字
ctx.fillStyle = "red";
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 2;
ctx.shadowColor = "#999";
ctx.font = "24px 宋体";
ctx.textBaseline = "top";
ctx.fillText("Canvas", 35, 50);
}