Canvas(画布)的使用

1、Canvas(画布)的概述

  • Canvas通过Javascript在网页上来绘制2D图形。Canvas是逐像素进行渲染的。开发者可以通过javascript脚本实现任意绘图。可以通过多种方法使用canvas元素绘制路径、矩形、圆形、字符以及添加图像。
  • 在Canvas中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。

2、Canvas(画布)基本使用

<canvas id="tutorial" width="300" height="300"></canvas>

2.1、 <canvas> 元素

  • canvas 是一个二维网格。
    canvas 的左上角坐标为 (0,0)
  • <canvas> 看起来和 <img> 标签一样,只是 <canvas> 只有两个可选的属性 width、heigth 属性,而没有 src、alt 属性。如果不给<canvas>设置 widht、height 属性时,则默认 width为300、height 为 150,单位都是 px。也可以使用 css 属性来设置宽高,但是如宽高属性和初始比例不一致,他会出现扭曲。所以,建议永远不要使用 css 属性来设置<canvas>的宽高
  • ​由于某些较老的浏览器(尤其是 IE9 之前的 IE 浏览器)或者浏览器不支持 HTML 元素<canvas>,在这些浏览器上你应该总是能展示替代内容。支持 <canvas>的浏览器会只渲染 <canvas>标签,而忽略其中的替代内容。
    不支持 <canvas>的浏览器则 会直接渲染替代内容:
<canvas>
    你的浏览器不支持 canvas,请升级你的浏览器。
</canvas>

用 <img> 替换:

<canvas>
    <img src="" alt=""> 
</canvas>
  • 结束标签 </canvas>不可省略。

2.2、渲染上下文(Thre Rending Context)

</canvas>会创建一个固定大小的画布,会公开一个或多个渲染上下文(画笔),使用渲染上下文来绘制和处理要展示的内容。
​ 我们重点研究 2D 渲染上下文。 其他的上下文我们暂不研究,比如, WebGL 使用了基于 OpenGL ES的3D 上下文 (“experimental-webgl”) 。

var canvas = document.getElementById('tutorial');
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');

2.3、检测支持性

var canvas = document.getElementById('tutorial');

if (canvas.getContext){
    
    
  var ctx = canvas.getContext('2d');
  // drawing code here
} else {
    
    
  // canvas-unsupported code here
}
  • 例子:绘制两个长方形
<canvas id="tutorial" width="300" height="300"></canvas>
<script type="text/javascript">
function draw(){
    
    
    var canvas = document.getElementById('tutorial');
    if(!canvas.getContext) return;
    var ctx = canvas.getContext("2d");
    ctx.fillStyle = "rgb(200,0,0)";
      //绘制矩形
    ctx.fillRect (10, 10, 55, 50);
 
    ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
    ctx.fillRect (30, 30, 55, 50);
}
draw();
</script>

3、绘制不同线条颜色的三角形

3.1、绘制三角形

3.1.1、 绘制一个简单的三角形

<script type="text/javascript">
// 获取画布元素
    var example = document.getElementById('example')
    // 获取工具集
    var ctx = example.getContext('2d')
     // 定位一个起始点
    ctx.moveTo(50, 50)
    // 绘制第二个点
    ctx.lineTo(100, 50)
    // 绘制第三个点
    ctx.lineTo(75, 100)
    // 连接起始点/闭合路径
    // ctx.lineTo(50, 50)
    ctx.closePath()

    // 绘制线条
    ctx.stroke()
</script>

3.1.2、 绘制一个不同边框颜色的三角形

  • 绘制的颜色与线条宽度
// 设置线条的宽度,以像素为单位
ctx.linewidth = number
// 设置笔触图形的颜色
ctx.strokeStyle = color
// 设置填充图形的颜色
ctx.fillStyle = color
  • 闭合路径
// 开始一条路径,或重置当前的路径,并切断和上一个图形的路径联系。
ctx.beginPath()
* 闭合路径的优势
可以实现不同大小和颜色图形的单独绘制。
<script type="text/javascript">
        // 获取画布元素
        var example = document.getElementById('example')
        // 获取工具集
        var ctx = example.getContext('2d')

        // 1、绘制第一个点
        // 设置绘制图形的颜色
        ctx.strokeStyle = 'pink'
        // 设置绘制图形的线条宽度
        ctx.lineWidth = 4
        ctx.moveTo(50, 50)
        ctx.lineTo(100, 50)
        // 重置当前路径
        // 绘制线条
        ctx.stroke()
        ctx.beginPath()
        // 2、绘制第二个点
        ctx.strokeStyle = 'orange'
        ctx.lineWidth = 4
        ctx.moveTo(100, 50)
        ctx.lineTo(75, 100)
        ctx.stroke()
        ctx.beginPath()
        // 3、绘制第三个点
        ctx.strokeStyle = 'blue'
        ctx.lineWidth = 4
        ctx.moveTo(75, 100)
        ctx.lineTo(50, 50)
        ctx.stroke()
    // ctx.beginPath()

    </script>

3.2、绘制文字和图片

  • 指定位置
// 在指定位置和宽度内绘制文字
ctx.fillText(text, x, y, maxwidth)
  • 设置字体名称和样式
// 设置字体名称和形状
ctx.font="字体属性" // bold 32px sans-serif
  • 设置字体对齐位置
