canvas

1 介绍

canvas是HTML5新增的标签,用于提供画布
它的标准属性有width和height,例如(class, id这些都属于标准属性)
width:表示canvas的宽
height:表示canvas的高
在javascript中,可以通过canvas.getContext(‘2d’)方法获取画布上下文
画布上下文为我们提供了大量的绘图方法
canvas是用于显示图形的,自带了一个坐标系,默认与元素的定位坐标是一致的位于左上角,是一个倒置的数学坐标系(与浏览器一样)

2 canvas API

在canvas中大部分都是在操作路径,所以在操作之前要开启路径
beginPath():用于开启路径
closePath():用于闭合路径,在闭合时候的点和最开始时候的点之间会形成一条线段
fillRect(x, y, w, h):填充矩形
	x:当前坐标系的x点		y:当前坐标系的y点
	w:矩形的宽			  h:矩形的高
strokeRect(x, y, w, h):描边矩形
	x:当前坐标系的x点		y:当前坐标系的y点
	w:矩形的宽			  h:矩形的高
clearRect(x, y, w, h):清除canvas上的一块区域
	x:当前坐标系的x点		y:当前坐标系的y点
	w:要清除的区域的宽	    h:要清除的区域的高
arc(x, y, r, star, end, bool):绘制弧
	x:圆心所在的圆弧的x点	y:圆心所在的圆弧的y点	r:表示圆弧的半径
	star:起始位置		end:终点位置
	bool:是一个布尔值,默认是false表示顺时针绘制,反之逆时针绘制
fill:		用于填充
stroke:		用于描边
fillStyle:	用于改变填充色
strokeStyle:用于改变描边色
fillText:	用于绘制文字
font:		用于改变文字样式
lineWidth:	用于改变线宽
lineTo:		绘制线
moveTo:		移动绘制的起点
  • 绘制线示例
<canvas id="app" class="demo" width="600" height="400"></canvas>

    <script>
        // 获取元素
        var canvas = document.getElementById('app');
        // 获取画布
        var ctx = canvas.getContext('2d');
        // 启动绘制
        ctx.beginPath();
        // 移动绘制起点
        ctx.moveTo(100, 100);
        // 绘制线
        ctx.lineTo(200, 200);
        // 结束绘制
        ctx.closePath();
        // 描边
        ctx.stroke();
    </script>

效果:
在这里插入图片描述

  • 绘制圆
        // // 更改描边颜色
        ctx.strokeStyle = 'red';
        // 更改填充颜色
        ctx.fillStyle = 'green';
        // 绘制圆
        ctx.beginPath();
        // // 顺时针
        // ctx.arc(200, 200, 100, 0, Math.PI);
        // 逆时针
        ctx.arc(200, 200, 100, 0, Math.PI / 2, true);  // 传入true逆时针

效果
第一张为顺时针,第二张为逆时针
顺时针逆时针

  • 绘制矩形
        // // 更改描边颜色
        ctx.strokeStyle = 'red';
        // 更改填充颜色
        ctx.fillStyle = 'green';
        ctx.beginPath();
        // 绘制矩形
        // ctx.strokeRect(100, 100, 200, 200);
        // 填充矩形
        ctx.fillRect(100, 100, 200, 200);
        ctx.closePath();
        ctx.stroke();

效果:
第一张为绘制矩形,第二张为填充矩形
在这里插入图片描述
在这里插入图片描述

清除矩形

        // // 更改描边颜色
        ctx.strokeStyle = 'red';
        // 更改填充颜色
        ctx.fillStyle = 'green';
        ctx.beginPath();
        // 填充矩形
        ctx.fillRect(100, 100, 200, 200);
        ctx.closePath();
        ctx.stroke();
        // // 清除矩形
        ctx.clearRect(200, 200, 100, 100);

效果
在这里插入图片描述

  • 绘制哑铃
<canvas id="app" class="demo" width="600" height="400"></canvas>
    <script>
        // 获取元素
        var canvas = document.getElementById('app');
        // 获取画布
        var ctx = canvas.getContext('2d');
        // 更改填充颜色
        ctx.fillStyle = 'green';
       
        ctx.arc(300, 200, 50, 0, 2 * Math.PI);
        ctx.arc(500, 200, 50, 0, 2 * Math.PI);
        ctx.fill();
        ctx.strokeStyle = 'green';
        ctx.lineWidth = 10;
        // 绘制线
        line(350, 200, 450, 200);
        // 封装方法
        function line(x, y, endX, endY) {
            ctx.beginPath();
            // 移动绘制起点
            ctx.moveTo(x, y);
            // 绘制线
            ctx.lineTo(endX, endY);
            // 结束绘制
            ctx.closePath();
            // 描边
            ctx.stroke();
        }
    </script>

