canvas 概念
绘图技术(canvas)
HTML5新增了
<canvas></canvas>
,它就像一块幕布,可以用JavaScript配套API 在上面绘制各种图表、配合定时器实现各种动画等。Javascript本身支持canvas和webGL两种绘图技术,Canvas是2d绘制,webGL是3d绘制
JavaScript绘图基础
画布 <canvas></canvas>
- 指的是HTML5中的canvas标签,它在JavaScript的绘制技术中充当”画布”的角色。一个Canvas定义了一个指定尺寸的矩形框,在这个范围内我们可以随意绘制,一个页面可以有多个画布。
画笔
- 是JavaScript提供的一个对象。每个画布都有一个专属的”画笔”。画笔里包含了大量的绘制相关api。开发人员利用api来在
<canvas>
中进行绘制。
获取画布和画笔
- 画布:通过原生dom函数获取
- 画笔:通过画布调用
getContext('2d')
来获取
//html:
<canvas width="300" height="300" id="myCanvas"></canvas>
//JavaScript:
//1. 获取画布
var canvas = document.querySelector("#myCanvas");
//2. 获取画笔,ctx就是画笔变量名
var ctx = canvas.getContext('2d');
由于浏览器对HTML5标准支持不一致,所以,通常在
<canvas>
内部添加一些说明性HTML代码,如果浏览器支持Canvas,它将忽略<canvas>
内部的HTML,如果浏览器不支持Canvas,它将显示<canvas>
内部的HTML
在使用Canvas前,用
canvas.getContext
来测试浏览器是否支持Canvas:var canvas = document.getElementById('test-canvas'); if (canvas.getContext) { console.log('你的浏览器支持Canvas!'); } else { console.log('你的浏览器不支持Canvas!'); }
画布中的坐标系
- 以画布的左上角为原点
(0,0)
.x轴向右为正。y轴向下为正
canvas绘图
路径&子路径
- 路径:画布会把一段闭合的线条称为一个完整路径。一个完整路径包含了多个子路径。
- 画布的 一个图形就是一个完整的路径
- 子路径:是绘图当中的一个线条。多个子路径可以构成一个闭合的完整的路径
canvas API
几何图形
moveTo()
:确定”落笔”的位置。将画笔移动到指定坐标。画笔变量名.moveTo(x坐标,y坐标);
lineTo()
:从画笔位置到指定位置勾勒出一条子路径画笔变量名.lineTo(x坐标,y坐标);
stroke()
:绘制已经勾勒出的所有子路径画笔变量名.stroke();
lineWidth
:设置线条的粗细程度画笔变量名.lineWidth = 5;
strokeStyle
:设置线条的颜色画笔变量名.strokeStyle = "red";
弧形
arc()
:勾勒出一个弧形子路径画笔变量名.arc(圆心x坐标,圆心y坐标,半径,开始角度,结束角度,是否逆时针)
- 是否逆时针:为true则按逆时针方向绘制。false或不写则按顺时针进行绘制
- 在JavaScript中,用
Math.PI
表示180度。那么一圈的话就是2*Math.PI
.1度为Math.PI/180
fill()
:对图形进行填充画笔变量名.fill();
fillStyle
:设置填充的颜色画笔.fillStyle = "颜色";
canvas动画
- 思路,将画出的弧形,利用定时器,每执行一次,更新开始和结束的位置,清除之前的路径,利用延时定时器,在一段时间之后清除该标签画布
// 获取画布和画笔
var canvas = document.querySelector("#demo");
var ctx = canvas.getContext('2d');
// canvas全屏
// canvas.setAttribute('width',innerWidth);
// canvas.setAttribute('height',innerHeight);
// 通过获取画布的宽高,决定圆的中心点
var w = canvas.getAttribute("width");
var h = canvas.getAttribute("height");
// 在画布中心点勾勒出四分之一圆
var start = 0;
var end = Math.PI/2;
var increment = Math.PI/90;
var endTime =3000;//loading结束时间
// 间隔定时器
var timer =setInterval(() => {
// 清屏 该方法清空给定矩形内的指定像素。
ctx.clearRect(0,0,w,h);
//方法开始一条路径,或重置当前的路径
ctx.beginPath();
ctx.arc(w/2,h/2,30,start,end);
ctx.stroke();
//更新开始和结束角度
start+=increment;
end+=increment;
}, 5);
setTimeout(() => {
//暂停间隔定时器
clearInterval(timer);
//把画布干掉
document.body.removeChild(canvas);
}, endTime);
封装的loding函数
/**
*
* @param {*} selector :指要使用loading的css选择器,支持多个
* @param {*} time 表示loading动画持续时间
* @param {*} callback 指动画结束后要执行的函数
*/
function loading(selector,time,callback){
var elems = document.querySelectorAll(selector);
if(elems.length>1){
elems.forEach(elem=>{
innerloading(elem);
});
}else{
innerloading(elems[0]);
}
function innerloading(elem){
var style = getComputedStyle(elem,null);
var w= style.width;
var h = style.height;
var canvas = document.createElement('canvas');
canvas.style.width = w;
canvas.style.height = h;
canvas.width = parseInt(w);
canvas.height = parseInt(h);
// canvas.style.backgroundColor="rgba(0,0,0,0.6)";
canvas.style.backgroundColor="rgba(0,0,0,0.3)";
canvas.className= "loadingCanvas";
canvas.style.display="block";
canvas.style.position='absolute';
canvas.style.top='0px';
canvas.style.left = "0px";
canvas.style.zIndex=99;
var position = getComputedStyle(elem,null).position;
if(position=='static'){elem.style.position = 'relative'};
elem.appendChild(canvas);
var ctx= canvas.getContext('2d');
var begin_angle = 0;
var length = Math.PI/2;
var timer = setInterval(()=>{
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.arc(canvas.width/2,canvas.height/2,20,begin_angle,begin_angle + length,false);
// ctx.strokeStyle="white";
ctx.stroke();
begin_angle+=0.04*Math.PI;
},16.7);
setTimeout(() => {
clearInterval(timer);
canvas.style.display = 'none';
elem.removeChild(canvas);
if(callback){
callback();
}
}, time);
}
}