CanvasDay07 使用其他HMTL元素,擴展Canvas的方法,Canvas與瀏覽器的兼容性,Canvas圖形庫推薦

目錄

0x00 在Canvas中使用其他HMTL 元素

0x01 擴展Canvas的context對象

0x02 Canvas與瀏覽器兼容性

0x03 Canvas圖形庫


0x00 在Canvas中使用其他HMTL 元素

canvas本身並不是透明的,默認背景色爲白色。

如果將一個html標籤,放在了canvas標籤之前,即便是我們對該標籤進行了絕對定位,那麼該標籤也有可能被canvas遮擋住

建議將浮動在canvas之上的標籤放在canvas之後。

同時也可以通過z-index屬性來調整不同的div在z軸方向的先後順序

案例:

效果:

代碼:

<!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>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet">
    <style>

        #canvas-wrapper{
            position: absolute;;
            top:50%;
            left:50%;
            transform: translate(-50%,-50%);
            width:1024px;
            height:650px;
            
        }

        #controller{
            position:absolute;
            top:30px;
            left:30px;
            width:200px;
            border-radius:10px;
            padding:15px;
            background: rgba(0,85,116,0.7);
            color:#fff;
        }
        .btn-black{
            background:black;
        }
        .btn-white{
            background:white;
        }
    </style>
</head>
<body>
<div id='canvas-wrapper'>
        <canvas id='canvas'></canvas>
        <div id="controller">
            <h4>Canvas 控制面板</h4>
            <a href="javascript:;" id='canvas-btn' class='btn btn-danger'>停止運動</a>
            <a href="javascript:;" id='black-color-btn' class='btn btn-black'>&nbsp;&nbsp;&nbsp;</a>
            <a href="javascript:;" id='white-color-btn' class='btn btn-white'>&nbsp;&nbsp;&nbsp;</a>
        </div>
</div>

</body>
<script>

    var themeColor = 'white';
    var isMoving = true;
window.onload = function(){
    var canvas = document.getElementById('canvas');
    canvas.width=1024;
    canvas.height=650;

    var ctx = canvas.getContext('2d');
    ctx.globalAlpha = 1;
    ctx.globalCompositeOperation='xor';
    balls = [];

    for(var i=0;i<100;i++){
        var R = Math.floor(Math.random()*255);
        var G = Math.floor(Math.random()*255);
        var B = Math.floor(Math.random()*255);

        var color = "rgba("+R+","+G+","+B+")";
        var ball = {
            x:Math.random()*canvas.width,
            y:Math.random()*canvas.height,
            r:Math.random()*100,
            vx:Math.random()*20,
            vy:Math.random()*20,
            c:color
        }
       balls.push(ball);
    }
    setInterval(function(){
        render(ctx);
        if(isMoving){
            update(ctx);
        }
    },50)

    document.getElementById('canvas-btn').onclick = function(){
        if(isMoving){
            isMoving = false;
            this.text = "開始運動";
        }else{
            isMoving = true;
            this.text = "停止運動";
        }
        return false;
    }
    document.getElementById('white-color-btn').onclick = function(){
        themeColor = "white";
        return false; 
    }
    document.getElementById('black-color-btn').onclick = function(){
        themeColor = "black";
        return false;
    }
    
}
function render(ctx){
    ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
    // console.log(ctx.canvas.height);

    if(themeColor == "black"){
        ctx.fillStyle = "black";
        ctx.fillRect(0,0,canvas.width,canvas.height);
    }
    for(var i=0;i<balls.length;i++){
        ctx.beginPath();
        ctx.fillStyle = balls[i].c;
        ctx.arc(balls[i].x,balls[i].y,balls[i].r,0,Math.PI * 2);
        ctx.closePath();
        ctx.fill();
    }
}

function update(ctx){
    for(var i =0;i<balls.length;i++){
        balls[i].x += balls[i].vx;
        balls[i].y += balls[i].vy;
        // 碰撞檢測
        // 下邊緣碰撞檢測
        if(balls[i].y >= ctx.canvas.height - balls[i].r){
            balls[i].y  = ctx.canvas.height - balls[i].r;
            balls[i].vy = -balls[i].vy*0.5;//每次反彈都會損失能量
        }
        if(balls[i].y <= 0 +balls[i].r){
            balls[i].y = 0+balls[i].r;
            balls[i].vy = -balls[i].vy;
        }
        if(balls[i].x <= 0+balls[i].r){
            balls[i].x = 0+balls[i].r;
            balls[i].vx = -balls[i].vx;
        }
        if(balls[i].x >= ctx.canvas.width-balls[i].r){
            balls[i].x = ctx.canvas.width-balls[i].r;
            balls[i].vx = - balls[i].vx;
        }
    }
}

</script>


</html>

