canvas中的样式与文本

711 阅读2分钟

【这是我参与更文挑战的第2天,活动详情查看: 更文挑战

图形的着色区域有两种

描边区域: strokeStyle 代表了描边样式,描边区域的绘制方法是 stroke()、strokeRect() 或者strokeText() 。 填充区域: fillStyle 代表了填充样式,填充区域的绘制方法是 fill()、fillRect() 或者fillText() 。

image.png

图形的着色方式有3种

  • 纯色
    • 书写方式(与css 一致):
      • red
      • #000000
      • rgb(r,g,b)
      • rgba(r,g,b,a)  
    • 赋值方式
      • ctx.fillStyle= 'red'
      • ctx.strokeStyle= 'rgb(r,g,b)'
  • 渐变
    • 建立渐变对象的方式:
      • 线性渐变: gradient=createLinearGradient(x1, y1, x2, y2)

image.png - 径向渐变 gradient=createRadialGradient(x1, y1, r1, x2, y2, r2)  

image.png

  • 定义渐变的颜色节点  gradient.addColorStop(position, color)  
  • 赋值方式
    • ctx.fillStyle= gradient
    • ctx.strokeStyle= gradient 
  • 纹理 
    • 建立纹理对象:
      • pattern=context.createPattern(image,"repeat|repeat-x|repeat-y|no-repeat");  
    • 为着色样式赋值
      • ctx.fillStyle= pattern
      • ctx.strokeStyle= pattern 

image.png

描边样式

影响描边样式的因素 

strokeStyle:描边的颜色。

ctx.strokeStyle = 'red'

lineWidth:描边宽。定义描边的宽度,它是从路径的中心开始绘制的,内外各占宽度的一半。

ctx.lineWidth = 40;

image.png

lineCap:描边端点样式。

<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    //canvas充满窗口
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;
    //画笔
    const  ctx=canvas.getContext('2d');

    /*strokeStyle:描边的着色样式*/
    ctx.strokeStyle='maroon';

    /*lineWidth:描边宽*/
    ctx.lineWidth=40;

    /*lineCap 描边端点样式
    *   butt 没有端点,默认
    *   round 圆形端点
    *   square 方形端点
    * */
    ctx.save();
    ctx.lineCap='butt';
    ctx.beginPath();
    ctx.moveTo(50,50);
    ctx.lineTo(400,50);
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.lineCap='round';
    ctx.beginPath();
    ctx.moveTo(50,150);
    ctx.lineTo(400,150);
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.lineCap='square';
    ctx.beginPath();
    ctx.moveTo(50,250);
    ctx.lineTo(400,250);
    ctx.stroke();
    ctx.restore();
</script>

image.png

lineJoin:描边拐角类型 。

<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    //canvas充满窗口
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    //画笔
    const  ctx=canvas.getContext('2d');

    /*strokeStyle:描边的着色样式*/
    ctx.strokeStyle='maroon';

    /*lineWidth:描边宽*/
    ctx.lineWidth=40;

    /*lineJoin 拐角类型
    *   miter 尖角
    *   round 圆角
    *   bevel 切角
    * */
    ctx.save();
    ctx.lineJoin='miter';
    ctx.beginPath();
    ctx.moveTo(50,50);
    ctx.lineTo(400,50);
    ctx.lineTo(200,150);
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.lineJoin='round';
    ctx.beginPath();
    ctx.moveTo(50,250);
    ctx.lineTo(400,250);
    ctx.lineTo(200,350);
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.lineJoin='bevel';
    ctx.beginPath();
    ctx.moveTo(50,450);
    ctx.lineTo(400,450);
    ctx.lineTo(200,550);
    ctx.stroke();
    ctx.restore();
</script>

image.png

miterLimit:拐角最大厚度(只适用于lineJoin=‘miter’ 的情况)。

<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    //canvas充满窗口
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;
    //画笔
    const  ctx=canvas.getContext('2d');

    /*strokeStyle:描边的着色样式*/
    ctx.strokeStyle='maroon';

    /*lineWidth:描边宽*/
    ctx.lineWidth=40;

    /*miterLimit 拐角限制,number 类型,如2,1,3*/
    ctx.save();
    ctx.miterLimit=2;
    ctx.beginPath();
    ctx.moveTo(50,50);
    ctx.lineTo(400,50);
    ctx.lineTo(400,150);
    ctx.stroke();
    ctx.restore();
</script>

image.png

setLineDash(segments):将描边设置为虚线,可以通过getLineDash() 方法获取虚线样式。

<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    //canvas充满窗口
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;
    //画笔
    const  ctx=canvas.getContext('2d');

    /*strokeStyle:描边的着色样式*/
    ctx.strokeStyle='maroon';

    /*lineWidth:描边宽*/
    ctx.lineWidth=4;

    /* setLineDash(segments) 虚线 */
    ctx.save();
    ctx.beginPath();
    ctx.moveTo(50,100);
    ctx.lineTo(700,100);
    ctx.setLineDash([30,60,90]);
    ctx.stroke();
    ctx.restore();
