Canvas

一、认识canvas

1、什么是canvas

canvas是html5的标签,可以用Javascript在html页面上绘制图形。

2、canvas可以做什么?

  • 绘图(图标,图形的绘制)
  • 数据的可视化(重点)
  • 动画与游戏
  • banner 广告
  • 多媒体、虚拟现实、图形编辑等

3、canvas基本使用

Canvas默认大小为300像素×150像素(宽×高,像素的单位是px),可以使用HTML的高度和宽度属性来自定义Canvas 的尺寸。

注意:Canvas是一个画布(图片),不要使用css样式进行宽高的设置,否则该画布将会被拉升变形

基本代码

<!DOCTYPE html>
 <html>
 <head lang="en">
     <meta charset="UTF-8">
     <title></title>
     <style>
      //通过设置边框样式可以在页面上看到画布的区域
         #c {
             border: 1px solid #000;
         }
     </style>
 </head>
 <body>
 <!-- 准备一个canvas标签,使用行内样式设置画布的大小-->
 <canvas id="c" width="600", height="300"></canvas>
 <script>
     //1. 准备画布(Javascript获取html页面元素进行操控)
     var canvas = document.querySelector("#c");
     //2. 生成画图工具
     var ctx = canvas.getContext("2d");
     //3. 开始画线
     //注意,画图工具会先生成图形路径(就像当于生成玻璃纸)
     //3.1先将画笔移动到起始坐标点
     ctx.moveTo(0, 150);
     //3.2画一条水平直线
     ctx.lineTo(600, 150);
     //4. 线条颜色填充,将玻璃纸复印到画布上
     ctx.stroke();
 </script>
 </body>
 </html>

效果:
在这里插入图片描述

4、canvas兼容性问题

只要浏览器支持此标签就可以生效,如果不支持,就会解析为div标签;

常常在 canvas 中嵌入文本, 以提示用户浏览器的能力

 var canvas = document.getElementById('tutorial');
 if (canvas.getContext){
     var ctx = canvas.getContext('2d');
     // 开始画图
 } else {
     // canvas不支持提示
 }

二、绘制形状

1、绘制直线

1、绘制步骤:

  • 获取canvas,画布
  • 生成ctx,画图工具
  • ctx.moveTo(x, y): 将画笔移动到某个坐标点上
  • ctx.lineTo(x, y), 从画笔所在的点,移动到当前点,即画出一条直线
  • ctx.stroke(),给画的线设置颜色
//获取画布
var canvas = document.getElementById("canvas");
//生成画图工具
var context = canvas.getContext("2d");
//画两条线
context.moveTo(0, 52);
context.lineTo(600, 52);
context.moveTo(50, 0);
context.lineTo(50, 400);
context.strokeStyle = 'red';
context.stroke();

效果:
在这里插入图片描述

2、使用直线绘制其他图形

1、三角形

使用moveTo lineTo strokeStyle stroke() fillStyle fill()

    var canvas = document.getElementById('canvas');
    var context = canvas.getContext("2d");
    //三角形
    context.moveTo(50, 50);
    context.lineTo(150, 50);
    context.lineTo(100, 100);
    context.lineTo(50,50);
    //设置描边颜色
    context.strokeStyle = 'green';
    //描边
    context.stroke();
    //设置填充颜色
    context.fillStyle = 'skyblue';
    //填充
    context.fill();
    //注意:可以同时设置描边和填充颜色

2、四边形

使用moveTo lineTo strokeStyle stroke() fillStyle fill()
beginPath() closePath()

    //在同一块画布上,为了避免描边或者填充时出现后设置的覆盖之前
    //的样式,使用context.beginPath()开启新的路径,相当于使用的
    //新的一块玻璃纸
    context.beginPath();
    context.moveTo(200, 50);
    context.lineTo(300,50);
    context.lineTo(300,150);
    context.lineTo(200,150);
    // context.lineTo(200,50);
    //闭合的图形,可以使用context.closePath(),这样会自动连接起始点,完成闭合
    context.closePath();
    context.strokeStyle = 'red';
    context.stroke();

在这里插入图片描述

3、绘制四边形的方式

1、使用直线绘制

//起始位置
context.moveTo(50, 50);
context.lineTo(150, 50);
context.lineTo(150, 150);
context.lineTo(50,150);
//使用context.closePath()封闭图形
context.closePath();
//描边
context.stroke();

2、直接绘制四边形

context.rect(x, y, w, h);
x为四边形左上角起点横坐标;
y为四边形左上角起点纵坐标;
w为四边形宽度
h为四边形高度

//context.rect(x, y, w, h);
//x为四边形左上角起点横坐标;y为四边形左上角起点纵坐标;
//w为四边形宽度;h为四边形高度;
context.rect(200, 50, 100, 100);
context.stroke();

3、直接绘制描边的四边形

context.strokeRect(x,y,w,h)中的参数与rect中的参数相同

//context.strokeRect(x,y,w,h)中的参数与rect中的参数相同
//设置描边样式
context.strokeStyle = 'red';
context.strokeRect(350, 50, 100, 100);

4、直接绘制填充的四边形

//context.fillRect(x,y,w,h)中的参数与rect中的参数相同
//设置填充样式
context.fillStyle ='skyblue';
context.fillRect(50, 200, 100, 100);

在这里插入图片描述

4、绘制圆弧、扇形和圆

1、圆弧

绘制圆弧context.arc(x, y, radius, startAngle, endAngle, anticlockwise)

  • x,y为圆心的横纵坐标
  • radius为半径
  • startAngle起始弧度
  • endAngle结束弧度
  • anticlockwise路径方向,默认值为false顺时针方向,true为逆时针方向
    
    context.arc(300, 200, 150, 0, 30/180*Math.PI);
    context.stroke();

