canvas 基础入门(四)
【今日学习目录】
- canvas中怎么使用图片
- canvas中怎么使用阴影
- canvas中绘制文本信息
【今日完成目标】
经过这么多天的分享,canvas的基础应该还是掌握了一些,今天就来实现一个基础班的折线图,进阶版:尝试一下用数据驱动,动态创建这个折线图。
1、使用图片
在canvas中使用图片,需要用到JavaScript中原生提供的Image的构造函数来生成一个图片对象,因为canvas提供的图片方法接受两个参数。第一个参数就是一个图片的对象或者是一个另外的canvas对象,第一个参数是决定当前图片是否重复平铺,跟css中的background-repeat一样的参数:repeat、repeat-x、repeat-y、no-repeat。通过 createPattern 方法来创建图片。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>canvas 基础入门(四)</title>
<style>
#canvasBox{
border: 1px solid #ccc;
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<canvas width="500" height="500" id="canvasBox"> 您浏览器暂不支持 canvas 标签的渲染,请选择 谷歌浏览器或者火狐浏览器打开浏览~ </canvas>
<script type="text/javascript">
// 获取到canvas盒子
let canvas = document.getElementById("canvasBox");
// 获取canvas的上下文对象
let ctx = canvas.getContext("2d");
// 判断当前浏览器是否支持
if ( ctx ) {
// 生成图片对象
let img = new Image();
// 加载图片路径
img.src = "./1.jpg";
// 监听图片加载成功
img.onload = () => {
// 创建canvas图片对象
let ctxImg = ctx.createPattern(img, 'repeat');
// 赋值给样式
ctx.fillStyle = ctxImg;
// 创建矩形
ctx.fillRect(10, 10, 300, 300);
}
} else {
console.log("您当前浏览器不支持canvas");
}
</script>
</body>
</html>
复制代码
【效果图】
可以看到 createPattern 的第二个参数为repeat的时候,是会x、y轴都会平铺。对应修改第二个参数,会有不同的平铺效果。
【repeat-x】
【repeat-y】
【no-repeat】
2、使用阴影
在很多网站中都可以看到阴影的效果,文字阴影,盒子阴影。使用的还是比较多的。在canvas中也支持阴影的绘制。
canvas提供了四个属性来设置阴影效果,shadowOffsetX 设置阴影在x轴延申的位置,shadowOffsetY 设置阴影在y轴延申的位置,shadowBlur 设置阴影的模糊程度。两个属性的默认值是0,shadowColor 是设置阴影的颜色,与 CSS 的颜色统一标准,默认是全透明的黑色。
通过一个小例子来感受一下canvas的阴影效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>canvas 基础入门(四)</title>
<style>
#canvasBox{
border: 1px solid #ccc;
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<canvas width="500" height="500" id="canvasBox"> 您浏览器暂不支持 canvas 标签的渲染,请选择 谷歌浏览器或者火狐浏览器打开浏览~ </canvas>
<script type="text/javascript">
// 获取到canvas盒子
let canvas = document.getElementById("canvasBox");
// 获取canvas的上下文对象
let ctx = canvas.getContext("2d");
// 判断当前浏览器是否支持
if ( ctx ) {
// 设置 阴影 延申位置
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
// 设置模糊程度
ctx.shadowBlur = 10;
// 设置阴影颜色
ctx.shadowColor = "rgba(255,0,255, 0.5)";
// 设置盒子的颜色
ctx.fillStyle = "#f0f";
// 绘制矩形
ctx.fillRect(100, 100, 100, 100);
} else {
console.log("您当前浏览器不支持canvas");
}
</script>
</body>
</html>
复制代码
【效果图】
在canvas中使用阴影还是比较方便的,四个属性就可以把阴影效果展现出来。刚是设置的正向的阴影,设置位置的时候,值是可以为负数的,给盒子的上方以及右方添加阴影。
// 设置 阴影 延申位置
ctx.shadowOffsetX = -10;
ctx.shadowOffsetY = -10;
复制代码
【效果图】
细心的小伙伴应该可以发现一个问题,就是,canvas好像没有提供一个同时左右都有阴影的属性,那怎么才能让盒子四周都有阴影呢。
由于canvas没有像html中css样式提供的shadow哪有有五个参数,设置扩散范围。那么只能看到一个简单的四周阴影效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>canvas 基础入门(四)</title>
<style>
#canvasBox{
border: 1px solid #ccc;
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<canvas width="500" height="500" id="canvasBox"> 您浏览器暂不支持 canvas 标签的渲染,请选择 谷歌浏览器或者火狐浏览器打开浏览~ </canvas>
<script type="text/javascript">
// 获取到canvas盒子
let canvas = document.getElementById("canvasBox");
// 获取canvas的上下文对象
let ctx = canvas.getContext("2d");
// 判断当前浏览器是否支持
if ( ctx ) {
// 设置 阴影 延申位置
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// 设置模糊程度
ctx.shadowBlur = 20;
// 设置阴影颜色
ctx.shadowColor = "rgba(255,0,255, 1)";
// 设置盒子的颜色
ctx.fillStyle = "#f0f";
// 绘制矩形
ctx.fillRect(100, 100, 100, 100);
} else {
console.log("您当前浏览器不支持canvas");
}
</script>
</body>
</html>
复制代码
【效果图】
3、绘制文本
之前我们学了怎么画一条线,怎么画一个圆,画一个有弧度的形状,设置样式,使用图片,使用阴影。一直还没涉及到如果设置一个文字,canvas常见的使用场景,图表插件,分享海报,以及其他的一些图片合成的算法和小游戏的开发。文字肯定是必不可少的。
canvas 提供了两个绘制文本的方法。fillText( text, x, y [, maxWidth ] ), strokeText( text, x, y[, maxWidth] ), 两个方法参数是一样的。第一个参数是需要绘制的文本信息,x,y确定文本开始绘制的位置。最后一个参数是可选的,是绘制文本最大的宽度。如果文字超出了。会对文字进行缩放。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>canvas 基础入门(四)</title>
<style>
#canvasBox{
border: 1px solid #ccc;
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<canvas width="500" height="500" id="canvasBox"> 您浏览器暂不支持 canvas 标签的渲染,请选择 谷歌浏览器或者火狐浏览器打开浏览~ </canvas>
<script type="text/javascript">
// 获取到canvas盒子
let canvas = document.getElementById("canvasBox");
// 获取canvas的上下文对象
let ctx = canvas.getContext("2d");
// 判断当前浏览器是否支持
if ( ctx ) {
// 设置文本大小
ctx.font = "40px serif";
// 绘制填充文本
ctx.fillText("hello word", 100, 100);
// 绘制空心文本
ctx.strokeText("hello word", 100, 200);
} else {
console.log("您当前浏览器不支持canvas");
}
</script>
</body>
</html>
复制代码
【效果图】
刚刚上面的例子中,我用到了一个font属性,对文字大小进行了修改。canvas 提供了四个属性设置文本的样式。font 跟css中的fon属性是一样的。textAlign 设置文本对齐方式: start、end、left、 right、或者 center, 默认值是start。textBaseline 设置基线对齐方式:top, hanging, middle, alphabetic, ideographic, bottom,默认值是 alphabetic。direction 设置文本的方向:lrt, rtl, inherit
4、实现一个简单的折线图
【分析】
-
x轴刻度线
-
底部x轴划分y轴时间线的数据
-
折线图位置
首先需要我们实现一个简单版的折线图。最高是300,x轴每个刻度相隔50高度。y轴距离分成七份,简单分析后,我们需要绘画的有三大部分,线段,文字,圆点。那么我们对实现三个方法。绘制不同内容。
【绘制线段】
// 绘制线段的方法 开始点xy,结束点xy, 颜色值 默认是黑色
let line = ( startX, startY, endX, endY, color = "#000" ) => {
// 设置颜色
ctx.strokeStyle = color;
// 生成路径
ctx.beginPath();
// 设置笔触
ctx.moveTo(startX,startY);
// 第一笔
ctx.lineTo(endX, endY);
// 关闭路径
ctx.closePath();
ctx.stroke();
}
复制代码
【绘制文字】
// 绘制文字 文本, 绘制开始坐标,字体大小
let text = (text, x, y, fontSize = 16) => {
// 设置文字大小
ctx.font = fontSize + 'px serif';
// 绘制文本
ctx.fillText(text, x, y);
}
复制代码
【绘制圆】
// 绘制圆 中心点位置,半径
let round = ( x, y, r ) => {
// 生成路径
ctx.beginPath();
// 绘制圆
ctx.arc(x, y, r, 0, Math.PI / 180 * 360, false);
ctx.stroke();
}
复制代码
辅助函数都已经准备好了。我们现来绘制折线图的x轴和y轴。首先确定一下分割线的距离。x轴的线,需要从总高度 / 刻度线 = 分割线距离。写着写着突然发现,这个计算规则有问题。略微尴尬,数学真是硬伤呀
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>canvas 基础入门(四)</title>
<style>
#canvasBox{
border: 1px solid #ccc;
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<canvas width="500" height="500" id="canvasBox"> 您浏览器暂不支持 canvas 标签的渲染,请选择 谷歌浏览器或者火狐浏览器打开浏览~ </canvas>
<script type="text/javascript">
// 获取到canvas盒子
let canvas = document.getElementById("canvasBox");
// 获取canvas的上下文对象
let ctx = canvas.getContext("2d");
// 判断当前浏览器是否支持
if ( ctx ) {
// 绘制线段的方法 开始点xy,结束点xy, 颜色值 默认是黑色
let line = ( startX, startY, endX, endY, color = "#000" ) => {
// 设置颜色
ctx.strokeStyle = color;
// 生成路径
ctx.beginPath();
// 设置笔触
ctx.moveTo(startX,startY);
// 第一笔
ctx.lineTo(endX, endY);
// 关闭路径
// ctx.closePath();
ctx.stroke();
}
// 绘制文字 文本, 绘制开始坐标,字体大小
let text = (text, x, y, fontSize = 16) => {
// 设置文字大小
ctx.font = fontSize + 'px serif';
// 绘制文本
ctx.fillText(text, x, y);
}
// 绘制圆 中心点位置,半径
let round = ( x, y, r ) => {
// 生成路径
ctx.beginPath();
// 绘制圆
ctx.arc(x, y, r, 0, Math.PI / 180 * 360, false);
ctx.stroke();
}
// 绘制方法
let polyline = () => {
// 定义盒子总高度,宽度, 我们定义canvas高度是500,这里我们取400
let H = 400,
W = 400;
// 获取到x轴之间距离
let X = parseInt(400 / 7);
// 获取Y轴之间距离
let Y = parseInt(400 / 8);
// 绘制折线的数据
let lineData = [50, 130, 150, 88, 250, 33, 300];
// 时间线的数据
let timeData = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
// 绘制x轴的线
[7,6,5,4,3,2,1].forEach((item, index) => {
// 画线
line(50,50 + X * index, W, 50 + X * index, item === 1 ? "#000" : "#ccc" );
console.log(50 + X * index)
// 标注刻度值
text((item - 1) * 50, 20,56 + X * index);
})
// 画时间分割线
for ( let i = 0, len = timeData.length + 1; i < len; i++ ) {
// 画线
line(50 + Y * i,X * 6 + 50, 50 + Y * i, X * 6 + 50 + 10);
if ( len - 1 > i ) {
// 标注刻度时间
text(timeData[i], 65 + Y * i, X * 6 + 65, 13);
}
}
// 绘制折线图
lineData.forEach(( item, index ) => {
if ( index === 0 ) {
ctx.moveTo(50 + Y * (index + 1), 400 - item - 14 );
ctx.lineTo(50 + Y * (index + 1), 400 - item - 14 );
} else {
ctx.lineTo(50 + Y * (index + 1), 400 - item - 14 );
}
ctx.stroke();
})
}
polyline();
} else {
console.log("您当前浏览器不支持canvas");
}
</script>
</body>
</html>
复制代码
【效果图】
进阶版没时间去实现了。突然临近下班,来项目了。靠各位大佬去实现了。