canvas離屏、旋轉效果實踐——旋轉的雪花

效果展現
理論基礎——「常見的canvas優化——模糊問題、旋轉效果」canvas

用離屏canvas畫基礎部分

一、封裝畫線函數segmentfault

function drawLine(ctx,x1,y1,x2,y2,color){
  ctx.save();
  ctx.beginPath();
  ctx.strokeStyle = color;
  ctx.lineTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.stroke();
  ctx.restore();
}

二、畫雪花的六條線函數

function canvasSingleSnow(snowSize){
  var singleSnow = document.createElement('canvas');
  var ctxSingle = singleSnow.getContext('2d');
  singleSnow.setAttribute('width', snowSize * 2);
  singleSnow.setAttribute('height', snowSize * 2);
  ctxSingle.translate(snowSize, snowSize);//定位原點到畫布中心
  for(var i = 0; i < 6; i++){//畫六條線
    ctxSingle.save();
    ctxSingle.rotate(Math.PI*2 * i/6);
    drawLine(ctxSingle, 0, 0, snowSize, 0,"#656565");
    ctxSingle.restore();
  }
  return singleSnow;
}

首先這裏用到了離屏canvas,咱們經過傳參的方式肯定離屏canvas的尺寸,是爲了儘量避免canvas圖案縮放致使的顯示效果問題。oop

另外這裏for循環中用到了canvas的旋轉效果,因此咱們能夠很輕易的畫出6條有角度的線。效果以下圖所示優化

clipboard.png

三、畫出完整的雪花spa

function drawCanvasSnow(centerSnow){
  var canvasSnow = document.createElement('canvas');
  var ctxSnow = canvasSnow.getContext('2d');
  canvasSnow.setAttribute('width', centerSnow * 2);
  canvasSnow.setAttribute('height', centerSnow * 2);
  //畫一個大雪花
  var bigSnow = canvasSingleSnow(centerSnow);
  ctxSnow.drawImage(bigSnow, 0, 0, bigSnow.width, bigSnow.height,
    0, 0, centerSnow * 2, centerSnow * 2);
  //畫六個小雪花
  var smallSnow = canvasSingleSnow(centerSnow/3);
  var sizeSnow = centerSnow * 3/5;//小雪花的尺寸(直徑)
  var rSnow = centerSnow - sizeSnow/2;//小雪花的位置(離大雪花中心的距離)
  for(var i = 0; i < 6; i++){
    ctxSnow.save();
    ctxSnow.translate(centerSnow, centerSnow);
    ctxSnow.rotate(Math.PI*2 * i/6);
    ctxSnow.drawImage(smallSnow, 0, 0, smallSnow.width, smallSnow.height,
      rSnow - sizeSnow/2, -sizeSnow/2, sizeSnow, sizeSnow);
    ctxSnow.restore();
  }
  return canvasSnow;
}

上述代碼中尺寸部分說明:小雪花的尺寸比大雪花小,用比例能夠方便縮放;小雪花的位置則固定在大雪花六條線的端點處。效果以下圖所示.net

clipboard.png

將離屏canvas做爲資源畫到實際顯示的canvas上

一、封裝一個根據旋轉加載離屏canvas的函數rest

//r爲雪花圖案中心距畫布中心的距離
//angle爲雪花圖案在畫布上的安放角度
//size爲雪花圖案的顯示尺寸
function drawSnowAngle(ctx,r,angle,size){
  ctx.save();
  ctx.rotate(Math.PI*2 * angle);
  drawLine(ctx,0,0,r,0,"#656565");
  ctx.drawImage(canvasSnow, 0, 0, canvasSnow.width, canvasSnow.height,
    r - size/2, -size/2, size, size);
  ctx.restore();
}

二、能夠將離屏canvas畫的雪花圖案畫到實際顯示的canvas上了code

//center爲實際顯示canvas的畫布中心(半徑)
//rSnow爲雪花圖案的半徑
drawSnowAngle(ctx, center - rSnow, i/snowNum, rSnow * 2);

三、加上動態旋轉效果blog

var snowNum = 1;
var isAdd = true;
var loop = setInterval('drawCanvas()', 10);//定時器,每10ms繪製一次
function drawCanvas(){
  //設置旋轉效果
  if(snowNum >= 18){isAdd = false;}//最大個數爲18
  else if(snowNum <= 1){isAdd = true;}//最小個數爲1
  if(isAdd){snowNum += snowNum/200;}//達到最大後開始遞減
  else{snowNum -= snowNum/100;}//達到最少後開始遞增
  //畫圖
  var rSnow = center/2 * (snowNum - 6)/6;//設置雪花圖案顯示尺寸
  canvasSnow = drawCanvasSnow(rSnow);//畫出離屏雪花圖案
  ctx.clearRect(-center, -center, center * 2, center * 2);//清除畫布
  for(var i = 0; i < snowNum; i++){//開始畫圖
    drawSnowAngle(ctx, center - rSnow, i/snowNum, rSnow * 2);
  }
}

旋轉的雪花就這樣完成了。效果見文章開頭的效果展現連接

相關文章
相關標籤/搜索