- 首次使用canvas绘图
- 删除画布区域 重绘
- 绘制边框 填充图形 修改样式(作用域)
- 插入图片, 2d变换
- 绘制圆 弧形
- 像素及操作
- 引入图片和视频
- 覆盖模式
- canvas动画 ,示例动画 (做canvas前先看看示例动画)
- 微信场景
// 建议这样绘制
ctx.beginPath();
ctx.save()
ctx.setFontSize(28 * common);
ctx.fillStyle = "#E9CA97"; // linear-gradient(#FFFFFF, #FDCA99)
ctx.fillText('再住2间夜可升级为', 240 * common, 156 * common);
ctx.restore()
位图:支持更多像素但放大会模糊 canvas
矢量图: 放大依旧很清晰 svg
canvas默认大小300*150
标签上设置height和width来设置大小
1.获取canvas标签,并设置绘制环境
let c1=document.getElementById(‘c1’)
let ctx =c1.getContext(‘2d’) //有两种环境2d 3d是webgl
2开始绘制
绘制方块 x y w h默认黑色
ctx.fillRect(100,100,100,100)
绘制边框 默认黑色 大小1px(会从边框向两边平分像素)
ctx.strokeRect(100.5,100.5,100,100)
先写样式再写边框图形等
ctx.lineWidth = 10
ctx.strokeStyle =‘red’
ctx.fillStyle = ‘black’ // 或者’rgba(255,0,0,255)’
ctx.fillRect(100,100,100,100)
ctx.strokeRect(100,100,100,100)
绘制路径 绘制填充
ctx.save()//开启作用域,不会对外部的起作用 restore结束作用域
ctx.strokeStyle = ‘blue’
ctx.beginPath()//(begainPath表示开始绘制一个新路径)baginPath和closePath用来包裹点,使每个路径不受填充的影响
ctx.moveTo(100,100) //第一个点
ctx.lineTo(200,200) //后续的点。。。
ctx.lineTo(300,300)
ctx.closePath()//closePath默认连接起点和终点
ctx.stroke() //进行绘制 stroke() 方法会实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径
//ctx.fill() //填充
ctx.restore()
删除一个矩形区域 删除画布
删除矩形区域 x y w h
ctx.clearRect(100,100,50,50)
删除画布
ctx.clearRect(0,0,c1.width,c1.height)//意思就是 (0,0)坐标点删除画布一样大小区域
插入图片
//创建img对象,加载成功后添加到canvas中
let img = new Image()
img.src=’./logo.png’
img.οnlοad=function(){
//三个参数时
ctx.drewImg(img,100,100)
//五个参数时
// ctx.drewImg(img,100,100,50,50)//图片对象,图片偏移的xy坐标,图片在canvas中的大小
// 九个参数
ctx.drawImg(img,在图片的x坐标,在图片的y坐标,在图片的宽,在图片的高,100,100,50,50)
}
2d变换
ctx.translate(100,100)
ctx.rotate(45*Math.PI/180)//单位为弧度
ctx.scale(2,0.5)//xy轴缩放比例
绘制圆形 圆弧
ctx.arc(圆心x坐标,圆心y坐标,圆半径,开始圆弧的弧度,结束圆弧的弧度,圆弧方向默认顺时针false可不写)
//角度和弧度换算公式 1角度= Math.PI / 180
//开始和结束圆弧的弧度相等时,绘制的是一条直线
//0弧度的位置在整个圆的最右侧
ctx.arc(200,200,100,0,90 * Math.PI/180,true)
像素及操作
获取像素点
ctx.getImageData(x坐标,y坐标,获取像素区域的宽,获取像素区域的高)
ctx.fillRct(50,50,100,100)
let imgs = cxt.getImageData(50,50,100,100)
// imgs.width imgs.height imgs.data//存储的是每个像素的rgba颜色值(所以是像素个数的4倍)
设置新的像素
ctx.putImageData(获取图片的像素,x,y)
imgs.data[0] = 255
imgs.data[1] = 0
imgs.data[2] = 255
imgs.data[3] = 125
ctx.putImageData(imgs,50,50)
生成像素矩阵
ctx.createImageData(像素区域的宽,像素区域的高)
let imgs = ctx.createImageData(100,100)
console.log(imgs) // 默认全部都是黑色透明的像素点
for(let i=0;i<imgs.data.length;i+=4){
imgs.data[i] = ‘255’
imgs.data[i+1] = ‘255’
imgs.data[i+1] = ‘0’
imgs.data[i+2] = ‘255’
}
ctx.putImageData(imgs,0,0)
封装: 获取和设置指定位置的像素点
// 在数组中的位置 = y*w+x
function getXY(imgs,x,y){
let w = imgs.data.width
let d = imgs.data
let color = []
color[0] = d[ 4 * ( y * w +x ) ]
color[1] = d[ 4 * ( y * w +x ) + 1]
color[2] = d[ 4 * ( y * w +x ) + 2]
color[3] = d[ 4 * ( y * w +x ) + 3]
return color
}
function setXY(imgs,x,y,color){
let w = imgs.data.width
let d = imgs.data
let color = []
d[ 4 * ( y * w +x ) ] = color[0]
d[ 4 * ( y * w +x ) + 1] = color[1]
d[ 4 * ( y * w +x ) + 2] = color[2]
d[ 4 * ( y * w +x ) + 3] = color[3]
}
canvas倒影(图片倒着渲染) canvas色彩公式(图片反色[256分别减去r g b ] 图片灰色[给r g b同时给 (r+b+c)/3]等效果) canvas视频操作
canvas操作图片必须在服务器下(有跨域限制)
c1.height = 800 c1.width=800
// 要先改变画布大小再操作画布
引入视频
页面使用video标签拿到视频
let c1 = document.getElementById('canvas')
let video = document.getElementById('video')
let ctx = c1.getContext('2d')
video.addEventListener('canplaythrough', function () {
c1.height = this.videoHeight
c1.width = this.videoWidth
let imgs = ctx.getImageData(0, 0, this.videoWidth, this.videoHeight)
let newImgs = ctx.createImageData(this.videoWidth, this.videoHeight)
ctx.drawImage(this, 0, 0)
setInterval(() => {
for (let i = 0; i < imgs.height; i++) {
for (let j = 0; j < imgs.width; j++) {
let color = getXY(imgs, j, i)
color[3] = color[3] * (i / (imgs.height - 1))
setXY(newImgs, j, imgs.height - 1 - i, color)
}
}
ctx.putImageData(newImgs, 0, this.height)
ctx.drawImage(this, 0, 0)
}, 0)
})
源:新的图形 // 默认源图形覆盖在目标图形上
目标: 已经绘制过的图形
globalCompositeOperation可以设置不同的覆盖模式
canvas动画 = 定时器 + 重绘 + 收集数据
// 示例动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
background-color: black;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400" color="white">
当前浏览器不支持canvas
</canvas>
<script>
var c1 = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
c1.fillStyle = 'rgba(0,0,0,255)'
var data = [] // 一.1:数据收集
// 实现运动的
setInterval(() => { // 二.1:开启定时器
// 二.2对数据进行变化
for (let i = 0; i < data.length; i++) {
data[i].r += 1
data[i].c4 -= 0.01 // 半径递减0.01
if (data[i].c4 <= 0) { // 优化性能,只保留前几十个
data.splice(i, 1)
}
}
console.log(data.length)
ctx.clearRect(0, 0, c1.width, c1.height) // 三:重绘
for (let i = 0; i < data.length; i++) {
ctx.fillStyle = `rgba(${data[i].c1},${data[i].c2},${data[i].c3},${data[i].c4})`
ctx.beginPath()
ctx.arc(data[i].x, data[i].y, data[i].r, 0, 360 * Math.PI / 180)
ctx.closePath()
ctx.fill()
}
}, 16)
// 一.2 每个一段时间,将数据添加到集合当中
setInterval(() => {
data.push({
x: Math.floor(Math.random() * 400),
y: Math.floor(Math.random() * 400),
r: 5,
c1: Math.floor(Math.random() * 255),
c2: Math.floor(Math.random() * 255),
c3: Math.floor(Math.random() * 255),
c4: 1
})
}, 500)
</script>
</body>
</html>
微信场景: 下面是(刮开新页面,自动播放音乐上下切屏)
传送连接: 链接