// 设置文本内容水平对齐方式
ctx.textAlign='水平方位' // center\left\right
// 设置文本内容垂直对齐方式
ctx.textBaseLine='垂直方位值' // top\middle\bottom
  • 绘制内容另存为图片
// 当前绘制内容存为图片
ctx.toDataURL(type, encoderOptions) // image/png图片格式,0到1区间图片质量
<script type="text/javascript">

        // 获取画布元素
        var example = document.getElementById('example')
        // 获取工具集
        var ctx = example.getContext('2d')
        // 设置文字样式(要在绘制之前)
        ctx.font = "bold 20px 黑体"
        
        // 这些代码只是容易区分文字位置
        ctx.strokeStyle = "pink"
        ctx.moveTo(10, 30)
        ctx.lineTo(120, 30)
        ctx.stroke()
        ctx.beginPath()
        ctx.moveTo(30, 10)
        ctx.lineTo(30, 120)
        ctx.stroke()
        ctx.beginPath()
        ctx.moveTo(10, 60)
        ctx.lineTo(120, 60)
        ctx.stroke()
        ctx.beginPath()
        ctx.moveTo(60, 10)
        ctx.lineTo(60, 120)
        ctx.stroke()

        // 水平
        ctx.textAlign = "center"
        // 垂直
        ctx.textBaseline = "middle"
        // 调用工具集中的API绘制文字
        // 第一种(填充式)
        ctx.fillText('文字', 30, 30)
        // 第二种(描边)
        ctx.strokeText('画笔', 60, 60)

        // 将绘制的内容另存为图片(会返回一个base64的字符集)
        var imgUrl = example.toDataURL('image/png', 1)
        console.log(imgUrl);

    </script>

3.3、绘制矩形和圆形及图片

  • 绘制矩形
// 1、先绘制矩形的路径,再描边或填充
ctx.rect(x, y, width, height);
ctx.stroke() 
// 或
ctx.fill()
// 2、直接绘制无/有填充的矩形
ctx.strokeRect(x,y,width,height)
ctx.fillRect(x,y,width,height)
  • 绘制有弧度的圆形
// 在指定位置绘制一个圆形
ctx.arc(x,y,startAngle,endAngle,clockwise) // 以(x, y) 为圆心,以r 为半径,从 startAngle 弧度开始到endAngle弧度结束。anticlosewise 是布尔值,true 表示逆时针,false 表示顺时针(默认是顺时针)。
  • 绘制不同大小的图片
// 在画布上绘制固定坐标的图像
ctx.drawImage(img,x,y);
// 在画布上绘制不仅固定坐标,且规定图像的宽度和高度图像
ctx.drawImage(img,x,y,width,height)
// 在画布上剪切图像,并在画布上绘制被剪切的部分
ctx.drawImage(img,sx,sy,swidth,sheight,x,y,width,height)

4、刮刮卡案例

分为三个步骤:

  1. 将随机的中奖信息绘制到画布中
  2. 使用灰色的矩形覆盖中奖信息
  3. 使用鼠标划擦区域实现刮刮的效果
<script type="text/javascript">

        // 获取画布元素
        var example = document.getElementById('example')
        // 获取工具集
        var ctx = example.getContext('2d')

        // 定义一个中奖信息的数组
        var prices = ['步步高升', '幸福美满', '财运亨通', '财源广进']
        ctx.fillStyle = 'red'
        ctx.font = 'bold 36px 黑体'
        ctx.textAlign = 'center'
        ctx.textBaseline = 'middle'
        // 随机生成一个中奖信息元素,并绘制到画布中间
        ctx.fillText(prices[Math.floor(Math.random() * prices.length)], example.width / 2, example.height / 2)

        // 将绘制的中奖信息另存图片并作为画布元素的背景图片
        var imgUrl = example.toDataURL('image/png', 1)

        example.style.background = 'url(' + imgUrl + ')';

        // 绘制矩形盖住中奖信息
        ctx.clearRect(0, 0, example.width, example.height)
        // 设置矩形的绘制颜色
        ctx.fillStyle = '#ddd'
        // 绘制盖住的区域
        ctx.fillRect(0, 0, example.width, example.height)

        var flag = false
        example.onmousedown = function () {
    
    
            flag = true
            ctx.globalCompositeOperation = 'destination-out';
        }
        example.ontouchstart = function () {
    
    
            flag = true
            ctx.globalCompositeOperation = 'destination-out';
        }
        example.onmousemove = function (e) {
    
    
            if (flag) {
    
    
                console.log(e);
                var x = e.offsetX
                var y = e.offsetY
                ctx.fillStyle = 'pink'
                ctx.fillRect(x, y, 30, 30)
            }
        }
        example.ontouchmove = function (e) {
    
    
            if (flag) {
    
    
                console.log(e);
                var x = e.touches[0].clientX
                var y = e.touches[0].clientY
                ctx.fillStyle = 'pink'
                ctx.fillRect(x, y, 30, 30)
            }
        }
        example.onmouseleave = function () {
    
    
            flag = false
        }
        example.ontouchend = function () {
    
    
            flag = false
        }
    </script>

猜你喜欢

转载自blog.csdn.net/weixin_44767973/article/details/124528944