在这里插入图片描述

2、扇形

    //圆弧
    context.arc(300, 200, 150, 0, 30/180*Math.PI);
    //指向圆心的直线
    context.lineTo(300, 200);
    //闭合图形
    context.closePath();
    context.stroke();

在这里插入图片描述

3、圆

    //圆弧的结束弧度到起始弧度的差值为2π则形成圆
    context.arc(300, 200, 150, 0, 2*Math.PI);
    context.stroke();

在这里插入图片描述

5、绘制图表

1、绘制折线图(直线的使用)

//模拟数据
var dataArr = [10,50,11,62,86];
//获取元素
var canvas = document.getElementById('canvas');
//生成工具
var context = canvas.getContext("2d");
//绘制坐标轴
context.moveTo(50, 50);
context.lineTo(50, 350);
context.lineTo(550, 350);
context.stroke();
//计算坐标
var xyArr = [];//创建新数组用于保存计算后的坐标值
for (var i = 0; i < dataArr.length; i++) {
    //x坐标
    var x = 50+i*(canvas.width-100)/(dataArr.length-1);
    //y坐标
    var y = canvas.height-50-(canvas.height-100)/100*dataArr[i];
    //每个数据的坐标值存在一个对象中
    var dataObj = {
        x:x,
        y:y
    };
    //将坐标对象放入新创建的数组中
    xyArr.push(dataObj);
};
//绘制折线
//于之前的坐标轴进行分割
context.beginPath();
//将画笔移动到第一个点的位置
context.moveTo(xyArr[0].x, xyArr[0].y);
//绘制后续的折线
for(var j = 1;j<xyArr.length;j++){
    context.lineTo(xyArr[j].x,xyArr[j].y);
}
// 描边
context.stroke();

在这里插入图片描述

2、绘制直方图(四边形的使用)

    //模拟数据 
    var dataArr = [47,45,87,87,18];
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext("2d");
    //绘制坐标系
    context.moveTo(50, 50);
    context.lineTo(50, 350);
    context.lineTo(550, 350);
    context.stroke();
    //于坐标系进行分隔
    context.beginPath();
    //计算坐标值
    //直方图宽度
    var width = 40;
    //间隔
    var gap = (canvas.width-100-width*dataArr.length)/(dataArr.length+1);
    for (var i = 0; i < dataArr.length; i++) {
        //计算每个数据的横坐标
        var x = 50+gap+i*(width+gap);
        //计算每个数据的高度
        var height = (canvas.height-100)/100*dataArr[i];
        //计算每个数据的纵坐标
        var y = canvas.height-50-height;
        //绘制四边形(带描边)
        context.strokeRect(x, y, width, height);
    }

在这里插入图片描述

3、绘制饼状图(圆弧的使用)

    //模拟数据
    var data = [
        {type:'程序员',count:800,color:'blue'},
        {type:'测试',count:500,color:'red'},
        {type:'设计师',count:450,color:'hotpink'},
        {type:'架构师',count:200,color:'orange'},
        {type:'产品',count:250,color:'green'},
        {type:'程序员鼓励师',count:400,color:'yellow'}
    ];
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext("2d");
    //计算总数
    var sum = 0;
    for (var i = 0; i < data.length; i++) {
        sum += data[i].count;
    }
    console.log(sum);
    //起始弧度
    var starRadian = 0;
    for (var j = 0; j < data.length; j++) {
        //计算占比
        var percent = data[j].count/sum;
        //计算弧度
        var radian = 2*Math.PI*percent;
        //逐个画扇形
        //避免出现填充覆盖问题
        context.beginPath();
        //绘制圆弧
        context.arc(300, 200, 150, starRadian, starRadian+radian);
        //绘制指向圆心的线
        context.lineTo(300, 200);
        //闭合图形,形成扇形
        context.closePath();
        //设置填充颜色
        context.fillStyle = data[j].color;
        //进行颜色填充
        context.fill();
        //起始弧度累加(下一个的开始是上一个的结束)
        starRadian +=radian;
    }

在这里插入图片描述

三、非零填充原则

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        #canvas {
            border: 1px solid #000;
        }
    </style>
</head>
<body>
<canvas id="canvas" width="600px" height="400px"></canvas>
<script>
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');
    //绘制同心圆
    //控制最里面的圆实心空心,只需要设置同心圆的总数,奇数为实心,偶数为空心,详解见最底下
    for(var i=0;i<10;i++){
        //i%2用于设置绘制出的圆的路径方向,使得相邻的两个圆的路径方向相反,在填充的时候依据非零填充原则进行填充
        context.arc(300,200,10+i*15,0,2*Math.PI,i%2);
    }
    //设置填充颜色
    context.fillStyle = 'skyblue';
    //进行填充
    context.fill();
</script>
</body>
</html>

在这里插入图片描述

绘制出的图形为封闭的图形,在填充颜色时遵循“非零填充原则”;

非零填充原则:

1、在封闭图形的内部,任意一点向外发射一条射线,射线会与绘制的图形的路径有交点;

2、图形路径为顺时针记作+1,图形路径为逆时针的时候记作-1;

3、射线与路径的所有交点的和不为0时,则该点在填充区域内,会被填充;如果结果为0,则该点不在填充区域内,不会被填充;

详解:改变代码context.arc(300,200,10+i15,0,2Math.PI,i%2);中变为(i+1)%2是无用的,因为(i+1)%2只是设置顺时针或逆时针,当同心圆个数为偶数时,从最里面的圆射线到最外面圆交点为偶数,总和为0,最里面的圆总是空心;当同心圆个数为奇数时,最里面的圆总是实心;所以应该改变的是for循环里的i控制同心圆个数

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值