0x01 擴展Canvas的context對象

我們可以將我們自己寫的函數添加給

CanvasRenderingContext.prototype,使之成爲ctx的一個接口

CanvasRenderingContext 就是我們獲取的context對象,所以我們需要將函數中的ctx 全部修改爲this

代碼:

   window.onload=function(){
        var canvas = document.getElementById('canvas');
    
        canvas.width = document.body.clientWidth;
        canvas.height =document.body.clientHeight;

        var ctx = canvas.getContext('2d');
        /**
        * 規劃彎月的路徑
        * 
        */
        CanvasRenderingContext2D.prototype.pathMoon=function(d){
            this.beginPath();
            this.arc(0,0,1,0.5*Math.PI,1.5*Math.PI,true);
            this.moveTo(0,-1);
            this.quadraticCurveTo(1.2,0,0,1);
            this.closePath();
        }
        /**
        * 繪製一輪填充的彎月
        * @ d 控制點座標的橫座標值
        * @ x,y  彎月的位置
        * @ R 彎月的半徑
        * @ rot 旋轉角度 角度值
        * @ fillColor 可選
        */
        CanvasRenderingContext2D.prototype.fillMoon = function(d,x,y,R,rot,fillColor){
                this.save();
                this.translate(x,y);
                this.rotate(rot * Math.PI / 180);
                this.scale(R,R);
                this.pathMoon(d);
                this.fillStyle = fillColor || "#fb5";
                this.fill();
                this.restore();
        }
        //黑夜
        var skyStyle =  ctx.createLinearGradient(0,0,0,canvas.height);
        skyStyle.addColorStop(0.0,'black');
        skyStyle.addColorStop(1.0,'#035');
        ctx.fillStyle = skyStyle;
        ctx.fillRect(0,0,canvas.width,canvas.height);
        //200個星星
        for(var i=0;i<40;i++){
            var r = Math.random() * 5 + 2; //2 - 7之間的隨機值
            var x = Math.random() * canvas.width;
            var y = Math.random() * canvas.height / 3;
            var rot = Math.random() * 360;
            drawStar(ctx,r,x,y,rot);
        }
        //繪製月亮
        ctx.fillMoon(2,900,200,100,30);
        //繪製綠地
        drawLand(ctx);
    }
    /**
    * 產生一個標準星星的路徑
    * 一個位於(0,0)點 外圓半徑爲1,內圓半徑爲0.5的星星
    * 
    */
    function starPath(ctx){
        var R = 1;
        var r = 0.5 * R;
        var rot =0;
        var x = 0;
        var y =0;

        ctx.beginPath();
        for(var i=0;i<5;i++){
            // 大圓半徑爲300 ,平移400px
            ctx.lineTo( 
                Math.cos((18 +i*72 - rot)*Math.PI/180)*R + x,
                -Math.sin((18 +i*72 - rot )*Math.PI/180)*R + y
            );
            //小圓半徑爲150,平移400px;
            ctx.lineTo( 
                Math.cos((54 +i*72 - rot)*Math.PI/180)*r +x,
                -Math.sin((54 +i*72 - rot)*Math.PI/180)*r +y
            );
        } 
        ctx.closePath(); 
    }
    /**
     * 繪製一個五角星
     * ctx 上下文
     * r 小圓半徑
     * x x軸方向上的平移
     * y y軸方向上的平移
     * rot 順時針旋轉角度
    */
    function  drawStar( ctx,r,x,y,rot){
        ctx.save();
        //因爲 我們左上角座標是0,0,所以scale不會改變左上角的座標
        ctx.translate(x,y);
        ctx.rotate(rot * Math.PI/180);
        ctx.scale(r,r);
        starPath(ctx);
      
        ctx.lineJoin = 'round';
        ctx.fillStyle = '#fb3';
        ctx.strokeStyle = '#fd5'; 
        ctx.fill();
        ctx.restore();

   }


// 計算兩點間的距離
function dis(x1,y1,x2,y2){
    return Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
function drawLand(ctx){
    ctx.save();
    ctx.beginPath();
    ctx.moveTo(0,600);
    ctx.bezierCurveTo(540,400,660,800,document.body.clientWidth,600);
    ctx.lineTo(document.body.clientWidth,document.body.clientHeight);
    ctx.lineTo(0,document.body.clientHeight);
    ctx.closePath();
    var landStyle = ctx.createLinearGradient(0,800,0,0);
    landStyle.addColorStop(0.0,'#030');
    landStyle.addColorStop(1.0,'#580');
    ctx.fillStyle=landStyle;
    ctx.fill();
    ctx.restore();
    
}

0x02 Canvas與瀏覽器兼容性

通過if(ctx.函數名) 可以判斷瀏覽器是否支持該函數

0x03 Canvas圖形庫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章