Javascript 使用three.js/webgl的基于Web的雷达动画

Javascript 使用three.js/webgl的基于Web的雷达动画,javascript,html,three.js,webgl,css-transitions,Javascript,Html,Three.js,Webgl,Css Transitions,我正在考虑实现一个基于web的雷达动画可视化,并在上查看了相当简单的实现。第一个版本看起来很不错,但确实占用了大量CPU,而纯CSS版本有点太简单了。使用webgl实现类似于第一个版本的硬件加速,例如使用three.js,会有多困难 我发现的另一个看起来很不错,实际上是在画布上实现的:(必须粘贴代码): var-radar=document.getElementById('radar'), 直径=220, 半径=直径/2, 填充=14, ctx=Sketch.create({ 集装箱:雷达, 全

我正在考虑实现一个基于web的雷达动画可视化,并在上查看了相当简单的实现。第一个版本看起来很不错,但确实占用了大量CPU,而纯CSS版本有点太简单了。使用webgl实现类似于第一个版本的硬件加速,例如使用three.js,会有多困难

我发现的另一个看起来很不错,实际上是在画布上实现的:(必须粘贴代码):

var-radar=document.getElementById('radar'),
直径=220,
半径=直径/2,
填充=14,
ctx=Sketch.create({
集装箱:雷达,
全屏:假,
宽度:直径,
高度:直径
}),
dToR=函数(度){
返回度*(数学PI/180);
},
扫掠角=270,
扫掠尺寸=2,
扫掠速度=1.2,
环=4,
hueStart=120,
hueEnd=170,
hueDiff=Math.abs(hueEnd-hueStart),
饱和=50,
亮度=40,
线宽=2,
渐变=ctx.createLinearGradient(半径,0,0,0);
radar.style.marginLeft=radar.style.marginTop=(-diameter/2)-填充+px';
渐变色.addColorStop(0,'hsla('+hueStart+','+saturation+'%,'+lightness+'%,1'));
渐变。添加色阻(1,'hsla('+hueEnd+','+saturation+'%,'+lightness+'%,0.1)');
var renderRings=函数(){
var i;
对于(i=0;i

不过,它对CPU的占用也有点大。

我认为最简单的方法是画两个精灵,一个是雷达的基本图像,另一个是扫描线。然后每帧旋转一次扫描线精灵就可以了,我同意WacławJasper的观点,几张图片和旋转就可以了。但是如果你真的想让GPU参与进来,你可以编写一个着色器,比如或。如果您想要在2D中使用three.js,就不需要它
var radar = document.getElementById( 'radar' ), 
diameter = 220,
radius = diameter / 2,
padding = 14,
ctx = Sketch.create({
  container: radar,
  fullscreen: false,
  width: diameter,
  height: diameter
}),
dToR = function( degrees ){ 
  return degrees * (Math.PI / 180);
},
sweepAngle = 270,
sweepSize = 2,
sweepSpeed = 1.2,
rings = 4,
hueStart = 120,
hueEnd = 170,
hueDiff = Math.abs( hueEnd - hueStart ),
saturation = 50,
lightness = 40,
lineWidth = 2,
gradient = ctx.createLinearGradient( radius, 0, 0, 0 );


radar.style.marginLeft = radar.style.marginTop = ( -diameter / 2 ) - padding + 'px';
gradient.addColorStop( 0, 'hsla( ' + hueStart + ', ' + saturation + '%, ' + lightness + '%, 1 )' );
gradient.addColorStop( 1, 'hsla( ' + hueEnd + ', ' + saturation + '%, ' + lightness + '%, 0.1 )' );

var renderRings = function(){
  var i;
  for( i = 0; i < rings; i++ ){
    ctx.beginPath();
    ctx.arc( radius, radius, ( ( radius - ( lineWidth / 2) ) / rings) * ( i + 1 ), 0, TWO_PI, false );
    ctx.strokeStyle = 'hsla(' + ( hueEnd - ( i * ( hueDiff / rings ) ) ) + ', ' + saturation + '%, ' + lightness + '%, 0.1)';
    ctx.lineWidth = lineWidth;
    ctx.stroke();
  };
};

var renderGrid = function(){
  ctx.beginPath();
  ctx.moveTo( radius - lineWidth / 2, lineWidth );
  ctx.lineTo( radius - lineWidth / 2, diameter - lineWidth );
  ctx.moveTo( lineWidth, radius - lineWidth / 2 );
  ctx.lineTo( diameter - lineWidth, radius - lineWidth / 2 );
  ctx.strokeStyle = 'hsla( ' + ( ( hueStart + hueEnd ) / 2) + ', ' + saturation + '%, ' + lightness + '%, .03 )';
  ctx.stroke();
};

var renderSweep = function(){
  ctx.save();
  ctx.translate( radius, radius );
  ctx.rotate( dToR(sweepAngle) );  
  ctx.beginPath();
  ctx.moveTo( 0, 0 );
  ctx.arc( 0, 0, radius, dToR( -sweepSize ), dToR( sweepSize ), false );
  ctx.closePath();
  ctx.fillStyle = gradient;
  ctx.fill();  
  ctx.restore();
};

var renderScanLines = function(){
  var i;
  var j;
  ctx.beginPath();
  for( i = 0; i < diameter; i += 2 ){    
    ctx.moveTo( 0, i + .5 );
    ctx.lineTo( diameter, i + .5);
  };
  ctx.lineWidth = 1;
  ctx.strokeStyle = 'hsla( 0, 0%, 0%, .02 )';
  ctx.globalCompositeOperation = 'source-over';
  ctx.stroke();
};

ctx.clear = function(){
  ctx.globalCompositeOperation = 'destination-out';
  ctx.fillStyle = 'hsla( 0, 0%, 0%, 0.1 )';
  ctx.fillRect( 0, 0, diameter, diameter );
};

ctx.update = function(){
  sweepAngle += sweepSpeed;
};

ctx.draw = function(){
  ctx.globalCompositeOperation = 'lighter';
  renderRings();
  renderGrid();
  renderSweep();
  renderScanLines();
};