3.04.07画布标签
1.画布标签canvas
- 这个元素用于绘制图形图像,需要结合JavaScript才能实现绘图功能
- 有些浏览器不支持该标签
- 应用场景:可视化数据图表、广告特效、js小游戏
- 默认尺寸为:300*150,客户端可以另存为,保存下来为图片格式
- 若要查看页面效果可以通过css设置背景色查看效果,但保存下来的图片不会带有背景色
- canvas.width与canvas.height设置的尺寸就是下载下来图片的尺寸,若不设置canvas.width与canvas.height,下载下来默认尺寸为:300*150,canvas标签css中的width与height只在查看页面时生效,所以建议使用canvas.width与canvas.height设置尺寸而不使用css设置
- 画布标签canvas对象身上有一些api
1. 画直线所需api
- canvas.width 设置画布的宽度
- canvas.height 设置画布的高度
- var pen=canvas.getContext(“2d”); 返回一个绘图上下文对象(简称画笔) "2d"这个参数是固定的
- pen.stroke() 划线
- pen.strokeStyle 线的颜色
- pen.moveTo(50,100); 将一个新的子路径的起始点移动到(x,y)坐标。
- pen.lineTo(300,100); 使用直线连接子路径的最后的点到x,y坐标。若有多条子路径的情况下,多条路径的最后一点都连到x,y坐标。一般不使用closePath()就会产生多条子路径。
- pen.lineWidth 线的粗细
- 用法:
<!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>Document</title>
<style>
canvas {
background-color: #ccc;
}
</style>
</head>
<body>
<canvas id="canvas">
如果浏览器不支持画布标签,那么请换一个浏览器查看效果!
</canvas>
<!--
主流浏览器支持canvas, IE9+ 谷歌 ,火狐,欧朋 .... 以及手机浏览器
这是画布标签:默认300 * 150 尺寸,行内块特性, 鼠标在画布上右击,直接保存在图片 -->
<!-- 以后想查看canvas效果,
不是通过css设置样式,
如果非要查看页面效果,就可以设置背景色辅助查看效果,保存图片,
这个css背景色不会出现
需要采用javascript才能控制画布的尺寸,颜色,图形,图像.. -->
<script>
// 编码:
// 获取画布标签
var canvas = document.getElementById("canvas");
// 设置画布的尺寸
canvas.width = 500;
canvas.height = 600;
// 获取绘图的上下文对象(画笔)
var pen = canvas.getContext("2d");
// console.log(pen); //打印一个CanvasRenderingContext2D对象
// 绘制一根线
// 设置线的颜色
pen.strokeStyle = "red";
// 设置线的大小
pen.lineWidth = 5;
// 绘制起点(x,y)
pen.moveTo(50,100);
// 绘制下一个点
pen.lineTo(300,100);
// 绘制线 (描边) 给边线上颜色
pen.stroke();
//canvas.style.width = "900px";
</script>
<script>
//绘制一个三角形
// 获取绘图的上下文对象(画笔)
var pen = canvas.getContext("2d");
console.log(pen);
// 绘制一根线
// 设置线的颜色
pen.strokeStyle = "red";
// 设置线的大小
pen.lineWidth = 5;
// 绘制起点(x,y)
pen.moveTo(50,100);
// 绘制下一个点
pen.lineTo(300,200);
pen.lineTo(100,200);
pen.lineTo(50,100);
pen.stroke();
</script>
</body>
</html>
- var pen=canvas.getContext(“2d”)获取的个绘图上下文对象是唯一的
<canvas id="canvas">
如果浏览器不支持画布标签,那么请换一个浏览器查看效果!
</canvas>
<script>
var pen = canvas.getContext("2d");
console.log(pen);
var pen2 = canvas.getContext("2d");
console.log(pen2);
console.log(pen===pen2); //true
</script>
2. 画图形所需的api
- pen.beginPath() 丢弃任何当前定义的路径并且开始一条新的路径。它把当前的点设置为 (0,0) 清空子路径列表开始一个新的路径。当你想创建一个新的路径时,调用此方法。
- pen.fillStyle 设置填充的颜色
- pen.fill() 根据当前的填充样式,填充当前或已存在的路径的方法。采取非零环绕或者奇偶环绕规则。
- pen.closePath() 使笔点返回到当前子路径的起始点。它尝试从当前点到起始点绘制一条直线。如果图形已经是封闭的或者只有一个点,那么此方法不会做任何操作。
- 用法:
<canvas id="canvas"> </canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
ctx.lineTo(200,20);
ctx.lineTo(120,120);
ctx.closePath(); // draws last line of the triangle
//此处ctx.closePath(); 等价于 ctx.lineTo(20,20);
ctx.fillStyle="red";
ctx.fill();
ctx.stroke();
</script>
- 绘制矩形
-
pen.clearRect()
- 这个方法通过把像素设置为透明以达到擦除一个矩形区域的目的。
- 语法:void ctx.clearRect(x, y, width, height);
- clearRect() 方法在一个矩形区域内设置所有像素都是透明的(rgba(0,0,0,0))。这个矩形范围的左上角在 (x, y),宽度和高度分别由 width 和height确定。
-
pen.fillRect()
- 语法:void ctx.fillRect(x, y, width, height);
- fillRect()方法绘制一个填充了内容的矩形,这个矩形的开始点(左上点)在(x, y) ,它的宽度和高度分别由width 和 height 确定,填充样式由当前的fillStyle 决定。
- 语法:void ctx.fillRect(x, y, width, height);
-
pen.strokeRect()
- 语法:void ctx.strokeRect(x, y, width, height);
- strokeRect()方法绘制一个描边矩形,其起点为(x, y) ,其大小由宽度和高度指定。
- 语法:void ctx.strokeRect(x, y, width, height);
-
- 用法:
<canvas id="canvas">
如果浏览器不支持画布标签,那么请换一个浏览器查看效果!
</canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width=450;
canvas.height=450;
//绘制描边矩形
ctx.strokeStyle = 'green';
ctx.strokeRect(20, 10, 160, 100);
//绘制填充矩形
ctx.fillStyle = 'red';
ctx.fillRect(20, 200, 150, 100);
// 绘制黄色背景
ctx.beginPath();
ctx.fillStyle = '#ff6';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制蓝色三角形
ctx.beginPath();
ctx.fillStyle = 'blue';
ctx.moveTo(20, 20);
ctx.lineTo(180, 20);
ctx.lineTo(130, 130);
ctx.closePath();
ctx.fill();
// 清除一部分画布
ctx.clearRect(10, 10, 120, 100);
</script>
3. 画弧线所需api
- pen…arc()
- 绘制圆弧路径的方法。 圆弧路径的圆心在 (x, y) 位置,半径为 r ,根据anticlockwise (默认为顺时针)指定的方向从 startAngle 开始绘制,到 endAngle 结束。
- 语法:void ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
- x 圆弧中心(圆心)的 x 轴坐标。
- y 圆弧中心(圆心)的 y 轴坐标。
- radius 圆弧的半径。
- startAngle 圆弧的起始点, x轴方向开始计算,单位以弧度表示。
- endAngle 圆弧的终点, 单位以弧度表示。
- anticlockwise 可选参数,可选的Boolean值 ,如果为 true,逆时针绘制圆弧,反之,顺时针绘制。
- 用法:
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(75, 75, 50, 45 * Math.PI/180, 180 * Math.PI/180,true);
ctx.stroke();
//弧度公式:弧度=角度 * Math.PI / 180
//画个圆
ctx.beginPath();
ctx.arc(75, 75, 25, 0, 360 * Math.PI/180);
ctx.stroke();
ctx.fillStyle="blue";
ctx.fill();
</script>
4. 画图像所需api
- pen.drawImage
- 方法提供了多种方式在Canvas上绘制图像。
- 语法:
- void ctx.drawImage(image, dx, dy);
- void ctx.drawImage(image, dx, dy, dWidth, dHeight);
- void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
- 参数:
- image:绘制到上下文的元素。允许任何的 canvas 图像源(CanvasImageSource),例如:CSSImageValue (en-US),HTMLImageElement,SVGImageElement (en-US),HTMLVideoElement,HTMLCanvasElement,ImageBitmap 或者OffscreenCanvas。
- sx可选:需要绘制到目标上下文中的,image的矩形(裁剪)选择框的左上角 X 轴坐标。
- sy可选:需要绘制到目标上下文中的,image的矩形(裁剪)选择框的左上角 Y 轴坐标。
- sWidth可选:需要绘制到目标上下文中的,image的矩形(裁剪)选择框的宽度。如果不说明,整个矩形(裁剪)从坐标的sx和sy开始,到image的右下角结束。
- sHeight可选:需要绘制到目标上下文中的,image的矩形(裁剪)选择框的高度。
- dx:image的左上角在目标canvas上 X 轴坐标。
- dy:image的左上角在目标canvas上 Y 轴坐标。
- dWidth可选:image在目标canvas上绘制的宽度。 允许对绘制的image进行缩放。 如果不说明, 在绘制时image宽度不会缩放。
- dHeight可选:image在目标canvas上绘制的高度。 允许对绘制的image进行缩放。 如果不说明, 在绘制时image高度不会缩放。
- 用法:
<canvas class="canvas">不支持画布,请换个浏览器!</canvas>
<script>
// 编码:
// 1. 获取相关的元素
var canvas = document.querySelector(".canvas");
// 获取浏览器可视区的尺寸
// var w = window.innerWidth;
// var h = window.innerHeight;
// 获取设备屏幕尺寸
var w = screen.availWidth;
var h = screen.availHeight;
// 2. 设置画布大小(黑板)
canvas.width = w;
canvas.height = h;
// 3. 获取画笔(画布上下文对象)
var pen = canvas.getContext("2d");
// 4、准备素材(资源)
var img = new Image();// 创建图片 createElement("img")
img.src = "./img/demo1.jpg";//设置图片路径
//代码一、
//加载图片
// img.onload = function(){
// // 设置图像
// pen.drawImage(
// img, // 图片资源
// 0, // 放在画布的x坐标
// 0 // 放在画布的y坐标
// )
// }
// 代码二、
// 加载图片
img.onload = function(){
// console.log({
// w: img.width,
// h: img.height
// });
// 设置图像
pen.drawImage(
img, // 图片资源
100, // 放在画布的x坐标
200, // 放在画布的y坐标
img.width * (2 / 6), // 设置图像的宽度
img.height * (2 / 6) // 设置图像的宽度
)
}
// 代码三、
// 加载图片
// pen.drawImage(
// img, // 图片资源
// sx, // 图片上的x坐标位置(裁剪的x坐标)
// sy, // 图片上的y坐标位置(裁剪的y坐标)
// sw, // 在图片上的宽度(裁剪的宽度)
// sh, // 在图片上的高度(裁剪的高度)
// x, // 画布上的x坐标位置
// y, // 画布上的y坐标位置
// w, // 在画布上显示出来的宽度
// h // 在画布上显示出来的高度
// )
// 九个参数 1.图片资源 2. 在图片的坐标和尺寸 3. 在画布的坐标和尺寸
/* img.onload = function(){
pen.drawImage(
img,
50,
150,
450,
300,
100,
100,
450 * (1 / 2),
300 * (1 / 2)
)
} */
</script>
5. 绘制文本需要的api
- pen.font 描述绘制文字时,当前字体样式的属性。 使用和 CSS font 规范相同的字符串值。
- 语法:ctx.font = value; ctx.font = “48px 微软雅黑”;
- 用法:
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "48px 微软雅黑";
ctx.strokeText("Hello world", 50, 100);
</script>
- pen.textAlign描述绘制文本时,文本的对齐方式的属性。注意,该对齐是基于CanvasRenderingContext2D.fillText方法的x的值。所以如果textAlign=“center”,那么该文本将画在 x-50%*width。
- 语法:ctx.textAlign = “left” || “right” || “center” || “start” || “end”;
- 用法:
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "48px serif";
ctx.textAlign = "left";
ctx.strokeText("Hello world", 0, 100);
</script>
- pen.textBaseline描述绘制文本时,当前文本基线的属性。
- 语法:ctx.textBaseline = “top” || “hanging” || “middle” || “alphabetic” || “ideographic” || “bottom”;
- 默认值为:alphabetic 文本基线是标准的字母基线。
- 用法:
<canvas id="canvas" width="550" height="500"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const baselines = ['top', 'hanging', 'middle', 'alphabetic', 'ideographic', 'bottom'];
ctx.font = '36px serif';
ctx.strokeStyle = 'red';
baselines.forEach(function (baseline, index) {
ctx.textBaseline = baseline;
let y = 75 + index * 75;
ctx.beginPath();
ctx.moveTo(0, y + 0.5);
ctx.lineTo(550, y + 0.5);
ctx.stroke();
ctx.fillText('Abcdefghijklmnop (' + baseline + ')', 0, y);
});
</script>
- pen.fillText() 是 Canvas 2D API 在 (x, y)位置填充文本的方法。如果选项的第四个参数提供了最大宽度,文本会进行缩放以适应最大宽度。
- 语法:void ctx.fillText(text, x, y, [maxWidth]);
- 参数:
- text 使用当前的 font, textAlign, textBaseline 和 direction 值对文本进行渲染。
- x 文本起点的 x 轴坐标。
- y 文本起点的 y 轴坐标。
- maxWidth 可选。绘制的最大宽度。如果指定了值,并且经过计算字符串的值比最大宽度还要宽,字体为了适应会水平缩放(如果通过水平缩放当前字体,可以进行有效的或者合理可读的处理)或者使用小号的字体。
- 用法:
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "48px serif";
ctx.fillText("Hello world", 50, 100);
<script>
- pen.strokeText() 在给定的 (x, y) 位置绘制文本的方法。如果提供了表示最大值的第四个参数,文本将会缩放适应宽度。
- 与pen.fillText()的区别在于:fillText()是实心文字,strokeText()是空心文字
- 语法:void ctx.strokeText(text, x, y [, maxWidth]);
- text 使用当前 font,textAlign,textBaseline和direction 的值对文本进行渲染。
- x 文本起始点的 x 轴坐标。
- y 文本起始点的 y 轴坐标。
- maxWidth 可选。需要绘制的最大宽度。如果指定了值,并且经过计算字符串的宽度比最大宽度还要宽,字体为了适应会使用一个水平缩小的字体(如果通过水平缩放当前的字体,可以进行有效的或者合理可读的处理)或者小号的字体。
- 用法:
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "48px serif";
ctx.strokeText("Hello world", 50, 100);
<script>
2.requsetAnimationFram与cancelAnimationFram
- 类似于定时函数与延迟函数,一秒钟执行60次形参里面的函数
- 因为动画1秒针60帧最好,所以产生了该函数
- requsetAnimationFram 设置1秒钟执行60次
- cancelAnimationFram 取消已设置的requsetAnimationFram
- 用法:
<!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>Document</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<div class="box"></div>
<button class="btn1">点击执行动画</button>
<button class="btn2">点击执行动画</button>
<script>
// 编码:
// 获取相关的元素
var box = document.querySelector(".box")
var btn1 = document.querySelector(".btn1")
var btn2 = document.querySelector(".btn2")
var dd = null;
// 编写函数
var move = function(){
// 设置盒子的宽度
box.style.width = box.offsetWidth + 10 +"px";
// 满足这个条件执行
if(box.offsetWidth < 1000){
// 每1秒执行60次move函数
dd = window.requestAnimationFrame(move);
// console.log(dd);
}
}
// 事件绑定
// btn.onclick = function(){move()};
// 执行动画
btn1.onclick = move;
// 取消动画
btn2.onclick = function(){
// console.log('test');
// 取消执行动画
window.cancelAnimationFrame(dd);
}
</script>
</body>
</html>