效果
在这里插入图片描述

3 绘制图片

在canvas中绘制图片有三种方式:1 设置背景图片 2插入图片 3drawImage方法绘制
drawImage	该方法用于绘制图片,使用方式有三种:
	第一种:可以以原尺寸来绘制图片  ctx.drawImage(img, x, y)
		img:要绘制的图片
		x:以原尺寸将图片放在canvas中的x点	y:以原尺寸将图片放在canvas中的y点
	第二种:可以缩放图片  ctx.drawImage(img, x, y, w, h)
		img:要绘制的图片
		x:将缩放的图片放在canvas中的x点	y:将缩放的图片放在canvas中的y点
		w:缩放后的图片的宽				  h:缩放后的图片的高
	第三种:截取图片中的某一部分
		ctx.drawImage(img, img_x, img_y, img_w, img_h, canvas_x, canvas_y, canvas_w, canvas_h)
			img:要绘制的图片
			img_x:要截取的图片的x点		img_y:要截取的图片的y点
			img_w:要截取图片的宽		 img_h:要截取的图片的高
			canvas_x:将截取后的图片放在canvas中的x点
			canvas_y:将截取后的图片放在canvas中的y点
			canvas_w:将截取后的图片放在canvas中的宽
			canvas_h:将截取后的图片放在canvas中的高
    <canvas id="app" class="demo" width="600" height="400"></canvas>
    <script>
        // 获取元素
        var canvas = document.getElementById('app');
        // 获取画布
        var ctx = canvas.getContext('2d');
        // 通过js方式加载图片
        var img = new Image();
        // 监听图片加载完成
        img.onload = function() {
            // 可以通过this和img获取图片,this指向img,就是img
            // console.log(this, img, img.width, img.height);
            // 绘制图片
            ctx.drawImage(img, 100, 100);
            // 缩小图片
            // ctx.drawImage(img, 100, 100, 400, 250);
            // 截取图片
            // ctx.drawImage(img, 800, 0, 600, 400, 0, 0, 600, 400);
            // 截取之后也可以缩放
            // ctx.drawImage(img, 800, 0, 600, 400, 0, 0, 300, 200);
        }
        // 加载图片
        img.src = './image/2.PNG';
    </script>

效果:

  1. 绘制图片
    在这里插入图片描述
  2. 缩小图片

在这里插入图片描述

  1. 截取图片
    在这里插入图片描述
  2. 截取之后也可以缩放
    在这里插入图片描述

4 坐标系

canvas中允许我们对坐标系做变换,类似css中transform
	translate(x, y)		移动坐标系
		x:表示水平移动	y:表示垂直移动
	rotate(deg)		旋转坐标系
		deg:表示旋转角度	单位是弧度(pi)
	scale(x, y)		缩放坐标系
		x:水平方向缩放	y:垂直方向缩放
		大于1表示放大,小于1表示缩小
    <canvas id="app" class="demo" width="800" height="400"></canvas>
    <script>
        // 获取元素
        var canvas = document.getElementById('app');
        // 获取画布
        var ctx = canvas.getContext('2d');
        // 封装方法
        function line(x, y, endX, endY) {
            ctx.beginPath();
            // 移动绘制起点
            ctx.moveTo(x, y);
            // 绘制线
            ctx.lineTo(endX, endY);
            // 结束绘制
            ctx.closePath();
            // 描边
            ctx.stroke();
        }
        // 绘制坐标系方法
        function drawXY() {
            // 水平方向
            line(0, 10, 780, 10);
            line(760, 0, 780, 10);
            line(760, 20, 780, 10);
            // 垂直方向
            line(10, 0, 10, 380);
            line(0, 360, 10, 380);
            line(20, 360, 10, 380);
        }
        drawXY();
        // 平移坐标系
        // 平移之前的绘制不受影响,平移之后的绘制受到影响
        ctx.translate(canvas.width / 2, canvas.height / 2);
        // 旋转
        // ctx.rotate(Math.PI / 4);
        // 放缩
        // ctx.scale(0.5, 0.5);
        drawXY();
    </script>

效果:
平移
在这里插入图片描述

旋转
在这里插入图片描述

放缩
在这里插入图片描述