</script>

image.png

lineDashOffset:虚线的偏移量。

<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    //canvas充满窗口
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;
    //画笔
    const  ctx=canvas.getContext('2d');

    /*strokeStyle:描边的着色样式*/
    ctx.strokeStyle='maroon';

    /*lineWidth:描边宽*/
    ctx.lineWidth=4;

    /* lineDashOffset 虚线偏移  */
    ctx.save();
    ctx.beginPath();
    ctx.moveTo(50,100);
    ctx.lineTo(700,100);
    ctx.setLineDash([60]);
    ctx.stroke();
    ctx.restore();

    ctx.save();
    ctx.beginPath();
    ctx.moveTo(50,150);
    ctx.lineTo(700,150);
    ctx.setLineDash([60]);
    ctx.lineDashOffset=-90;
    ctx.stroke();
    ctx.restore();
</script>

image.png

霓虹灯

实现思路:

  • 爱心:两个三次贝塞尔曲线
  • 描边
  • 虚线偏移
<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    // canvas充满窗口
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;
    // 画笔
    const  ctx=canvas.getContext('2d');

    // 颜色数组
    const colors=['red','yellow'];

    function draw(){
        // 保存上下文对象的状态
        ctx.save();
        // 偏移坐标系
        ctx.translate(300,400);
        // 开始绘制路径
        ctx.beginPath();
        // 向路径集合中添加子路径
        // 绘制心形子路径
        // 设置路径起点
        ctx.moveTo(0,0);
        // 用两个三次贝塞尔曲线组成爱心
        ctx.bezierCurveTo(-200,-50,-180,-300,0,-200);
        ctx.bezierCurveTo(180,-300,200,-50,0,0);
        // 设置描边宽度
        ctx.lineWidth=10;
        ctx.setLineDash([30]);
        /*--------虚线1-------*/
        // 描边颜色
        ctx.strokeStyle=colors[0];
        // 以描边的方式显示路径
        ctx.stroke();
        /*--------虚线2-------*/
        // 描边颜色
        ctx.lineDashOffset=30;
        ctx.strokeStyle=colors[1];
        // 以描边的方式显示路径
        ctx.stroke();
        // 将上下文对象的状态恢复到上一次保存时的状态
        ctx.restore();
    }

    setInterval(function(){
        draw();
        colors.reverse();
    },200)
</script>

GIF 2020-12-27 22-00-58.gif

文本属性
  • 字体:fontcanvas里得font属性和css的font属性是一样的,它可以设置文本的粗细、字号、字体等
    • css设置字体:p{font:bold 18px serif}
    • canvas设置字体:ctx.font = 'bold 18px serif'
  • 水平对齐: textAlign下方文字的x位置都是一样,都是垂直虚线的x位置,它们的textAlign的属性各不相同 image.png
    • start和end受html的dir属性影响

image.pngimage.png 默认情况:<html dir="ltr">                    <html dir="rtl">

  • 垂直对齐: textBaselinen

image.png MDN 文档

alphabetic默认。标准字母基线对齐 
top上对齐 
hanging悬挂基线对齐 
middle垂直居中 
ideographic表意字基线对齐 
bottom下对齐 
文本的绘制方法
  • 填充文字 fillText(text, x, y, maxWidth)
  • 描边文字 strokeText(text, x, y, maxWidth)
  • 获取文字宽度的方法:measureText(text)
布艺文字
  • 要点:fillText(), strokeText(), setLineDash(), shadowColor, shadowBlur, shadowOffsetY 

image.png 实现上图的代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>文本</title>
    <style>
        body {
            margin: 0;
            overflow: hidden
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
    <script>
        const canvas = document.getElementById('canvas');
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        const ctx = canvas.getContext('2d');

        /*文字内容*/
        const text = 'canvas';

        /*文字位置*/
        const [x, y] = [50, 200];

        /*字体属性,文字加粗,大小:200px,字体:arial*/
        ctx.font = 'bold 200px arail';

        /*投影,颜色:rgba(0,0,0,0.6),垂直偏移:2,模糊:4*/
        ctx.shadowColor = 'rgba(0,0,0,0.6)';
        ctx.shadowOffsetY = 2;
        ctx.shadowBlur = 4;

        /*填充文字,颜色:#a76921*/
        ctx.fillStyle = '#a76921';
        ctx.fillText(text, x, y);

        /*实线描边文字,颜色:#f0d5ac,线宽:8*/
        ctx.strokeStyle = '#f0d5ac';
        ctx.lineWidth = 8;
        ctx.strokeText(text, x, y);

        /*虚线描边文字,颜色:#333,线宽:1,线段长度[5,3]*/
        ctx.strokeStyle = '#333';
        ctx.lineWidth = 1;
        ctx.setLineDash([5, 3]);
        ctx.strokeText(text, x, y);
    </script>
</body>

</html>