h5新增標簽canvas0818

h5新增標簽canvas

1.基本概念

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>01-Canvas開篇</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                background: red;
            }
        </style>
    </head>
    <body>
    <!--1.在body中創建一個canvas標簽-->
    <!--
    注意點
    canvas標簽有默認的寬度和高度
    默認的寬度是300px
    默認的高度是150px
    -->
    <canvas></canvas>
    <script>
        /*
        1.什么是Canvas?
        Canvas是H5新增的一個標簽, 我們可以通過JS在這個標簽上繪制各種圖案
        Canvas 擁有多種繪制路徑、矩形、圓形、字符以及圖片的方法。
        * */
        // 2.通過js代碼拿到canvas標簽
        let oCanvas = document.querySelector("canvas");
        // 3.從canvas標簽中獲取到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        // 4.通過繪圖工具在canvas標簽上繪制圖形
        // 4.1設置路徑的起點
        oCtx.moveTo(50, 50);
        // 4.2設置路徑的終點
        oCtx.lineTo(200, 50);
        // 4.3告訴canvas將這些點連接起來
        oCtx.stroke();
    </script>
    </body>
    </html>
    

2.注意點

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>02-Canvas注意點</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                background: red;
                /*width: 500px;*/
                /*height: 500px;*/
            }
        </style>
    </head>
    <body>
    <!--1.創建一個畫布-->
    <canvas width="500" height="500"></canvas>
    <script>
        /*
        1.canvas有默認的寬度和高度
        默認寬300px, 高150px
        */
        /*
        2.不能通過CSS設置畫布的寬高
        通過CSS設置畫布寬高會在默認寬高的基礎上拉伸
        如果需要設置canvas寬高請通過元素行內屬性width和height設置
        */
        /*
        3.線條默認寬度和顏色
        通過canvas繪制的線條默認寬度是1px, 顏色是純黑色
        但是由于默認情況下canvas會將線條的中心點和像素的底部對齊,
        所以會導致顯示效果是2px和非純黑色問題,解決辦法就是加0.5或者減0.5
        * */
    
        // 2.拿到畫布
        let oCanvas = document.querySelector("canvas");
        // 3.拿到繪制工具
        let oCtx = oCanvas.getContext("2d");
        // 4.利用繪制工具繪制直線
        // 4.1設置起始位置
        oCtx.moveTo(50, 50.5);
        // 4.2設置路徑上的點
        oCtx.lineTo(200, 50.5);
        // 4.2繪制已定義的路徑
        oCtx.stroke();
    </script>
    </body>
    </html>
    

3.線條屬性

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>03-Canvas線條屬性</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                background: yellowgreen;
            }
        </style>
    </head>
    <body>
    <canvas></canvas>
    <script>
        /*
        1.線條相關屬性
        lineWidth: 線條寬度
        strokeStyle: 線條顏色
        lineCap: 線末端類型:(butt默認)、round、square
        * */
        let oCanvas = document.querySelector("canvas");
        let oCtx = oCanvas.getContext("2d");
        // 修改線條的高度
        oCtx.lineWidth = 50;
        // 修改線條的顏色
        oCtx.strokeStyle = "blue";
        // 修改線條的兩端樣式
        oCtx.lineCap = "round";
        oCtx.moveTo(50, 50);
        oCtx.lineTo(200, 50);
        oCtx.stroke();
    </script>
    </body>
    </html>
    

4.繪制多根線條

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>04-Canvas多根線條</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                background: yellowgreen;
            }
        </style>
    </head>
    <body>
    <canvas></canvas>
    <script>
        /*
        1.多根線條注意點
        如果是同一個路徑, 那么路徑樣式會被重用(第二次繪制會復用第一次的樣式)
        如果是同一個路徑, 那么后設置的路徑樣式會覆蓋先設置的路徑樣式
    
        2.如何給每根線條單獨設置路徑樣式?
        每根線條都開啟一個新的路徑即可
        * */
        let oCanvas = document.querySelector("canvas");
        let oCtx = oCanvas.getContext("2d");
        oCtx.moveTo(50, 50);
        oCtx.lineTo(200, 50);
        oCtx.lineWidth = 20;
        oCtx.strokeStyle = "blue";
        oCtx.stroke();
    
        oCtx.beginPath(); // 重新開啟一個路徑
        oCtx.moveTo(50, 100);
        oCtx.lineTo(200, 100);
        oCtx.lineWidth = 10; // 重新設置當前路徑樣式
        oCtx.strokeStyle = "red";
        oCtx.stroke();
    
        oCtx.beginPath(); // 重新開啟一個路徑
        oCtx.moveTo(50, 150);
        oCtx.lineTo(200, 150);
        oCtx.lineWidth = 15; // 重新設置當前路徑樣式
        oCtx.strokeStyle = "green";
        oCtx.stroke();
    </script>
    </body>
    </html>
    

