canvas繪圖

https://blog.csdn.net/lecepin/article/details/53536445

思路:增加每個像素點的寬度 減少數組個數。 用另外一個數組去維護每個點的唯一。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    #c1 {
      background: #ccc;
    }
  </style>
</head>
<body>
  <canvas id="c1"></canvas>
  <script>
var canvas = document.getElementById('c1');
var ctx = canvas.getContext('2d');


//畫布屬性
var mW = canvas.width = screen.width;
var mH = canvas.height = 300;
var lineWidth = 3;

var speed = 1; //波浪速度,數越大速度越快
var speedx = 0.05; //波浪速度,數越大速度越快
var yOffset = 0; //波浪x偏移量
var xOffset = 0; //波浪x偏移量

//Sin 曲線屬性
var sX = 0;
var sY = mH / 2;
var axisLength = mW; //軸長
var waveWidth = 0.011 ;   //波浪寬度,數越小越寬    
var waveHeight = 70; //波浪高度,數越大越高

ctx.lineWidth = lineWidth;

//畫sin 曲線函數
var drawSin = function(yOffset,xOffset){
    ctx.save();

    var points=[];  //用於存放繪製Sin曲線的點

    ctx.beginPath();
    //在整個軸長上取點
    for(var x = sX; x < sX + axisLength; x += 20 / axisLength){
        //此處座標(x,y)的取點,依靠公式 “振幅高*sin(x*振幅寬 + 振幅偏移量)”
        // var y = -Math.sin((sX + x) * waveWidth);
        var y = -Math.sin((sX + x) * waveWidth+xOffset);
        points.push([x, sY + y * waveHeight]);
        ctx.lineTo(x, sY + y * waveHeight+yOffset);     
    }
    //封閉路徑
    ctx.lineTo(axisLength, mH);
    ctx.lineTo(sX, mH);
    ctx.lineTo(points[0][0],points[0][1]);
    ctx.stroke();

    ctx.restore();
};
drawSin(yOffset,xOffset);
var render = function(){
    ctx.clearRect(0, 0, mW, mH);

    drawSin(yOffset,xOffset);
    // drawSin(xOffset2);
    // drawSin(20);
    yOffset += speed; //形成動態效果
    xOffset += speedx; //形成動態效果
    if(yOffset > waveHeight ){
      speed = -1;
    }
    if(yOffset < -waveHeight){
      speed = 1;
    }
    requestAnimationFrame(render);
}

render();
  </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    #c1 {
      background: #ccc;
    }
  </style>
</head>
<body>
  <canvas id="c1"></canvas>
  <script>
var canvas = document.getElementById('c1');
var ctx = canvas.getContext('2d');


//畫布屬性
var mW = canvas.width = screen.width;
var mH = canvas.height = 300;
var lineWidth = 3;

var speed = 1; //波浪速度,數越大速度越快
var speedx = 0.05; //波浪速度,數越大速度越快
var yOffset = 0; //波浪x偏移量
var xOffset = 0; //波浪x偏移量

//Sin 曲線屬性
var sX = 0;
var sY = mH / 2;
var axisLength = mW; //軸長
var waveWidth = 0.011 ;   //波浪寬度,數越小越寬    
var waveHeight = 70; //波浪高度,數越大越高

ctx.lineWidth = lineWidth;

    var points=[];
//畫sin 曲線函數
var drawSin = function(yOffset,xOffset){
    ctx.save();
  //用於存放繪製Sin曲線的點

    ctx.beginPath();
    //在整個軸長上取點
    for(var x = sX; x < sX + axisLength; x += 2000 / axisLength){
        //此處座標(x,y)的取點,依靠公式 “振幅高*sin(x*振幅寬 + 振幅偏移量)”
        // var y = -Math.sin((sX + x) * waveWidth);
        var y = -Math.sin((sX + x) * waveWidth);
        points.push([x, sY + y * waveHeight]);
       // ctx.lineTo(x, sY + y * waveHeight);     
    }
    //封閉路徑
    ctx.lineTo(axisLength, mH);
    ctx.lineTo(sX, mH);
    ctx.lineTo(points[0][0],points[0][1]);
    ctx.stroke();

    ctx.restore();
};
drawSin();
drawWave = function(){
  ctx.save();
  ctx.beginPath();
  for(var i=0;i<points.length;i++){
    let point = points[i];
    let x = point[0];
    let y = point[1];
    ctx.lineTo(x,y)
  }
  ctx.stroke();
}
var len = points.length;
// drawWave();

  drawPoint = function(x,y){
    ctx.fillRect(x,y,10,10)
    // ctx.lineTo(x,y)
    // ctx.stroke();
  }

