web前端:Canvas 基础(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/itwangyang520/article/details/82120457

0.前言

相信各位小伙伴读了之前的文章,对Canvas基础已经有了一定的认识和了解,但是大家也一定记得我在上一篇文章留了一个小的坑。

就是我没有告诉大家该如何去绘制圆,之所以没有说是因为绘制圆实际上是因为CanvasRenderingContext2D对象只提供了两个绘制矩形的方法,并没有直接提供绘制圆,椭圆等几何图形的方法。为了在Canvas上绘制更复杂的方法,必须在Canvas上启用路径,借用路径来绘制图形。

那么我们现在就一起来看一看,该如何使用路径来绘制圆等图形吧。

------------------我是华丽的分割线----------------------

1.使用路径

在Canvas上使用路径,可按照下面的步骤进行。

  1. 调用CanvasRenderingContext2D对象的beginPath()方法开始定义路径。
  2. 调用CanvasRenderingContext2D的各种方法添加子路径。
  3. 调用CanvasRenderingContext2D的closePath方法关闭路径。
  4. 调用CanvasRenderingContext2D的fill()或stroke()方法来填充路径或者绘制路径边框。

那我们明确了该如何去进行应该怎么去使用路径,那么我们接下来就来介绍一下canvas中添加子路径的方法。

- -
arc(float x,float y,float radius,float startAngle,float endAngle,boolean逆时针) 向画布的当前路径上添加一段弧。绘制以x,y为圆心,radius为半径,从startAngle角度开始,到endAngle角度结束的圆弧.startAngle和endAngle以角度为单位。
arcTo(float x1,float x2,float y1,float y2,float radius) 向画布的当前路径上添加一段弧。与上一个方法不同的地方只是定义弧的方式不同。
bezierCurveTo(float cpX1,float cpY1,float cpX2,float cpY2,float x,float y) 在当前路径上添加一段贝塞尔曲线
quadraticCurveTo(float cpX,float cpY,float x,float y) 向帆道当前路径添加一段二次贝塞尔曲线
rect(float x,float y,float width,float height) 向画布的当前路径上添加一个矩形

方法就这些,但是参数就显得非常多了,咱们来一条条的来看看这些方法的具体使用吧。

1.1绘制圆

首先我们来学习下如何绘制圆,首先明确,我们应该去使用arc()方法,那么我们该如何去使用这个方法呢?

咱们,放“码”过来。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div>
        <h2>绘制圆形</h2>
        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
            当前浏览器不支持 canvas
        </canvas>
    </div>
</body>
<script type="text/javascript">
    // 获取 canvas 元素对应的 DOM 对象
    var canvas_1 = document.getElementById("canvas_1");

    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
    var ctx = canvas_1.getContext("2d");

    // 我们多去绘制几个圆形,使用下 for 循环
    for(var i = 0; i < 10 ; i++){
        // 开始定义路径
        ctx.beginPath();
        // 添加一段圆弧
        ctx.arc(i * 25,i * 25,(i + 1) * 8, 0, Math.PI * 2, true);
        // 关闭路径
        ctx.closePath();
        // 设置填充颜色
        ctx.fillStyle = 'rgba(255,0,255,'+ (10 - i) * 0.1 + ')';
        // 填充当前路径
        ctx.fill();
    }
</script>
</html>

最后实现效果如下:

扫描二维码关注公众号,回复: 2951303 查看本文章

Paste_Image.png

不知道小伙伴们是否看懂了上面的程序呢?

如果没看懂也无所谓,咱们就来一起说一说上面内容中的难点。

首先说一下,Math.PI实际上指代的就是π,换而言之也就是180°,那么我们上面使用的角度是Math.PI * 2,也就是绘制了一个圆形。

再说之后一下arc(float x,float y,float radius,float startAngle,float endAngle,boolean counterclockwise)这个方法。

里面一共有6个参数,这六个参数实际上对应的是:

- -
浮动x 指定圆弧的圆心的X坐标
漂浮 指定圆弧的圆心的Y坐标
浮动半径 指定圆弧的半径
float startAngle 设置圆弧的开始角度
float endAngle 设置圆弧的结束角度
boolean逆时针 设置是否顺时针旋转

这样不知道大家对我们绘制圆是否清楚明白了呢?

如果有任何疑问请及时留言回复呦。

1.2绘制圆角矩形

我们之前已经学习过绘制圆形,也学习过绘制矩形,甚至我们也可以通过lineJoin去对我们的元素的圆角去进行修改。

但是,固定的东西我们不需要,我们真正需要的是可以自定义,可以根据我们想要的效果能够随意订制的内容。

为了做到这个目的,我们还可以去使用arcTo来去绘制一段圆弧。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div>
        <h2>绘制圆形</h2>
        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
            当前浏览器不支持 canvas
        </canvas>
    </div>
</body>
<script type="text/javascript">
    /*
        该方法负责绘制圆角矩形
        x1 , y2 : 圆角矩形左上角的坐标
        width,height:控制圆角矩形的宽度和高度
        radius:控制圆角矩形的四个圆角的半径
    */

    function creatRoundRect(ctx, x1, y1, width, height, radius){
        // 移动到左上角的开始点
        ctx.moveTo(x1 + radius, y1);
        // 添加一条连接开始点到右上角的线段
        ctx.lineTo(x1 + width - radius, y1);
        // 添加右上角的一段圆弧
        ctx.arcTo(x1 + width, y1, x1 + width, y1 + radius, radius);
        // 添加一条连接到右下角的线段
        ctx.lineTo(x1 + width, y1 + height - radius);
        // 添加右下角的一段圆弧
        ctx.arcTo(x1 + width, y1 + height, x1 + width - radius, y1 + height, radius);
        // 添加一条由右下角连接到左下角的线段
        ctx.lineTo(x1 + radius, y1 + height);
        // 添加左下的圆弧
        ctx.arcTo(x1, y1 + height, x1, y1 + height - radius,radius);
        // 添加一条由左下角连接到左上角的线段
        ctx.lineTo(x1, y1 + radius);
        // 添加一段圆弧
        ctx.arcTo(x1, y1, x1 + radius, y1, radius);
        ctx.closePath();
    }
    // 获取 canvas 元素对应的 DOM 对象
    var canvas_1 = document.getElementById("canvas_1");

    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
    var ctx = canvas_1.getContext("2d");

    ctx.lineWidth = 3;
    creatRoundRect(ctx, 30, 30, 200, 100, 20);
    ctx.stroke();
</script>
</html>

注意,我在这里分别绘制了四条线和四个弧度角,并且让他们首尾相连,以此来达到绘制矩形框的作用。

其次就是专门去封装了一个函数,用于绘制圆角矩形,回头有需要的小伙伴可以直接自行粘贴呦。

1.3绘制多角形

不知道大家对之前绘制三角形是否还记得?

我们在绘制三角形的时候,主要是去使用lineTo和moveTo这两个方法,可是我们在生活中遇到的图形远远不止这么几种图形。

那么我们今天就来学习一下如何去绘制多角形。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div>
        <h2>绘制多角形</h2>
        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
            当前浏览器不支持 canvas
        </canvas>
    </div>
</body>
<script type="text/javascript">
    /*
        该方法用于绘制多角形
            n:该参数通常设置为奇数,控制绘制 N 角星
            dx、dy:控制 N 角星的位置
            size:控制 N 角星的大小
    */
    function creatStar(context, n, dx, dy, size){
        // 开始创建路径
        context.beginPath();
        var dig = Math.PI / n * 4;
        context.moveTo(dx, y + dy);
        for(var i = 0; i <= n; i++){
            var x = Math.sin(i * dig);
            var y = Math.cos(i * dig);
            // 绘制从当前点连接到指定点的线条
            context.lineTo(x * size + dx, y * size + dy);
        }
        // 关闭路径
        context.closePath();
    }

    // 获取 canvas 元素对应的 DOM 对象
    var canvas_1 = document.getElementById("canvas_1");

    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
    var ctx = canvas_1.getContext("2d");

    // 绘制三角星
    creatStar(ctx, 3, 60, 60, 50);
    ctx.fillStyle = '#f00';
    ctx.fill();
    // 绘制五角星
    creatStar(ctx, 5, 160, 60, 50);
    ctx.fillStyle = '#0f0';
    ctx.fill();
    // 绘制七角星
    creatStar(ctx, 7, 260, 60, 50);
    ctx.fillStyle = '#00f';
    ctx.fill();
    // 绘制九角星
    creatStar(ctx, 9, 360, 60, 50);
    ctx.fillStyle = '#f0f';
    ctx.fill();
</script>
</html>

可以看到我们又去封装了一个方法,专门用于绘制多角星,当然我们也可以在这个基础之上去继续拓展,这些就需要看小伙伴们的发挥啦。

Paste_Image.png

1.4绘制曲线

还记得我们在一开始的时候我们学习了五个方法,除了现在已经学习的绘制圆和绘制圆角矩形,是不是还有一些奇奇怪怪的方法?

那么我们现在就开始来学习这些方法。

首先先来学习一下,添加贝塞尔曲线。

- -
bezierCurveTo(float cpX1,float cpY1,float cpX2,float cpY2,float x,float y) 在当前路径上添加一段贝塞尔曲线
quadraticCurveTo(float cpX,float cpY,float x,float y) 向帆道当前路径添加一段二次贝塞尔曲线

首先来看看第一个方法,第一个方法中实际上有四个点需要注意。

Paste_Image.png

他们分别是

  • 的左下角开始点
  • 红色粉的第一个控制点(锚点)
  • 的藏青色第二个控制点(锚点)
  • 的右上角结束点

而方法中cpX1和cpY1则是控制第一个控制点的坐标,

后面的cpX2和cpY2则是控制第二个控制点的坐标。

而二次贝塞尔曲线又是怎么回事呢?

Paste_Image.png

和正常贝塞尔不同,二次曲线只需要三个点:

  • 的左下角开始点
  • 的藏青色控制点
  • 的右上角结束点

方法中的cpX和cpY则是去设置控制点的坐标。

那么我们来一起试一试,该如何去绘制一个个花朵。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div>
        <h2>绘制花朵</h2>
        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
            当前浏览器不支持 canvas
        </canvas>
    </div>
</body>
<script type="text/javascript">
    /*
        该方法负责绘制花朵
            n:该参数控制花朵的花瓣数
            dx,dy:控制花朵的位置
            size:控制花朵的大小
            length:控制花瓣的长度
    */
    function creatFlower(context, n, dx, dy, size, length){
        // 开始创建路径
        context.beginPath();
        context.moveTo(dx, dy + size);
        var dig = 2 * Math.PI / n;
        for(var i = 1; i < n + 1; i++){
            // 计算控制点的坐标
            var ctrlX = Math.sin((i - 0.5) * dig) * length + dx;
            var ctrlY = Math.cos((i - 0.5) * dig) * length + dy;
            // 计算结束点的坐标
            var x = Math.sin(i * dig) * size + dx;
            var y = Math.cos(i * dig) * size + dy;
            // 绘制二次曲线
            context.quadraticCurveTo(ctrlX, ctrlY, x, y);
        }
        context.closePath();
    }
    // 获取 canvas 元素对应的 DOM 对象
    var canvas_1 = document.getElementById("canvas_1");
    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
    var ctx = canvas_1.getContext("2d");
    // 绘制五瓣的花朵
    creatFlower(ctx, 5, 70, 100, 30, 80);
    ctx.fillStyle = "#f00";
    ctx.fill();
    // 绘制六瓣的花朵
    creatFlower(ctx, 6, 220, 100, 30, 80);
    ctx.fillStyle = "#ff0";
    ctx.fill();
    // 绘制七瓣的花朵
    creatFlower(ctx, 7, 370, 100, 30, 80);
    ctx.fillStyle = "#f0f";
    ctx.fill();
</script>
</html>

1.5绘制位图

一直到现在我们讲了如何去绘制线,三角形,多角星,矩形,圆,花朵,圆角矩形等各种图形。

但是除了这些基础图形之外,我们还可以去绘制“位图”,让一张图片绘制在我们的画布之上。

那我们怎么来做呢?

我们既然想将我们的图片载入到我们的画布中,怎么做呢?我们先来差混构建一个Image对象。

var image = new Image();
image.src = "itwangyang.png";

需要注意两点,

  • 我们的程序只是创建,加载图片,所以调用image时无需传入宽度和高度,这样创建的图像将会与src属性指定的图片保持相同的宽度和高度。
  • 我们可以使用onload去保证我们一定是在图片加载完成后再绘制。
var image = new Image();
image.src = "itwangyang.png";
image.onload =  function(){
  //绘制图片
}

学习了如何去加载图片,我们就可以向我们的画布中添加图片了么?

没有方法你怎么去添加图片呀,魂淡。

我们还要学习添加图片的方法,这里跟大家说三种方法。

- -
drawImage(图像,float x,float y) 把图像绘制在x,y处。该方法不会对图片做任何缩放处理,绘制处理的图片保持原来的大小
drawImage(图像,浮动x,浮动y,浮动宽度,浮动高度) 把图像绘制在x,y处。该方法会对图片进行缩放,绘制出来的宽度为width,高度为height。
drawImage(图像,整数sx,整数sy,整数sw,整数sh,float dx,float dy,float dw,float dh) 该方法将会从图像上“挖出”一块绘制到画布上。其中sx,sy两个参数控制从原图片上的哪一个位置开始挖去,sw,sh两个参数控制从原图片挖球的宽度和高度; dx,dy两个参数控制把挖取的图片绘制到画布上的哪个位置,而dw,dh则控制对绘制图片进行缩放,绘制出来的宽度是dw,高度dh

我们知道了方法,那就来一起学习下,该如何用代码来实现吧。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div>
        <h2>绘制位图</h2>
        <canvas id="canvas_1" width="1000" height="500" style="box-shadow: 0px 0px 20px black;">
            当前浏览器不支持 canvas
        </canvas>
    </div>
</body>
<script type="text/javascript">
    // 获取 canvas 元素对应的 DOM 对象
    var canvas_1 = document.getElementById("canvas_1");

    // 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
    var ctx = canvas_1.getContext("2d");

    // 创建 image 对象
    var image = new Image();
    // 创建 image 对象装载图片
    image.src = "itwangyang.png";
    // 当图片加载完成后触发该函数
    image.onload = function(){
        // 保持原大小绘制图片
        ctx.drawImage(image, 20, 10);
        // 绘制图片的时候进行缩放
        ctx.drawImage(image, 600, 10, 76, 110);
        // 从原图中挖去一块,放大三倍后绘制在 canvas 上
        var sd = 50;
        var sh = 50;
        /*
        参数说明
            Image image, integer sx, integer sy, integer sw, integer sh, float dx, float dy,float dw, float dh

            sx, sy 两个参数控制从原图片上的哪一个位置开始挖去,
            sw, sh 两个参数控制从原图片挖球的宽度和高度;
            dx, dy 两个参数控制把挖取的图片绘制到画布上的哪个位置,而
            dw, dh 则控制对绘制图片进行缩放,绘制出来的宽度是 dw, 高度 dh
        */
        ctx.drawImage(image, 230, 220,sd, sh, 765, 10, sd * 3, sh * 3);
    }
</script>
</html>

         讲到这里,大家都理解的差不多了吧。如果还不太明白或者还要深入学习的话,欢迎大家在下方留言,我会再抽出时间来,与大家一起分享这其中的奥秘......

猜你喜欢

转载自blog.csdn.net/itwangyang520/article/details/82120457