5.簡單圖形

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>05-Canvas簡單圖形</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                display: block;
                margin: 0 auto;
                background: red;
            }
        </style>
    </head>
    <body>
    <canvas width="500" height="500"></canvas>
    <script>
        /*
        1.closePath
        自動創建從當前點回到起始點的路徑
    
        2.lineJoin
        設置相交線的拐點樣式 miter(默認)、round、bevel
        * */
        let oCanvas = document.querySelector("canvas");
        let oCtx = oCanvas.getContext("2d");
        oCtx.moveTo(50, 50);
        oCtx.lineTo(200, 50);
        oCtx.lineTo(200, 200);
        // 注意點: 如果通過lineTo來閉合圖形, 那么是不能很好的閉合
        // oCtx.lineTo(50, 50);
        oCtx.closePath();
        oCtx.lineWidth = 20;
        oCtx.lineJoin = "round";
        // 注意點: 默認情況下不會自動從最后一個點連接到起點
        oCtx.stroke();
    </script>
    </body>
    </html>
    

6.填充圖形

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>06-Canvas填充圖形</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                display: block;
                margin: 0 auto;
                background: red;
            }
        </style>
    </head>
    <body>
    <canvas width="500" height="500"></canvas>
    <script>
        /*
         1.stroke
        繪制已定義的路徑
    
        2.fill
        填充已定義的路徑
        */
        let oCanvas = document.querySelector("canvas");
        let oCtx = oCanvas.getContext("2d");
        
        oCtx.moveTo(100, 100);
        oCtx.lineTo(300, 100);
        oCtx.lineTo(300, 300);
        oCtx.lineTo(100, 300);
        oCtx.closePath();
        // oCtx.stroke();
    
        // oCtx.beginPath();
        /*
       oCtx.moveTo(150, 150);
       oCtx.lineTo(250, 150);
       oCtx.lineTo(250, 250);
       oCtx.lineTo(150, 250);
      */
       oCtx.moveTo(250, 150);
       oCtx.lineTo(150, 150);
       oCtx.lineTo(150, 250);
       oCtx.lineTo(250, 250);
    
        oCtx.closePath();
        /*
        注意點: 只要沒有手動開啟新的路徑, 那么使用的都是默認路徑
        如果都是默認路徑, 那么設置的樣式在同一個路徑中都是有效的
        * */
        // oCtx.strokeStyle = "blue";
        // oCtx.stroke();
        oCtx.fill();
        /*
        對于同一路徑,在填充的時候回遵循非零環繞規則
        從當前的區域拉出一條直線, 遇到順時針相交的線就+1, 遇到逆時針相交的線就-1
        最終計算的結果如何是0就不填充, 如果不是0就填充 
        所以上面那兩個填充的時候,里面的不會填充
        * */
    </script>
    </body>
    </html>
    

7.繪制虛線

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>07-Canvas虛線</title>
        <style>
            *{
                margin: 0px;
                padding: 0;
            }
            canvas{
                display: block;
                margin: 0 auto;
                background: red;
            }
        </style>
    </head>
    <body>
    <canvas width="500" height="500"></canvas>
    <script>
        let oCanvas = document.querySelector("canvas");
        let oCtx = oCanvas.getContext("2d");
        oCtx.moveTo(100, 100);
        oCtx.lineTo(400, 100);
        oCtx.lineWidth = 20;
        oCtx.strokeStyle = "blue";
        // oCtx.setLineDash([5, 20]);
        oCtx.setLineDash([5, 10, 20]);
        console.log(oCtx.getLineDash());
        oCtx.lineDashOffset = -50;
        oCtx.stroke();
        /*
        1.setLineDash
        [5,10] 數組是用來描述你的排列方式的
    
        2.getLineDash
        獲取虛線的排列方式 獲取的是不重復的那一段的排列方式
    
        3.lineDashOffset
        設置虛線的偏移位
        * */
    
    </script>
    </body>
    </html>
    

