- 前端 | ( 十)HTML5简介及相关新增属性
- 尚硅谷前端HTML5教程(html5入门经典)
是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,创建动画。
最早由Apple引入WebKit。
标签来定义一个canvas元素
标签时,建议要成对出现,不要使用闭合的形式。width: 300px
,height:150px
很容易定义一些替代内容。由于某些较老的浏览器(尤其是IE9之前的IE浏览器)不支持HTML元素"canvas",但在这些浏览器上你应该要给用户展示些替代内容。
标签中提供替换内容就可以。
的浏览器将会忽略在容器中包含的内容,并且只是正常渲染canvas。不支持
的浏览器会显示代替内容。
<canvas id="test" width="300" height="300">
<span>您的浏览器不支持画布元素 请您换成可爱的谷歌span>
canvas>
看起来和 元素很相像,唯一的不同就是它并没有 src 和 alt 属性。
标签只有两个属性—— width和height。这些都是可选的。
元素只是创造了一个固定大小的画布,要想在它上面去绘制内容,我们需要找到它的渲染上下文。
元素有一个叫做 getContext()
的方法,这个方法是用来获得渲染上下文和它的绘画功能。getContext()
只有一个参数:上下文的格式。var canvas = document.getElementById('box');
var ctx = canvas.getContext('2d');
var canvas = document.getElementById('tutorial');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
}
fillRect(x, y, width, height)
strokeRect(x, y, width, height)
clearRect(x, y, width, height)
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
body{
background: pink;
}
#test{
background: gray;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
style>
head>
<body>
<canvas id="test" width="300" height="300">
<span>您的浏览器不支持画布元素 请您换成可爱的谷歌span>
canvas>
body>
<script type="text/javascript">
window.onload=function(){
//拿到画布
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
//注意不加单位,填充的矩形
ctx.fillRect(0,0,100,100)
//带边框的矩形
ctx.strokeRect(100.5,100.5,100,100)
// 清除指定矩形区域,让清除部分完全透明
// ctx.clearRect(0,0,100,100)
}
}
script>
html>
context.strokeRect(10,10,50,50)
:边框会渲染在10.5 和 9.5之间,浏览器是不会让一个像素只用自己的一半的,相当于边框会渲染在9到11之间。context.strokeRect(10.5,10.5,50,50)
:边框会渲染在10到11之间。fillStyle
:设置图形的填充颜色。strokeStyle
:设置图形轮廓的颜色。
lineWidth
:这个属性设置当前绘线的粗细。属性值必须为正数。描述线段宽度的数字。 0、 负数、 Infinity 和 NaN 会被忽略。默认值是1.0。设定线条与线条间接合处的样式(默认是 miter)
round
: 圆角bevel
: 斜角miter
: 直角DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
body{
background: pink;
}
#test{
background: gray;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
style>
head>
<body>
<canvas id="test" width="300" height="300">
<span>您的浏览器不支持画布元素 请您换成可爱的谷歌span>
canvas>
body>
<script type="text/javascript">
window.onload=function(){
//拿到画布
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
// 设置图形的填充颜色
ctx.fillStyle="deeppink";
// 设置图形轮廓的颜色
ctx.strokeStyle="pink";
// 当前绘线的粗细
ctx.lineWidth=25;
// 设定线条与线条间接合处的样式
ctx.lineJoin="round";
ctx.strokeRect(100,100,100,100)
ctx.fillRect(0,0,100,100)
//ctx.clearRect(100,100,100,100)
}
}
script>
html>
rect
画矩形var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.rect(50,50,100,100);
ctx.fillStyle="skyblue";
ctx.strokeStyle="black";
ctx.fill();
ctx.stroke();
}
图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。
首先,创建路径起始点。
beginPath()
:新建一条路径,生成之后,图形绘制命令被指向到路径上准备生成路径。
使用画图命令去画出路径。
moveTo(x, y)
lineTo(x, y)
之后你把路径封闭。
closePath()
stroke()
:通过线条来绘制图形轮廓。不会自动调用closePath()。fill()
:通过填充路径的内容区域生成实心的图形。自动调用closePath()。一旦路径生成,你就能通过描边或填充路径区域来渲染图形。
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
body{
background: pink;
}
#test{
background: gray;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
style>
head>
<body>
<canvas id="test" width="300" height="300">
<span>您的浏览器不支持画布元素 请您换成可爱的谷歌span>
canvas>
body>
<script type="text/javascript">
window.onload=function(){
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.strokeStyle="deeppink";
ctx.lineWidth=10;
ctx.moveTo(100,100);
ctx.lineTo(100,200);
ctx.lineTo(200,200);
ctx.closePath();
ctx.stroke();
//fill方法会自动合并路径
ctx.fill();
}
}
script>
html>
butt
:线段末端以方形结束。round
:线段末端以圆形结束square
:线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.strokeStyle="pink";
ctx.lineWidth=10;
ctx.lineCap="round";
ctx.moveTo(100,100);
ctx.lineTo(100,200);
ctx.stroke();
}
restore() 是 Canvas 2D API 通过在绘图状态栈中弹出顶端的状态,将 canvas 恢复到最近的保存状态的方法。
如果没有保存状态,此方法不做任何改变。
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.save();
ctx.fillStyle="pink";
ctx.save();
// 没保存的不入栈
ctx.fillStyle="deeppink";
ctx.fillStyle="blue";
ctx.save();
ctx.fillStyle="red";
ctx.save();
ctx.fillStyle="green";
ctx.save();
ctx.beginPath();
// 弹出,restore四个是pink,三个是blue,二个是red,一个是green
ctx.restore();
ctx.restore();
ctx.restore();
ctx.restore();
ctx.fillRect(50,50,100,100);
}
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
body{
background: #dbd0ff;
}
#test{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
background:white;
}
style>
head>
<body>
<canvas id="test" width="500" height="500">canvas>
body>
<script type="text/javascript">
window.onload=function(){
var canvas =document.getElementById("test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
}
// 在鼠标按下时触发事件
canvas.onmousedown=function(ev){
// 获取事件对象
ev = ev || window.event;
if(canvas.setCapture){
// 设置鼠标捕获,确保鼠标事件在元素上持续触发
canvas.setCapture();
}
ctx.beginPath();
// ev.clientX表示鼠标相对于文档可视区域的水平坐标,canvas.offsetLeft表示画布相对于文档可视区域的水平偏移量
ctx.moveTo(ev.clientX -canvas.offsetLeft,ev.clientY -canvas.offsetTop);
document.onmousemove=function(ev){
// 在整个文档区域内移动鼠标时触发事件
// 保存画布当前的状态
ctx.save();
ctx.strokeStyle="black";
ev = ev || event;
// 创建从当前点到指定点的线段,即绘制直线
ctx.lineTo(ev.clientX -canvas.offsetLeft,ev.clientY -canvas.offsetTop);
// 绘制已定义的路径
ctx.stroke();
ctx.restore();
}
// 释放鼠标捕获
document.onmouseup=function(){
document.onmousemove=document.onmouseup=null;
if(document.releaseCapture){
document.releaseCapture();
}
}
return false;
}
}
script>
html>
radians=(Math.PI/180)*degrees
。arc(x, y, radius, startAngle, endAngle, anticlockwise)
ture
:逆时针,false
:顺时针var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(100,100);
ctx.arc(100,100,50,0,90*Math.PI/180,true);
ctx.closePath();
ctx.stroke();
}
arcTo(x1, y1, x2, y2, radius)
,根据给定的控制点和半径画一段圆弧。
相当于指定了起点和终点的切线(就是下边示例中,画出的直线就是在画弧线时的切线)
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.strokeStyle="purple";
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(300,0);
ctx.lineTo(200,200);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(50,50)
ctx.arcTo(300,0,200,200,50);
ctx.stroke();
}
quadraticCurveTo(cp1x, cp1y, x, y)
var ctx = canvas.getContext("2d");
ctx.strokeStyle="purple";
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(300,0);
ctx.lineTo(200,200);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(50,50)
ctx.quadraticCurveTo(300,0,200,200);
ctx.stroke();
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(50,50);
ctx.lineTo(300,0);
ctx.lineTo(0,300);
ctx.lineTo(300,300);
ctx.stroke();
ctx.strokeStyle="purple";
ctx.beginPath();
ctx.moveTo(50,50)
ctx.bezierCurveTo(300,0,0,300,300,300);
ctx.stroke();
}
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.translate(100,100)
ctx.beginPath();
ctx.fillStyle="skyblue";
ctx.fillRect(0,0,100,100);
}
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.translate(70,70)
ctx.rotate(22.1*Math.PI/180)
ctx.rotate(22.9*Math.PI/180)
ctx.beginPath();
ctx.fillStyle="skyblue";
ctx.fillRect(50,50,100,100);
}
scale 方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。
值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。
缩放一般我们用它来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大。
在canvas中scale是累积的。
var ctx = canvas.getContext("2d");
ctx.fillStyle="skyblue";
ctx.beginPath();
ctx.fillRect(50,50,100,100);
ctx.beginPath();
ctx.fillStyle="green";
ctx.scale(0.5,0.5)
ctx.fillRect(50,50,100,100);
ctx.beginPath();
ctx.fillStyle="yellow";
// 因为累加,相当于两倍
ctx.scale(4,4)
ctx.fillRect(50,50,100,100);
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
background-color: #dbdbff;
overflow: hidden;
}
#test{
background: rgba(143, 143, 253, 0.785);
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
style>
head>
<body>
<canvas id="test" width="300" height="300">
<span>您的浏览器不支持画布元素 请您换成可爱的谷歌span>
canvas>
body>
<script type="text/javascript">
window.onload=function(){
var angle =0;//角度
var scale = 0;//比例
var angleScale = 0;//状态
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.fillStyle="rgba(10, 10, 79, 0.785)";
ctx.save();
// 将坐标原点平移到150,150
ctx.translate(150,150);
ctx.beginPath();
ctx.fillRect(-50,-50,100,100);
ctx.restore();
// 设定定时器函数,每隔10毫秒执行一次
setInterval(function(){
// 每次执行时,将旋转角度标记加1
angle++;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.save();
ctx.translate(150,150);
// 旋转
ctx.rotate(angle*Math.PI/180);
// 0~100之间缩放
if(scale==100){
angleScale=-1;
}else if(scale==0){
angleScale=1;
}
scale+=angleScale;
// 缩放
ctx.scale(scale/50,scale/50);
ctx.beginPath();
ctx.fillRect(-50,-50,100,100);
ctx.restore();
},10)
}
}
script>
html>
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
background: rgb(197, 197, 255);
}
#clock{
background: rgb(167, 208, 255);
position: absolute;
left: 50%;
top: 50%;
transform: translate3d(-50%,-50%,0);
}
style>
head>
<body>
<canvas id="clock" width="400" height="400">canvas>
body>
<script type="text/javascript">
window.onload=function(){
var clock = document.querySelector("#clock");
if(clock.getContext){
var ctx = clock.getContext("2d");
// 定时器函数,每隔1秒执行一次
setInterval(function(){
// 清除整个画布的内容
ctx.clearRect(0,0,clock.width,clock.height);
// 调用move函数
move();
},1000);
move();
// move函数,用于绘制时钟
function move(){
ctx.save();
ctx.lineWidth = 8;
ctx.strokeStyle = "black";
// 设置线条末端的形状为圆形
ctx.lineCap = "round";
// 将坐标原点平移到(200, 200)的位置
ctx.translate(200,200);
// 对画布进行旋转操作,旋转的角度为-90°,即将角度转换为弧度单位,并逆时针旋转
ctx.rotate(-90*Math.PI/180);
ctx.beginPath();
// 外层空心圆盘
ctx.save();
ctx.strokeStyle="#325FA2";
ctx.lineWidth = 14;
ctx.beginPath();
// 绘制一个从0°到360°的弧线,即画一个圆
ctx.arc(0,0,140,0,360*Math.PI/180);
ctx.stroke(); // 绘制已定义的路径
ctx.restore(); // 恢复之前保存的画布状态
// 时针刻度
ctx.save();
// 循环绘制12个时针刻度
for(var i=0;i<12;i++){
// 逆时针旋转30°,即将角度转换为弧度单位
ctx.rotate(30*Math.PI/180);
ctx.beginPath();
ctx.moveTo(100,0)
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.restore();
// 分针刻度
ctx.save();
ctx.lineWidth=4;
// 循环绘制60个分针刻度
for(var i=0;i<60;i++){
// 逆时针旋转6°,即将角度转换为弧度单位
ctx.rotate(6*Math.PI/180);
// 如果不是整点刻度,则绘制
if((i+1)%5!=0){
ctx.beginPath();
ctx.moveTo(117,0)
ctx.lineTo(120,0);
ctx.stroke();
}
}
ctx.restore();
// 时针、分针、秒针、表座
// 创建一个Date对象,获取当前时间
var date = new Date();
// 获取当前的秒数
var s = date.getSeconds();
// 获取当前的分钟数,并加上秒数的部分
var m = date.getMinutes()+s/60;
// 获取当前的小时数,并加上分钟数的部分
var h = date.getHours()+m/60;
// 如果小时数大于12,则减去12
h = h>12?h-12:h;
// 时针
ctx.save()
ctx.lineWidth=14;
// 逆时针旋转小时数乘以30°,即将角度转换为弧度单位
ctx.rotate(h*30*Math.PI/180)
ctx.beginPath()
ctx.moveTo(-20,0);
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore()
// 分针
ctx.save()
ctx.lineWidth=10;
// 逆时针旋转分钟数乘以6°,即将角度转换为弧度单位
ctx.rotate(m*6*Math.PI/180)
ctx.beginPath()
ctx.moveTo(-28,0);
ctx.lineTo(112,0);
ctx.stroke();
ctx.restore()
// 秒针
ctx.save()
ctx.lineWidth=6;
ctx.strokeStyle="#D40000";
ctx.fillStyle="#D40000";
// 逆时针旋转秒数乘以6°,即将角度转换为弧度单位
ctx.rotate(s*6*Math.PI/180)
ctx.beginPath();
ctx.moveTo(-30,0);
ctx.lineTo(83,0);
ctx.stroke();
// 表座
ctx.beginPath();
ctx.arc(0,0,10,0,360*Math.PI/180);
ctx.fill();
// 秒针头
ctx.beginPath();
ctx.arc(96,0,10,0,360*Math.PI/180);
ctx.stroke();
ctx.restore()
ctx.restore();
}
}
}
script>
html>
drawImage(image, x, y, width, height)
:其中 image 是 image 或者 canvas 对象,x 和 y 是其在目标 canvas 里的起始坐标。这个方法多了2个参数:width 和 height,这两个参数用来控制 当像canvas画入时应该缩放的大小var ctx = canvas.getContext("2d");
var img = new Image();
img.src="tg.png";
img.onload=function(){
draw();
}
function draw(){
ctx.drawImage(img,0,0,img.width,img.height)
}
createPattern(image, repetition)
image:图像源
epetition:“repeat” 、“repeat-x” 、“repeat-y” 、“no-repeat”
一般情况下,我们都会将createPattern返回的对象作为fillstyle的值
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
var img = new Image();
img.src="tg.png";
img.onload=function(){
draw();
}
function draw(){
var pattern = ctx.createPattern(img,"no-repeat")
ctx.fillStyle=pattern;
ctx.fillRect(0,0,300,300);
}
}
createLinearGradient(x1, y1, x2, y2)
,表示渐变的起点 (x1,y1) 与终点 (x2,y2)gradient.addColorStop(position, color)
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
var gradient = ctx.createLinearGradient(0, 0, 200, 200);
gradient.addColorStop(0,"red");
gradient.addColorStop(0.5,"yellow");
gradient.addColorStop(0.7,"pink");
gradient.addColorStop(1,"green");
ctx.fillStyle=gradient;
ctx.fillRect(0,0,300,300);
}
径向渐变:createRadialGradient(x1, y1, r1, x2, y2, r2)
var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
var gradient = ctx.createRadialGradient(150, 150, 50, 150, 150, 100)
gradient.addColorStop(0,"red");
gradient.addColorStop(0.5,"yellow");
gradient.addColorStop(0.7,"pink");
gradient.addColorStop(1,"green");
ctx.fillStyle=gradient;
ctx.fillRect(0,0,300,300);
}
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
#test{
background: white;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
style>
head>
<body>
<canvas id="test" width="300" height="300">canvas>
body>
<script type="text/javascript">
window.onload=function(){
var canvas = document.querySelector("#test");
canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;
if(canvas.getContext){
var ctx = canvas.getContext("2d");
// 用于标记当前显示的图片序号
var flag = 0;
// 用于控制图片在x轴的偏移量
var value=0;
setInterval(function(){
ctx.clearRect(0,0,canvas.width,canvas.height)
value+=10;
flag++;
if(flag==9){
// 当图片序号达到9时,重新设置为1
flag=1;
}
var img = new Image();
img.src="img/q_r"+(flag)+".jpg";
img.onload=function(){
draw(this);
}
},100)
function draw(img){
ctx.drawImage(img,value,0)
}
}
}
script>
html>
canvas 提供了两种方法来渲染文本:
fillText(text, x, y)
:在指定的(x,y)位置填充指定的文本strokeText(text, x, y)
:在指定的(x,y)位置绘制文本边框var canvas = document.querySelector("#test");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
ctx.fillStyle="skyblue"
ctx.font="40px sans-serif"
ctx.fillText("lalayouyi",70,150);
ctx.strokeText("lalayouyi",70,150);
}
font = value
textAlign = value
:文本对齐选项。可选的值包括: left, right center.
textBaseline = value
:描述绘制文本时,当前文本基线的属性。
measureText()
方法返回一个 TextMetrics 对象,包含关于文本尺寸的信息(例如文本的宽度)
canvas中文本水平垂直居中
var oC =document.getElementById('c1');
var oGC = oC.getContext('2d');
oGC.font = '60px impact';
oGC.textAlign = 'left';
oGC.textBaseline = 'middle';
var w = oGC.measureText('lalayouyi').width;
oGC.fillText('lalayouyi',(oC.width - w)/2 , (oC.height - 60)/2);
shadowOffsetX = float
:shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们默认都为 0。shadowOffsetY = float
:shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们默认都为 0。shadowBlur = float
:shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0。shadowColor = color
(必需项):shadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。var oC =document.getElementById('c1');
var oGC = oC.getContext('2d');
oGC.font = '60px impact';
oGC.textAlign = 'left';
oGC.textBaseline = 'middle';
var w = oGC.measureText('lalayouyi').width;
//文本阴影&盒阴影
oGC.shadowOffsetX = 20;
oGC.shadowOffsetY = 20;
oGC.shadowBlur = 30;
oGC.shadowColor = "yellow";
oGC.fillText('lalayouyi',(oC.width - w)/2 , (oC.height - 60)/2);
到目前为止,我们尚未深入了解Canvas画布真实像素的原理,事实上,你可以直接通过ImageData对象操纵像素数据,直接读取或将数据数组写入该对象中。
getImageData()
:获得一个包含画布场景像素数据的ImageData对像,它代表了画布区域的对象数据ctx.getImageData(sx, sy, sw, sh)
ImageData
对象中存储着canvas对象真实的像素数据,它包含以下几个只读属性:
putImageData()
方法去对场景进行像素数据的写入。putImageData(myImageData, dx, dy)
:dx和dy参数表示你希望在场景内左上角绘制的像素数据所得到的设备坐标。ctx.createImageData(width, height)
:创建一个ImageData对象,默认创建出来的是透明的。var ctx = canvas.getContext("2d");
// 设置填充样式为"rgba(255, 192, 203,1)"
ctx.fillStyle="rgba(255, 192, 203,1)";
ctx.fillRect(0,0,100,100);
// 获取矩形区域(0, 0, 100, 100)内的图像数据
var imageData = ctx.getImageData(0,0,100,100);
// var imageData = ctx.createImageData(100,100);
// 透明度即为数组 imageData.data中下标为4i+3的值(其中i表示像素点的索引)。
// 将每个像素点的透明度设置为100,即不完全透明状态。
for(var i=0;i<imageData.data.length;i++){
imageData.data[4*i+3]=100;
}
// 重新绘制
ctx.putImageData(imageData,0,0)
流程:
ctx.drawImage
方法绘制原始图片。ctx.getImageData
方法获取原始图片的图像数据,并保存在oldImgdata变量中。ctx.createImageData
方法创建新的图像数据,并保存在newImgdata变量中。ctx.putImageData
方法将修改后的新图像数据绘制到画布上。通过获取和设置图像数据的像素颜色信息,将原始图片划分为小块,并在每个小块中随机选择一个像素点的颜色信息,并应用于整个小块内的所有像素点,从而实现像素化的效果。
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
#msk{
position: absolute;
left: 50%;
top: 50%;
transform: translate3d(-50%,-50%,0);
}
style>
head>
<body>
<canvas id="msk" >canvas>
body>
<script type="text/javascript">
var oc = document.querySelector("#msk");
if(oc.getContext){
var ctx = oc.getContext("2d");
var img = new Image();
img.src="2.png";
img.onload=function(){
oc.width=img.width*2;
oc.height=img.height;
draw();
}
function draw(){
ctx.drawImage(img,0,0);
var oldImgdata = ctx.getImageData(0,0,img.width,img.height);
var newImgdata = ctx.createImageData(img.width,img.height);
// 定义每个小方块的大小为5像素
var size = 5;
for(var i=0;i<oldImgdata.width/size;i++){
for(var j=0;j<oldImgdata.height/size;j++){
// 获取当前小方块内某个像素的颜色信息
var color = getPxInfo(oldImgdata,i*size+Math.floor(Math.random()*size),j*size+Math.floor(Math.random()*size));
for(var a=0;a<size;a++){
for(var b=0;b<size;b++){
// 设置新图像数据中的像素颜色信息
setPxInfo(newImgdata,i*size+a,j*size+b,color)
}
}
}
}
ctx.clearRect(0,0,oc.width,oc.height);
ctx.putImageData(newImgdata,0,0);
}
// 获取指定位置像素的颜色信息
function getPxInfo(imgdata,x,y){
var color = [];
var data = imgdata.data;
var w = imgdata.width;
var h = imgdata.height;
// 获取像素点的红色值
color[0]=data[(y*w+x)*4];
// 获取像素点的绿色值
color[1]=data[(y*w+x)*4+1];
// 获取像素点的蓝色值
color[2]=data[(y*w+x)*4+2];
// 获取像素点的透明度值
color[3]=data[(y*w+x)*4+3];
// 返回颜色信息数组
return color;
}
// 设置指定位置像素的颜色信息
function setPxInfo(imgdata,x,y,color){
var data = imgdata.data;
var w = imgdata.width;
var h = imgdata.height;
data[(y*w+x)*4]=color[0];
data[(y*w+x)*4+1]=color[1];
data[(y*w+x)*4+2]=color[2];
data[(y*w+x)*4+3]=color[3];
}
}
script>
html>
globalAlpha = value
。这个属性影响到 canvas 里所有图形的透明度,有效的值范围是 0.0 (完全透明)到 1.0(完全不透明),默认是 1.0。
var ctx = canvas.getContext("2d");
ctx.fillStyle="red";
ctx.globalAlpha=.4;
ctx.fillRect(0,0,100,100);
ctx.fillRect(100,100,100,100);
globalCompositeOperation
属性用于设置绘制图形时的组合操作方式。组合操作可以理解为将已有的图形和新绘制的图形进行合并或者覆盖的方式。该属性的值可以是以下几种:
"source-over"
(默认值):新绘制的图形覆盖在已有图形之上。这是最常用的组合操作方式。
"source-in"
:新绘制的图形只显示于已有图形的重叠部分,其他部分不可见。
"source-out"
:新绘制的图形只显示于已有图形之外的部分,与已有图形重叠的部分不可见。
"source-atop"
:新绘制的图形显示于已有图形上方的重叠部分,与已有图形下方的部分不可见。
"destination-over"
:已有的图形覆盖在新绘制的图形之上。
"destination-in"
:已有的图形只显示于新绘制图形的重叠部分,其他部分不可见。
"destination-out"
:已有的图形只显示于新绘制图形之外的部分,与新绘制图形重叠的部分不可见。
"destination-atop"
:已有的图形显示于新绘制图形上方的重叠部分,与新绘制图形下方的部分不可见。
"lighter"
:将已有的图形和新绘制的图形颜色混合,得到更亮的颜色。
"copy"
:新绘制的图形完全替换已有的图形。
"xor"
:新绘制的图形与已有的图形进行异或运算,产生一种类似于橡皮擦的效果。
var ctx = canvas.getContext("2d");
ctx.fillStyle="pink";
ctx.fillRect(50,50,100,100);
// 控制新绘制的图形如何与已有的图形进行组合。
// 源图形仅会在与目标图形重叠的区域内显示,并且会覆盖目标图形,而非重叠区域将保持目标图形原有的样式。
ctx.globalCompositeOperation="destination-atop";
ctx.fillStyle="green";
ctx.fillRect(100,100,100,100);
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">meta>
<title>title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
html,body{
height: 100%;
overflow: hidden;
}
#wrap,ul,ul>li{
height: 100%;
}
ul>li{
background: url(img/b.png);
background-size:100% 100% ;
}
canvas{
position: absolute;
left: 0;
top: 0;
transition:1s;
}
style>
head>
<body>
<div id="wrap">
<canvas>canvas>
<ul>
<li>li>
ul>
div>
body>
<script type="text/javascript">
window.onload = function() {
var canvas = document.querySelector("canvas");
canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = "img/a.png";
img.onload = function() {
draw();
}
//绘制画布
function draw() {
// 记录透明像素点的数量
var flag = 0;
// 将图片绘制到画布上
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
// 判断是否正在绘制路径(使得刮刮乐更平滑)
var isDrawing = false;
var lastX = 0; // 上一个绘制点的水平坐标
var lastY = 0; // 上一个绘制点的垂直坐标
canvas.addEventListener("mousedown", startDrawing);
canvas.addEventListener("mousemove", drawPath);
canvas.addEventListener("mouseup", stopDrawing);
/**
* 开始绘制路径
* @param {MouseEvent} ev 鼠标按下事件
*/
function startDrawing(ev) {
isDrawing = true;
// 获取当前鼠标位置的水平坐标
var x = ev.clientX - canvas.offsetLeft;
// 获取当前鼠标位置的垂直坐标
var y = ev.clientY - canvas.offsetTop;
// 记录起始坐标
[lastX, lastY] = [x, y];
}
/**
* 绘制路径
* @param {MouseEvent} ev 鼠标移动事件
*/
function drawPath(ev) {
if (!isDrawing) return;
var x = ev.clientX - canvas.offsetLeft;
var y = ev.clientY - canvas.offsetTop;
// 设置绘制模式为“目标图像透明部分显示出来”
ctx.globalCompositeOperation = "destination-out";
ctx.lineWidth = 40;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.save();
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.stroke();
ctx.restore();
[lastX, lastY] = [x, y];
}
/**
* 停止绘制路径
*/
function stopDrawing() {
isDrawing = false;
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// 计算像素总数
var allPx = imgData.width * imgData.height;
for (var i = 0; i < allPx; i++) {
// 判断像素是否透明
if (imgData.data[4 * i + 3] === 0) {
flag++;
}
}
// 如果透明像素点数量超过一半,则将画布透明度设置为0(就认为已经刮得差不多
if (flag >= allPx / 2) {
canvas.style.opacity = 0;
}
}
// 监听CSS过渡效果结束事件
canvas.addEventListener("transitionend", function() {
this.remove(); // 移除画布元素
})
}
}
}
script>
html>