公司官网改版,决定学(zhao)习(ban)一下腾讯集团官网的首页,官网其他部分都没什么难点,主要就是banner动画效果的实现,可没找到腾讯的源码,索性直接从0实现一个
1.随机在页面上生成圆环并慢慢变大
2.到一定尺寸时,渐隐直至消失
3.随机的中心点要在中国地图里
一个就三个需求
先看效果图
<body>
<div id="banner">
<img src="./banner.jpg"/>
<canvas id="canvas"></canvas>
</div>
</body>
html简单给一个底图,在底图上面一个空白的canvas
var canvas = document.getElementById('canvas')//实现动画效果
var ctx = canvas.getContext('2d')
var cx = canvas.width = 700
var cy = canvas.height = 550
var round = []
var initRoundPopulation = 18
var canvas2 = document.createElement('canvas')//记录中国地图的边界
var ctx2 = canvas2.getContext('2d')
canvas2.width = cx
canvas2.height = cy
页面中现有的canvas来做动画,再创建一个canvas节点储存中国地图的边界
//中国地图的边际线
var mapline = [ [125,170],
[125,140],
[220,85],
[247,125],
[305,180],
[380,205],
[450,180],
[495,125],
[543,22],
[663,72],
[663,125],
[585,205],
[585,480],
[450,480],
[450,545],
[390,540],
[390,480],
[305,480],
[290,400],
[220,400],
[140,370],
[80,315],
[50,180]
]
ctx2.beginPath()
ctx2.moveTo(50,180)
for(var i=0;i<mapline.length;i++){
for(var j=0;j<mapline[i].length;j++){
ctx2.lineTo(mapline[i][0],mapline[i][1])
}
}
ctx2.closePath()
ctx2.fillStyle = 'red'
ctx2.fill()
将中国地图绘制进canvas2中
function Round_item(index,x,y){ //设置圆环对象的属性
this.index = index;
this.x = x
this.y = y
this.r = Math.random() * 50 + 1
this.maxR = Math.floor(Math.random()*50)+30
this.color = 'white'
this.globalAlpha = 1
}
Round_item.prototype.draw = function(){ //绘制圆环
ctx.strokeStyle = this.color
ctx.globalAlpha = this.globalAlpha
ctx.shadowBlur = this.r * 2
ctx.beginPath()
//注意这里时ctx2
if(ctx2.isPointInPath(this.x,this.y)){//判断中心点是否在中国地图中
ctx.arc(this.x,this.y,this.r,0,Math.PI*2)
}
ctx.closePath()
ctx.stroke()
}
Round_item.prototype.move = function(){//做动画效果
this.r += 0.15 //圆的半径递增
var tAlpha = (this.r / this.maxR) //(当前圆的半径)/ (圆半径的最大值) 算出动画完成的百分比
if(tAlpha> 0.8){ //当完成80%时
this.globalAlpha -= 0.1 //圆的透明版递减
if(this.globalAlpha<0.1){ //透明版不能负数
this.globalAlpha = 0
}
}
if(this.r > this.maxR){ //当圆到达最大比例时
this.r = 10//将这个圆返回为最小
this.x = Math.random()*cx//再随机一个坐标
this.y = Math.random()*cy
this.globalAlpha = 1//把透明的变为1
}
this.draw()//再进行绘制
}
function animate(){
ctx.clearRect(0,0,cx,cy)
for(var i in round){
round[i].move()
}
requestAnimationFrame(animate)//一个新的api,详细查看mdn
}
function init(){//初始化
for(var i=0;i<initRoundPopulation;i++){
round[i] = new Round_item(i,Math.random()*cx,Math.random()*cy)
round[i].draw()
}
animate()
}
init()
绘制动画效果,使用面向对象来写这个方法,具体看注释
- 主要卡壳就卡在判断是否在中国地图内,一开始寻找判断”一个点是否在不规则图形中“,无果
- 随后发现
inpointinpath()
的方法,但做判断时,永远为false。一步步检查发现,页面每一帧都会绘制很多路径,这些点不可能在路径里。决定试一试createElement('canvas')
来保存地图的路径。 - 最后用生成的圆心来和单独保存的路径进行比较,问题顺利解决