8.繪制表格

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>08-Canvas繪制表格</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                display: block;
                margin: 0 auto;
                background: red;
            }
        </style>
    </head>
    <body>
    <canvas width="500" height="400"></canvas>
    <script>
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        // 3.定義變量保存小方格的尺寸
        let gridSize = 50;
        // console.log(oCanvas.offsetWidth);
        // console.log(oCanvas.offsetHeight);
        // console.log(oCtx.canvas.width);
        // console.log(oCtx.canvas.height);
        //canvas里面就有獲取寬高的屬性,oCtx.canvas.width,所以就不用offsetWidth了
        // 4.拿到canvas的寬高
        let canvasWidth = oCtx.canvas.width;
        let canvasHeight = oCtx.canvas.height;
        // 5.計算在垂直方向和水平方向可以繪制多少條橫線
        let row = Math.floor(canvasHeight / gridSize);
        let col = Math.floor(canvasWidth / gridSize);
        // 6.繪制垂直方向的橫線
        for(let i = 0; i < row; i++){
            oCtx.beginPath();
            oCtx.moveTo(0, i * gridSize - 0.5);
            oCtx.lineTo(canvasWidth, i * gridSize - 0.5);
            oCtx.strokeStyle = "#ccc";
            oCtx.stroke();
        }
        // 7.繪制水平方向的橫線
        for(let i = 0; i < col; i++){
            oCtx.beginPath();
            oCtx.moveTo(i * gridSize - 0.5, 0);
            oCtx.lineTo(i * gridSize - 0.5, canvasHeight);
            oCtx.strokeStyle = "#ccc";
            oCtx.stroke();
        }
    </script>
    </body>
    </html>
    

9.繪制坐標系

  • //在上面繪制好表格的基礎上
    // 1.計算坐標系原點的位置
     let originX = gridSize;
     let originY = canvasHeight - gridSize;
     // 2.計算X軸終點的位置
     let endX = canvasWidth - gridSize;
     // 3.繪制X軸
     oCtx.beginPath();
     oCtx.moveTo(originX, originY);
     oCtx.lineTo(endX, originY);
     oCtx.strokeStyle = "#000";
     oCtx.stroke();
     // 4.繪制X軸的箭頭
     oCtx.lineTo(endX - 10, originY + 5);
     oCtx.lineTo(endX - 10, originY - 5);
     oCtx.lineTo(endX, originY);
     oCtx.fill();
    
     // 5.計算Y軸終點的位置
     let endY = gridSize;
     // 3.繪制Y軸
     oCtx.beginPath();
     oCtx.moveTo(originX, originY);
     oCtx.lineTo(originX, endY);
     oCtx.strokeStyle = "#000";
     oCtx.stroke();
     // 4.繪制Y軸的箭頭
     oCtx.lineTo(originX - 5, endY + 10);
     oCtx.lineTo(originX + 5, endY + 10);
     oCtx.lineTo(originX, endY);
     oCtx.fill();
    

10.繪制數據點

  • //在上面的基礎上
    // 1.拿到服務器返回數據
        let list = [
            {
                x: 100,
                y: 300
            },
            {
                x: 200,
                y: 200
            },
            {
                x: 300,
                y: 250
            },
            {
                x: 400,
                y: 100
            },
        ];
        let dotLocation = {
            x: 100,
            y: 300
        }
        let dotSize = 20;
        /*
        // 2.繪制數據點
        oCtx.beginPath();
        oCtx.moveTo(dotLocation.x - dotSize / 2, dotLocation.y - dotSize / 2);
        oCtx.lineTo(dotLocation.x + dotSize - dotSize / 2, dotLocation.y - dotSize / 2);
        oCtx.lineTo(dotLocation.x + dotSize - dotSize / 2, dotLocation.y + dotSize - dotSize / 2);
        oCtx.lineTo(dotLocation.x - dotSize / 2, dotLocation.y + dotSize - dotSize / 2);
        oCtx.closePath();
        oCtx.fill();
        */
        for(let i = 0; i < list.length; i++){
            oCtx.beginPath();
            oCtx.moveTo(list[i].x - dotSize / 2, list[i].y - dotSize / 2);
            oCtx.lineTo(list[i].x + dotSize - dotSize / 2, list[i].y - dotSize / 2);
            oCtx.lineTo(list[i].x + dotSize - dotSize / 2, list[i].y + dotSize - dotSize / 2);
            oCtx.lineTo(list[i].x - dotSize / 2, list[i].y + dotSize - dotSize / 2);
            oCtx.closePath();
            oCtx.fill();
        }
    

