# Canvas 绘制风向动画

```根据UV 图提取出每个格点的
tmpCanvas.width = windImage.width;
tmpCanvas.height = windImage.height;
tmpCtx.drawImage(windImage, 0, 0);
// imageData.data.length: width*height*4
let imageData = tmpCtx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height),
dataLength = imageData.data.byteLength;
if (compressRatio == undefined || (compressRatio !== undefined && compressRatio < 1)) {
console.warn("Input compressRatio invalid, use default 1.");
compressRatio = 1;
}
for (let i=1;i<tmpCanvas.height-1;i+=compressRatio) {
// i:0~180, j:0~360
for (let j=0;j<tmpCanvas.width;j+=compressRatio) {
let particle = {
'lon': -180 + j,
'lat': -90 + i,
};
let uIndex = (i * 360 + j) * 4, vIndex = uIndex + 1;
let uVal = imageData.data[uIndex], vVal = imageData.data[vIndex],
// 根据UV计算风力，和风向.
windPow = Math.pow(uVal, 2) + Math.pow(vVal, 2),
angle = Number(Math.atan(vVal/uVal).toFixed(2)),
color = 'rgba('+ (windPow/255).toFixed(0) + ', 255, 100, 0.7)';
// return geojson dataSource for mapboxgl.vector layer.
if (geojson) {
particle = { "type": "Feature",
"properties": {
"angle": angle,
"color": color
},
"geometry": {
"type": "Point",
"coordinates": [-180 + j, -90 + i]
}
}
features.push(particle);
} else {
// 如果不用geojson 的数据，就用自定义的canvas 去渲染，为了动画方便，我们采用这种方式.
particle.color = color;
particle.angle = angle;
particles.push(particle);
}
}
}```

### Canvas 渲染风向

```// genWindTarget 函数其实就是根据风向来模拟一个风粒子的动画效果，产生动画的目标对象，Alex.myTween为根据source 和target 自动计算中间坐标和状态.

objs = windlayer.particles; targets = genWindTarget(objs);
// calc targets depend on its angle, use 6 degree as dist.
Alex.myTween.get(objs).to(targets, 8000, windlayer.redraw);
map.on('moveend', function(){
windlayer.redraw(objs);
});```

|