文档:CanvasGradient - Web API | MDN
1.使用canvas基本步骤
不能用css样式来控制cavnas的宽高
设置线条宽度和颜色 注意这些设置需要再stroke()之前
锥形渐变
2.画线
连续路径
3.重复元图像
3.圆弧
笑脸小练习
4.椭圆
第5个参数可以控制整个椭圆的角度,是横着竖着还是斜着
例如 90*Math.PI/180就是竖着的
接上文的小案例
5.贝赛尔曲线
6.填充图案 fill()
context.fill() 先画路径再填充 调用fill方法的时候,路径会自动连接起始点和终点
渐变原理
7.制作五子棋小游戏
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
canvas {
background-color: #0a0;
display: block;
margin: 0 auto;
}
#info{
text-align: center;
font-size: 20px;
font-weight: bold;
}
</style>
</head>
<body>
<div id="info">请黑子落子</div>
<script>
const canvas = document.createElement('canvas')
canvas.width = 800;
canvas.height = 800;
document.body.appendChild(canvas);
const content = canvas.getContext('2d')
let circle = []
for (let i = 0; i < 16; i++) {
circle[i] = []
for (let j = 0; j < 16; j++) {
circle[i][j] = null
}
}
// 画棋盘 循环14次,画14条横线和14条竖线
for (let i = 1; i < 16; i++) {
// 画横线
//线段开头
content.moveTo(50, 50 * i)
//线段终点
content.lineTo(750, 50 * i)
content.stroke()
// 画竖线
content.moveTo(50 * i, 50)
content.lineTo(50 * i, 750)
content.stroke()
}
let isBlack = true
canvas.addEventListener('click', e => {
let { offsetX, offsetY } = e
//边界判断
if (offsetX < 50 || offsetX > 750 || offsetY < 50 || offsetY > 750) {
return
}
let x = Math.floor((offsetX + 25) / 50) * 50
let y = Math.floor((offsetY + 25) / 50) * 50
let xIndex = Math.floor((offsetX + 25) / 50)
let yIndex = Math.floor((offsetY + 25) / 50)
if (circle[xIndex][yIndex]) {
alert('该位置已有棋子,请选择其他位置。')
return
}
circle[xIndex][yIndex] = isBlack ? 'black' : 'white'
content.beginPath()
content.arc(x, y, 10, 0, Math.PI * 2)
//渐变棋子样式
let color_x = isBlack?x-10:x+10
let color_y = isBlack?y-10:y+10
let g = content.createRadialGradient(color_x,color_y,1,color_x,color_y,30)
g.addColorStop(0,isBlack?'#ccc':'#666')
g.addColorStop(1,isBlack?'#000':'#fff')
content.fillStyle = g
//设置棋子的阴影
content.shadowColor = '#333'
content.shadowBlur = 4
content.shadowOffsetX = 4
content.shadowOffsetY = 4
//单纯黑白棋子样式
// content.fillStyle = isBlack ? 'black' : 'white'
//填充棋子不描边
content.fill()
// content.stroke()
content.closePath()
//检查是否连成5子
if(checkWin(xIndex,yIndex)){
setTimeout(() => {
alert(isBlack ? '黑子胜利' : '白子胜利')
}, 100)
return
}
document.getElementById('info').innerHTML = isBlack ? '请白子落子' : '请黑子落子'
isBlack = !isBlack
})
//检查纵向是否连成5子
function checkWin(row, col) {
let directions = [
{ x: 1, y: 0 }, // 水平
{ x: 0, y: 1 }, // 垂直
{ x: 1, y: 1 }, // 斜向下
{ x: 1, y: -1 } // 斜向上
]
let target = circle[row][col]
for (let dir of directions) {
let count = 1
// 向一个方向搜索
for (let i = 1; i <= 4; i++) {
let x = row + dir.x * i
let y = col + dir.y * i
if (x < 0 || x >= 16 || y < 0 || y >= 16 || circle[x][y] !== target) break
count++
}
// 向相反方向搜索
for (let i = 1; i <= 4; i++) {
let x = row - dir.x * i
let y = col - dir.y * i
if (x < 0 || x >= 16 || y < 0 || y >= 16 || circle[x][y] !== target) break
count++
}
if (count >= 5) return true
}
return false
}
</script>
</body>
</html>
8使用cavnas绘制图片
CanvasRenderingContext2D:drawImage() 方法 - Web API | MDN
8.1使用canvas绘制图片实现动画
8.2滤镜
CanvasRenderingContext2D:filter 属性 - Web API | MDN
9.使用cavnas绘制文字
9.1渐变的文字
9.2文字对齐方式
10.变形
10.1translate方法位移
10.2rotate方法实现图形旋转
10.3使用scale实现图形缩放
10.4transfrom方法实现变换效果
11.动画
11.1平移小方块
11.2太阳地球月亮运行小练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
</style>
</head>
<body>
<script>
const canvas = document.createElement('canvas')
canvas.width = 800;
canvas.height = 800;
document.body.appendChild(canvas);
const content = canvas.getContext('2d')
//准备一个地球旋转角度
let earthAngle = 0
//准备一个月亮旋转角度
let moonAngle = 0
function loop(){
//解决图形闪烁
content.save()
//清除之前画布上的内容
content.clearRect(0,0,canvas.width,canvas.height)
//画太阳
//把太阳画在x:400 y:300的位置上
content.beginPath()
content.arc(400,300,100,0,2*Math.PI)
content.fillStyle = '#e3fa14'
content.shadowColor ='#e3fa14'
content.shadowBlur = 10
content.fill()
content.closePath()
//画地球
content.beginPath()
//把原点移动正中心
content.translate(400,300)
//画笔旋转一个角度
content.rotate((earthAngle +=0.5)*Math.PI/180)
//为了画月亮的动画,把原点设置成和地球中心完全一致
content.translate(200,0)
content.arc(0,0,20,0,2*Math.PI)
content.fillStyle = 'blue'
content.shadowBlur = 0
content.fill()
content.closePath()
//画月亮
content.beginPath()
//画笔旋转一个角度
content.rotate((moonAngle +=2)*Math.PI/180)
content.arc(40,0,6,0,2*Math.PI)
content.fillStyle = 'green'
content.fill()
content.closePath()
content.restore()
requestAnimationFrame(loop)
}
requestAnimationFrame(loop)
</script>
</body>
</html>