11.繪制折線圖

  • // 1.繪制折線
    oCtx.beginPath();
    for(let i = 0; i < list.length; i++){
        if(i === 0){
            oCtx.moveTo(list[i].x, list[i].y);
        }else{
            oCtx.lineTo(list[i].x, list[i].y);
        }
    }
    oCtx.stroke();
    

12.繪制矩形

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>13-Canvas繪制矩形</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                display: block;
                margin: 0 auto;
                background: red;
            }
        </style>
    </head>
    <body>
    <canvas width="500" height="400"></canvas>
    <script>
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        /*
        第一個參數: x的坐標
        第二個參數: y的坐標
        第三個參數: 矩形的寬度
        第四個參數: 矩形的高度
       */
       
        oCtx.rect(100, 100, 200, 200);
        oCtx.stroke();
        oCtx.fill();
      //還可以直接繪制填充的
        oCtx.fillRect(100, 100, 200, 200);
      
        //以下為清除繪制的圖形
    
       let canvasWidth = oCtx.canvas.width;
       let canvasHeight = oCtx.canvas.height;
       oCtx.clearRect(0, 0, canvasWidth, canvasHeight);
    </script>
    </body>
    </html>
    

13.繪制柱狀圖

  • //繪制好坐標系后
    // 1.拿到服務器返回數據
    let list = [
        {
            x: 100,
            y: 300
        },
        {
            x: 200,
            y: 200
        },
        {
            x: 300,
            y: 250
        },
    ];
    let data = {
        x: 100,
        y: 300
    }
    // 2.繪制矩形
    for(let i = 0; i < list.length; i++){
        let barHeight = originY - list[i].y;
        oCtx.fillRect(list[i].x, list[i].y, gridSize, barHeight);
    }
    

14.繪制漸變色

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>15-Canvas漸變色</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                display: block;
                margin: 0 auto;
                background: red;
            }
        </style>
    </head>
    <body>
    <canvas width="500" height="400"></canvas>
    <script>
        /*
        1.漸變背景顏色
        和普通的標簽一樣我們也可以給填充的圖形設置線性漸變和徑向漸變的背景顏色
    
        2.設置圖形漸變背景顏色步驟
        2.1通過繪圖工具創建漸變背景顏色
        2.2指定漸變的范圍
        2.3將漸變背景顏色設置給對應的圖形
        * */
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
    
        // 1.創建一個漸變的方案
        /*
        可以通過x0,y0 / x1,y1確定漸變的方向和漸變的范圍
        * */
        let linearGradient = oCtx.createLinearGradient(100, 100, 300, 300);
        /*
        第一個參數是一個百分比 0~1
        第二個參數是一個顏色
        * */
        linearGradient.addColorStop(0, "green");
        linearGradient.addColorStop(0.5, "yellow");
        linearGradient.addColorStop(1, "blue");
    
        // oCtx.createRadialGradient();
        // oCtx.fillStyle = "blue";
        oCtx.fillStyle = linearGradient;
        oCtx.fillRect(100, 100, 200, 200);
    </script>
    </body>
    </html>
    

15.繪制圓弧

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>16-Canvas繪制圓弧</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                display: block;
                margin: 0 auto;
                background: red;
            }
        </style>
    </head>
    <body>
    <canvas width="500" height="400"></canvas>
    <script>
        /*
        1.基本概念(請翻開初中數學課本)
        角度: 一個圓360度, 一個半圓是180度
        弧度: 一個圓2π, 一個半圓π
    
        2.角度轉換弧度公式:
        ∵ 180角度 = π弧度
        ∴ 1角度 = π/180;
        ∴ 弧度 = 角度 * π/180;
           90角度 * π/180 = π/2
    
        3.弧度轉換角度公式:
        ∵ π弧度 = 180角度
        ∴ 1弧度 = 180/π
        ∴ 角度 = 弧度 * 180/π
           π/2 * 180/π = 180/2 = 90度
        * */
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        /*
        x, y: 確定圓心
        radius: 確定半徑
        startAngle: 確定開始的弧度
        endAngle: 確定結束的弧度
        Boolean: 默認是false, false就是順時針繪制, true就是逆時針繪制
        context.arc(x, y, radius, startAngle, endAngle, Boolean);
        * */
        // oCtx.arc(100, 100, 100, 0, Math.PI);
        // oCtx.arc(100, 100, 100, 0, Math.PI, true);
        oCtx.arc(100, 100, 100, 0, Math.PI * 2);
        oCtx.stroke();
    </script>
    </body>
    </html>
    

