阅读 376
二哥-canvas 基础入门(四)

二哥-canvas 基础入门(四)

canvas 基础入门(四)

【今日学习目录】

  • canvas中怎么使用图片
  • canvas中怎么使用阴影
  • canvas中绘制文本信息

【今日完成目标】

image-20210531092342162.png

​ 经过这么多天的分享,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>
复制代码

【效果图】

image-20210531103048985.png

​ 可以看到 createPattern 的第二个参数为repeat的时候,是会x、y轴都会平铺。对应修改第二个参数,会有不同的平铺效果。

【repeat-x】

image-20210531103322369.png

【repeat-y】

image-20210531103343836.png

【no-repeat】

image-20210531103415786.png

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>
复制代码

【效果图】

image-20210531104711932.png

​ 在canvas中使用阴影还是比较方便的,四个属性就可以把阴影效果展现出来。刚是设置的正向的阴影,设置位置的时候,值是可以为负数的,给盒子的上方以及右方添加阴影。

// 设置 阴影 延申位置
ctx.shadowOffsetX = -10;
ctx.shadowOffsetY = -10;
复制代码

【效果图】

image-20210531104903890.png

​ 细心的小伙伴应该可以发现一个问题,就是,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>
复制代码

【效果图】

image-20210531105228978.png

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>
复制代码

【效果图】

image-20210531111033085.png

刚刚上面的例子中,我用到了一个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>
复制代码

【效果图】

image-20210531170915160.png

​ 进阶版没时间去实现了。突然临近下班,来项目了。靠各位大佬去实现了。

文章分类
前端
文章标签