var j = 0;

var render = function(){

  if(j >= len) {
      ctx.clearRect(0, 0, mW, mH);
      j =0;
  }
  var pop = points[j++]
  drawPoint(pop[0],pop[1]);
  requestAnimationFrame(render);
}
render()
  </script>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>canvas高級貝塞爾曲線運動動畫</title>
</head>

<body>
<script type="text/javascript ">
window.addEventListener('load',eventWindowLoaded,false);
function eventWindowLoaded(){
    canvasApp();
}
function canvasApp(){

    var pointImage = new Image();
    pointImage.src="point.jpg";

    function drawScreen(){
        //首先填充canvas的背景
        context.fillStyle = '#eee'
        context.fillRect(0,0,theCanvas.width,theCanvas.height);
        //邊框
        context.strokeStyle = '#eee'
        context.strokeRect(1,1,theCanvas.width,theCanvas.height);


//在這裏解釋下貝塞爾曲線,看網頁底部的那個點擊成Canvas三次貝塞爾曲線操作實例!你就會發現一個曲線是由4個點組成的,在下面有註釋

var t = ball.t;

        var cx = 3*(p1.x-p0.x);
        var bx = 3*(p2.x-p1.x)-cx;
        var ax = p3.x-p0.x-cx-bx;

        var cy = 3*(p1.y-p0.y);
        var by = 3*(p2.y-p1.y)-cy;
        var ay = p3.y-p0.y-cy-by;

        var xt = ax*(t*t*t)+bx*(t*t)+cx*t+p0.x;
        var yt = ay*(t*t*t)+by*(t*t)+cy*t+p0.y;
        //這裏的xt和yt貝塞爾曲線的公式,這裏涉及到一門叫做計算機圖形學的學科(大學裏面有上,我也最近一直在上)
        // 0 <= t <= 1這是一個T....學過圖形學的應該知道比如一根直線他的起始座標軸的位置(0,0)然後有DDA算法計算斜率,他也是一樣,具體的公式網上還是都有的,我的語言組織也不是很好-_-//


        ball.t +=ball.speed;

        if(ball.t>1){
            ball.t=1;
        }

        //繪製點
        context.font = "10px sans ";
        context.fillStyle = "#ff0000 ";
        context.beginPath();
        context.arc(p0.x,p0.y,8,0,Math.PI*2,true);
        context.closePath();
        context.fill();
        context.fillStyle = "#fff";
        context.fillText("0",p0.x-2,p0.y+2);


        //
        points.push({x:xt,y:yt});

        for(var i =0;i<points.length;i++){

            context.drawImage(pointImage,points[i].x,points[i].y,5,5);

        }
        //繪製圖片重點!!!!圖片,定位context.drawImage(img,x,y,width,height);也就是繪製那個點後的小點的軌跡

        context.closePath();

        context.fillStyle="#000000 ";
        context.beginPath();
        context.arc(xt,yt,5,0,Math.PI*2,true);
        context.closePath();
        context.fill();
    }
        var p0={x:60,y:10};//起始點
        var p1={x:70,y:200};//1號點
        var p2={x:125,y:295};//2號點
        var p3={x:350,y:350};//3號點
        var ball={x:0,y:0,speed:.01,t:0};
        var points=new Array();

        //這裏的起始點和3號點,我取得的名字比較通俗一下,實際上應該稱爲端點。因爲必須要經過的
        //1號點和2號點雖然可以刪除但是他控制着弧線的路徑,我們就叫他控制點

        theCanvas = document.getElementById('canvas')
        context = theCanvas.getContext("2d")

        setInterval(drawScreen,33);




}
</script>
<canvas id="canvas" width="800 " height="800 ">
你的瀏覽器無法使用canvas
小白童鞋;你的支持是我最大的快樂!!
</canvas>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章