16.繪制扇形

  • <script>
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        oCtx.moveTo(100, 100);
        oCtx.arc(100, 100, 100, 0, Math.PI/2);
        oCtx.closePath();
        // oCtx.stroke();
        oCtx.fill();
    </script>
    

17.繪制文字

  • <script>
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        // 3.繪制參考線
        let canvasWidth = oCtx.canvas.width;
        let canvasHeight = oCtx.canvas.height;
        oCtx.moveTo(0, canvasHeight/2);
        oCtx.lineTo(canvasWidth, canvasHeight/2);
        oCtx.stroke();
        oCtx.moveTo(canvasWidth/2, 0);
        oCtx.lineTo(canvasWidth/2, canvasHeight);
        oCtx.stroke();
        // 4.繪制文字
        let str = "知播漁教育";
        // 通過font屬性可以設置文字的大小和樣式
        oCtx.font = "50px 微軟雅黑";
        // 通過textBaseline屬性可以設置文字垂直方向的對齊方式
        // 注意點: 在對齊的時候是以繪制文字的y作為參考點進行對齊的
        oCtx.textBaseline = "middle";
        // 通過textAlign屬性可以設置文字水平方向的對齊方式
        // 注意點: 在對齊的時候是以繪制文字的x作為參考點進行對齊的
        oCtx.textAlign = "center";
        /*
        注意點:
        在繪制文字的時候, 是以文字的左下角作為參考點進行繪制
        * */
        //以下一個是填充,一個不填充
        // oCtx.strokeText(str, canvasWidth/2, canvasHeight/2);
        oCtx.fillText(str, canvasWidth/2, canvasHeight/2);
    
        // oCtx.fillRect(canvasWidth/2, canvasHeight/2, 100, 100);
    </script>
    

18.繪制圖片

  • <script>
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        // 3.加載圖片
        let oImg = new Image();
        oImg.onload = function () {
            // 如果只有三個參數, 那么第一個參數就是需要繪制的圖片
            // 后面的兩個參數是指定圖片從什么位置開始繪制
            // oCtx.drawImage(oImg, 100, 100);
    
            // 如果只有五個參數, 那么第一個參數就是需要繪制的圖片
            // 后面的兩個參數是指定圖片從什么位置開始繪制
            // 最后的兩個參數是指定圖片需要拉伸到多大
            // oCtx.drawImage(oImg, 100, 100, 100, 100);
    
            // 如果有九個參數, 那么第一個參數就是需要繪制的圖片
            // 最后的兩個參數是指定圖片需要拉伸到多大
            // 第6~7個參數指定圖片從什么位置開始繪制
            // 第2~3個參數指定圖片上定位的位置
            // 第4~5個參數指定從定位的位置開始截取多大的圖片
            oCtx.drawImage(oImg, 50, 50, 100, 100, 100, 100, 100, 100);
        }
        oImg.src = "images/lnj.jpg";
    </script>
    