平移放缩
在这里插入图片描述

  • 小案例:旋转坐标系
    <canvas id="app" class="demo" width="800" height="400"></canvas>
    <script>
        // 获取元素
        var canvas = document.getElementById('app');
        // 获取画布
        var ctx = canvas.getContext('2d');
        // 封装方法
        function line(x, y, endX, endY) {
            ctx.beginPath();
            // 移动绘制起点
            ctx.moveTo(x, y);
            // 绘制线
            ctx.lineTo(endX, endY);
            // 结束绘制
            ctx.closePath();
            // 描边
            ctx.stroke();
        }
        // 绘制坐标系方法
        function drawXY() {
            // 水平方向
            line(0, 10, 780, 10);
            line(760, 0, 780, 10);
            line(760, 20, 780, 10);
            // 垂直方向
            line(10, 0, 10, 380);
            line(0, 360, 10, 380);
            line(20, 360, 10, 380);
        }
        // 在中间旋转
        ctx.translate(canvas.width / 2, canvas.height / 2);
        // 旋转的速度
        var speed = Math.PI / 180;
        // 起始度数
        var deg = 0;
        // 每隔1s绘制一次
        setInterval(function() {
            // 在下一次的绘制的时候清空画布
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            deg += speed;
            ctx.rotate(deg);
            drawXY();
        }, 100);
    </script>

效果:坐标系会一直旋转,速度不断加快
在这里插入图片描述

5 状态的保存与恢复

在canvas中很多时候要用到之前的状态,所以提供了相应的API用于保存canvas上的状态
	save	存储状态
	restore	恢复状态
save方法可以使用多次,每save一次就好比装了一颗子弹
每restore一次,就好比扣了一次扳机
    <canvas id="app" class="demo" width="800" height="600"></canvas>
    <script>
        // 获取元素
        var canvas = document.getElementById('app');
        // 获取画布
        var ctx = canvas.getContext('2d');
        ctx.fillStyle = 'green';
        // 绘制矩形
        ctx.fillRect(100, 100, 50, 50);
        // 存储状态
        ctx.save();

        // 绘制红色盒子
        ctx.fillStyle = 'red';
        ctx.fillRect(200, 200, 50, 50);
        ctx.save();

        // 恢复状态,此时恢复上一次保存的红色盒子
        ctx.restore();
        ctx.fillRect(300, 300, 50, 50);

        ctx.restore(); // 此时恢复上上一次保存的绿色盒子
        ctx.fillRect(400, 400, 50, 50);

    </script>

效果
在这里插入图片描述

6 融合

融合,是在canvas中新图形和原有图形之间的覆盖方式
	默认情况下,新图形覆盖原有图片
	通过ctx.globalCompositeOperation属性设置
		source-over		默认,在目标图像上显示源图像
		source-atop		在目标图像顶部显示源图像,源图像位于目标图像之外的部分是不可见的
		source-in		在目标图像中显示源图像,只有目标图像内的源图像部分会显示,目标图像是透明的
		source-out		在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图像是透明的
		destination-over在源图像上方显示目标图像
		destination-atop在源图像顶部显示目标图像,源图像之外的目标图像部分不会被显示
		destination-in	在源图像中显示目标图像,只有源图像内的目标图像部分会被显示,源图像是透明的
		destination-out	在源图像外显示目标图像,只有源图像外的目标图像部分会被显示,源图像是透明的
		lighter			显示源图像+目标图像
		copy			显示源图像,忽略目标图像
		xor				使用异或操作对源图像与目标图像进行组合
<canvas width="600" height="600" style="margin: 10px auto; display: block; border: 1px solid pink;"></canvas>
    <script>
        var canvas = document.getElementsByTagName('canvas')[0];
        var ctx = canvas.getContext('2d');
        ctx.fillStyle = 'red';
        fillArc(200, 200, 100);

        // 修改覆盖关系
        // 重叠的绿色显示
        // ctx.globalCompositeOperation = 'source-atop';
        // 两个圆重叠的部分显示
        // ctx.globalCompositeOperation = 'source-in';
        // 显示绿色没有重叠的部分
        // ctx.globalCompositeOperation = 'source-out';
        // 优先显示底部红色部分
        // ctx.globalCompositeOperation = 'destination-over';
        // 显示红色与绿色重叠部分
        // ctx.globalCompositeOperation = 'destination-atop';
        // 重叠部分显示,显示红色
        // ctx.globalCompositeOperation = 'destination-in';
        // 显示红色未重叠部分
        // ctx.globalCompositeOperation = 'destination-out';
        // 显示源图像+目标图像
        // ctx.globalCompositeOperation = 'lighter';
        // 显示源图像,忽略目标图像
        // ctx.globalCompositeOperation = 'cpoy';
        // 使用异或操作对源图像与目标图像进行组合
        ctx.globalCompositeOperation = 'xor';

        ctx.fillStyle = 'green';
        fillArc(300, 200, 100);
        // 绘制两个圆
        function fillArc(x, y, r) {
            ctx.beginPath();
            ctx.arc(x, y, r, 0, Math.PI * 2);
            ctx.closePath();
            ctx.fill();
        }
    </script>

在这里插入图片描述

7 像素信息

getImageData	该方法用于获取canvas上的像素信息
	返回的是一个像素信息对象,该对象中有三个属性
		第一个是一个data是一个数组、
		第二个是height表示获取图像的高度
		第三个是width表示获取图像的宽度
putImageData	该方法用于将修正之后的像素信息对象重新放回canvas,三个参数分别是:
	第一个参数:像素数据
	第二个参数:绘制横坐标
	第三个参数:绘制纵坐标
    <canvas id="app"></canvas>
    <script>
        var img = new Image();
        var canvas = document.getElementById('app');
        var ctx = canvas.getContext('2d');
        img.onload = function() {
            // 修改画布大小
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img, 0, 0, img.width / 2, img.height / 2);
            // 获取像素数据
            var result = ctx.getImageData(100, 100, 400, 400);
            // console.log(result);
            // 将获取到的像素信息绘制到右边
            ctx.putImageData(result, img.width / 2, 0);
        }
        img.src = './image/2.PNG';
    </script>

效果
在这里插入图片描述

  • 实现图片特效
<body>
    <button id="red">去除红色</button>
    <button id="green">去除绿色</button>
    <button id="blue">去除蓝色</button>
    <button id="gray">灰色</button>
    <canvas id="app" style="border: 2px solid green;"></canvas>
    <script>
        var img = new Image();
        var canvas = document.getElementById('app');
        var ctx = canvas.getContext('2d');
        var width, height;
        img.onload = function() {
            // 修改画布大小
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img, 0, 0, img.width / 2, img.height / 2);
            width = img.width / 2;
            height = img.height / 2;
            // 获取像素数据
            // var result = ctx.getImageData(100, 100, 400, 400);
            // // console.log(result);
            // // 将获取到的像素信息绘制到右边
            // ctx.putImageData(result, img.width / 2, 0);
        }
        img.src = './image/2.PNG';

        // 绑定事件
        // 去除红色
        red.onclick = function() {
            var result = ctx.getImageData(0, 0, width, height);
            for (var i = 0, len = result.data.length; i < len; i +=4) {
                // 每个像素点包括四个信息,红,绿,蓝,透明度
                // 删除红色通道
                result.data[i] = 0;
            }
            ctx.putImageData(result, width , 0);
        }
        // 去除绿色
        green.onclick = function() {
            var result = ctx.getImageData(0, 0, width, height);
            for (var i = 0, len = result.data.length; i < len; i +=4) {
                // 每个像素点包括四个信息,红,绿,蓝,透明度
                // 删除绿色通道
                result.data[i + 1] = 0;
            }
            ctx.putImageData(result, width , 0);
        }
        // 去除蓝色
        blue.onclick = function() {
            var result = ctx.getImageData(0, 0, width, height);
            for (var i = 0, len = result.data.length; i < len; i +=4) {
                // 每个像素点包括四个信息,红,绿,蓝,透明度
                // 删除蓝色通道
                result.data[i + 2] = 0;
            }
            ctx.putImageData(result, width , 0);
        }
        // 灰色
        gray.onclick = function() {
            var result = ctx.getImageData(0, 0, width, height);
            var arr = result.data;
            for (var i = 0, len = arr.length; i < len; i +=4) {
                // 每个像素点包括四个信息,红,绿,蓝,透明度
                // // 让三个通道取红色值
                // arr[i + 1] = arr[i];
                // arr[i + 2] = arr[i];

                // 取三个通道的平均值
                var arg = (arr[i] + arr[i + 1] + arr[i + 2]) / 3;
                arr[i] = arg;
                arr[i + 1] = arg;
                arr[i + 2] = arg;
            }
            ctx.putImageData(result, width , 0);
        }
    </script>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值