19.逐幀動畫

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>23-Canvas幀動畫</title>
        <style>
            *{
                margin: 0;
                padding: 0;
            }
            canvas{
                display: block;
                margin: 0 auto;
                background: red;
            }
        </style>
    </head>
    <body>
    <canvas width="500" height="400"></canvas>
    <script>
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        /*
        面向對象思想:
        找到小人對象, 你給我畫到指定的位置, 你給我走起來, 你給我停下來
        * */
        class Person{
            constructor(canvas, x, y){
                this.canvas = canvas;
                this.x = x;
                this.y = y;
                this.oCtx = canvas.getContext("2d");
                this.index = 1;
                this.timerId = null;
                // 0正面/1左面/2右面/3后面
                this.direction = 0;
            }
            render(){
                let oImg = new Image();
                oImg.onload = () => {
                    // 1.計算每一張圖片的寬高
                    let imageWidth = oImg.width;
                    let imageHeight = oImg.height;
                    let personWidth = imageWidth / 4;
                    let personHeight = imageHeight / 4;
                    // 2.繪制圖片
                    this.oCtx.drawImage(
                        oImg, // 需要繪制的圖片
                        0, this.direction * personHeight, // 圖片定位的位置
                        personWidth, personHeight, // 圖片裁剪的大小
                        this.x, this.y, // 圖片繪制的位置
                        personWidth, personHeight // 指定圖片繪制的大小
                    );
                    this.oImg= oImg;
                    this.personWidth = personWidth;
                    this.personHeight = personHeight;
                }
                oImg.src = "images/person.png";
            }
            run(stepX, stepY){
                let canvasWidth = this.oCtx.canvas.width;
                let canvasHeight = this.oCtx.canvas.height;
                clearInterval(this.timerId);
                this.timerId = setInterval(() => {
                    if(stepX !== 0){
                        this.x += stepX;
                    }
                    if(stepY !== 0){
                        this.y += stepY;
                    }
                    this.oCtx.clearRect(0, 0, canvasWidth, canvasHeight);
                    this.oCtx.drawImage(
                        this.oImg, // 需要繪制的圖片
                        this.index * this.personWidth, this.direction * this.personHeight, // 圖片定位的位置
                        this.personWidth, this.personHeight, // 圖片裁剪的大小
                        this.x, this.y, // 圖片繪制的位置
                        this.personWidth, this.personHeight // 指定圖片繪制的大小
                    );
                    this.index++;
                    if(this.index > 3){
                        this.index = 0;
                    }
                }, 500);
            }
            moveDown(){
                this.direction = 0;
                this.run(0, 5);
            }
            moveUp(){
                this.direction = 3;
                this.run(0, -5);
            }
            moveLeft(){
                this.direction = 1;
                this.run(-5, 0);
            }
            moveRight(){
                this.direction = 2;
                this.run(5, 0);
            }
            stop(){
                clearInterval(this.timerId);
            }
        }
        let person = new Person(oCanvas, 100, 100);
        person.render();
        person.moveDown();
        // person.run(0, 5);
        // person.run(0, -5);
        // person.run(-5, 0);
        // person.run(5, 0);
        // person.moveRight();
        // person.stop();
    
        window.onkeydown = function (event) {
            let key = event.key;
            // console.log(key);
            switch (key.toLowerCase()){
                case "w":
                    person.moveUp();
                    break;
                case "s":
                    person.moveDown();
                    break;
                case "a":
                    person.moveLeft();
                    break;
                case "d":
                    person.moveRight();
                    break;
            }
        }
    </script>
    </body>
    </html>
    

20.形變

  • <script>
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        // 注意點: 在canvas中所有的形變屬性操作的都是坐標系, 而不是圖形
        // oCtx.translate(100, 0);
        // oCtx.translate(0, 100);
        // oCtx.translate(100, 100);
    
        // oCtx.rotate(Math.PI/6);
    
        oCtx.scale(0.5, 1);
        // 3.繪制一個矩形
        oCtx.strokeRect(100, 100, 200, 100);
    </script>
    

21.事件監聽

  • <script>
        /*
        因為整個canvas是一個標簽, 所以只能通過監聽鼠標在canvas上的位置來判斷是否需要處理對應的圖形
        當然也可以通過第三方框架來解決交互問題
        諸如: zrender.js / Knova.js /three.js / egret.js / pixi.js等等
        * */
        // 1.拿到canvas
        let oCanvas = document.querySelector("canvas");
        // 2.從canvas中拿到繪圖工具
        let oCtx = oCanvas.getContext("2d");
        // 3.繪制矩形
        let rectX = 100;
        let rectY = 100;
        let rectWidth = 100;
        let rectHeight = 100;
        oCtx.rect(rectX, rectY, rectWidth, rectHeight);
        oCtx.fill();
    
        oCtx.beginPath();
        oCtx.rect(200, 200, 100, 100);
        oCtx.fill();
        // 4.添加點擊事件
        oCanvas.onclick = function (event) {
            let x = event.offsetX;
            let y = event.offsetY;
            /*
            if(x >= rectX && x <= rectX + rectWidth &&
                y >= rectY && y <= rectY + rectHeight){
                console.log("矩形被點擊了");
            }else{
                console.log("矩形沒有被點擊");
            }
            */
            /*
            注意點:
            isPointInPath方法如果開啟了一個新的路徑, 那么判斷的就是點是否在新的路徑的圖形中
            * */
            console.log(oCtx.isPointInPath(x, y));
        }
    </script>
    
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容