美文网首页让前端飞
【Tank】1.0 canvas-基础使用

【Tank】1.0 canvas-基础使用

作者: bobokaka | 来源:发表于2022-05-09 01:07 被阅读0次

    1.0 新建一个项目tank,新建一个文件1.html。

    image.png
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <canvas id="canvas"></canvas>
    </body>
    </html>
    

    canvas就是渲染一个画布。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <canvas id="canvas"></canvas>
    <script>
        //获取dom节点
        const el = document.querySelector("#canvas")
        // 得到一个对象
        const app = el.getContext("2d")
        console.log(app)
    </script>
    </body>
    </html>
    
    image.png

    操作步骤

    1.颜料 线 贴图(图片)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <canvas id="canvas" width="300" height="300"></canvas>
    <script>
        //获取dom节点
        const el = document.querySelector("#canvas")
        // 得到一个对象
        const app = el.getContext("2d")
        console.log(app)
        // 1.颜料 线 贴图(图片)
        // 2. 画
    
        app.fillStyle = "red"
        app.fillRect(0, 0, 300,300)
    </script>
    </body>
    </html>
    
    image.png

    TS支撑

    为了提供类型提示,这里采用脚手架进行(vite)。

    yarn create vite
    
    image.png

    vite脚手架可以选择不同语言的模板,这里选用经典的 vanilla。


    image.png

    安装依赖。

    yarn install
    

    修改index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <link rel="icon" type="image/svg+xml" href="favicon.svg" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Vite App</title>
      </head>
      <body>
        <div id="app"></div>
        <canvas id="canvas"></canvas>
        <script type="module" src="/src/main.ts"></script>
      </body>
    </html>
    
    image.png
    npm run dev
    
    image.png

    canvas

    修改src/main.ts

    // @ts-ignore
    const el: HTMLCanvasElement = document.querySelector<HTMLCanvasElement>("#canvas")
    
    const app = el?.getContext("2d")
    
    // 1.颜料 线 贴图(图片)
    // 2. 画
    // @ts-ignore
    app.fillStyle = "#80e737"
    // 画一个矩形
    // @ts-ignore
    app.fillRect(0, 0, 300, 300)
    
    
    // @ts-ignore
    app.fillStyle = "#16a085"
    // 画一个矩形
    // @ts-ignore
    app.fillRect(el.width / 2 - 50, el.height / 2 - 50, 100, 100)
    

    修改.html

    ......
        <canvas id="canvas" width="300" height="300"></canvas>
    ......
    
    image.png

    所以,整个使用流程就是:堆颜料,画->堆颜料,画

    深入练习

    // @ts-ignore
    const el: HTMLCanvasElement = document.querySelector<HTMLCanvasElement>("#canvas")
    
    const app = el?.getContext("2d")
    
    // 1.颜料 线 贴图(图片)
    // 2. 画
    // @ts-ignore
    // app.fillStyle = "#80e737"
    // // 画一个矩形
    // // @ts-ignore
    // app.fillRect(0, 0, 300, 300)
    //
    //
    // // @ts-ignore
    // app.fillStyle = "#16a085"
    // // 画一个矩形
    // // @ts-ignore
    // app.fillRect(el.width / 2 - 50, el.height / 2 - 50, 100, 100)
    // @ts-ignore
    app.strokeStyle = "#8e44ad"
    //调整线的宽度
    // @ts-ignore
    app.lineWidth=30
    //线条交汇的边角
    // @ts-ignore
    app.lineJoin='round'
    // 画一个矩形线条
    // @ts-ignore
    app.strokeRect(50,50,200,200)
    
    image.png
    // @ts-ignore
    const el: HTMLCanvasElement = document.querySelector<HTMLCanvasElement>("#canvas")
    
    const app = el?.getContext("2d")
    
    // 1.颜料 线 贴图(图片)
    // 2. 画
    // ******************* 填充矩形 ******************
    // @ts-ignore
    // app.fillStyle = "#80e737"
    // // 画一个矩形
    // // @ts-ignore
    // app.fillRect(0, 0, 300, 300)
    //
    //
    // // @ts-ignore
    // app.fillStyle = "#16a085"
    // // 画一个矩形
    // // @ts-ignore
    // app.fillRect(el.width / 2 - 50, el.height / 2 - 50, 100, 100)
    // ******************* 填充矩形 ******************
    
    // ******************* 矩形边 ******************
    // @ts-ignore
    // app.strokeStyle = "#8e44ad"
    // //调整线的宽度
    // // @ts-ignore
    // app.lineWidth=30
    // //线条交汇的边角
    // // @ts-ignore
    // app.lineJoin='round'
    // // 画一个矩形线条
    // // @ts-ignore
    // app.strokeRect(50,50,200,200)
    // ******************* 矩形边 ******************
    
    // ******************* 圆 ******************
    // @ts-ignore
    app.fillStyle = "#16a085"
    // @ts-ignore
    app.strokeStyle = "red"
    // @ts-ignore
    app.lineWidth=20
    
    // @ts-ignore
    app.arc(100,100,50,0,2*Math.PI)
    // 绘制
    // @ts-ignore
    app.stroke();
    // @ts-ignore
    app.fill();
    // ******************* 圆 ******************
    
    image.png
    // @ts-ignore
    const el: HTMLCanvasElement = document.querySelector<HTMLCanvasElement>("#canvas")
    
    const app = el?.getContext("2d")
    
    // 1.颜料 线 贴图(图片)
    // 2. 画
    // ******************* 填充矩形 ******************
    // @ts-ignore
    // app.fillStyle = "#80e737"
    // // 画一个矩形
    // // @ts-ignore
    // app.fillRect(0, 0, 300, 300)
    //
    //
    // // @ts-ignore
    // app.fillStyle = "#16a085"
    // // 画一个矩形
    // // @ts-ignore
    // app.fillRect(el.width / 2 - 50, el.height / 2 - 50, 100, 100)
    // ******************* 填充矩形 ******************
    
    // ******************* 矩形边 ******************
    // @ts-ignore
    // app.strokeStyle = "#8e44ad"
    // //调整线的宽度
    // // @ts-ignore
    // app.lineWidth=30
    // //线条交汇的边角
    // // @ts-ignore
    // app.lineJoin='round'
    // // 画一个矩形线条
    // // @ts-ignore
    // app.strokeRect(50,50,200,200)
    // ******************* 矩形边 ******************
    
    // ******************* 圆 ******************
    // @ts-ignore
    // app.fillStyle = "#16a085"
    // // @ts-ignore
    // app.strokeStyle = "red"
    // // @ts-ignore
    // app.lineWidth=20
    //
    // // @ts-ignore
    // app.arc(100,100,50,0,2*Math.PI)
    // // 绘制
    // // @ts-ignore
    // app.stroke();
    // // @ts-ignore
    // app.fill();
    // ******************* 圆 ******************
    
    // ******************* 三角形 ******************
    // 开始一条路径,或重置当前的路径
    // @ts-ignore
    app.beginPath()
    // 把路径移动到画布中的指定点,不创建线条
    // @ts-ignore
    app.moveTo(el.width/2,10)
    // @ts-ignore
    app.lineTo(el.width-10,222)
    // @ts-ignore
    app.lineTo(10,222)
    // 闭合路径,创建从当前点到开始点的路径
    // @ts-ignore
    app.closePath()
    
    // @ts-ignore
    app.strokeStyle = "red"
    // @ts-ignore
    app.lineWidth=2
    // @ts-ignore
    app.stroke();
    // ******************* 三角形 ******************
    
    image.png

    渐变颜色的实现

    // @ts-ignore
    const el: HTMLCanvasElement = document.querySelector<HTMLCanvasElement>("#canvas")
    
    const app = el?.getContext("2d")
    
    // 1.颜料 线 贴图(图片)
    // 2. 画
    // ******************* 填充矩形 ******************
    // @ts-ignore
    // app.fillStyle = "#80e737"
    // // 画一个矩形
    // // @ts-ignore
    // app.fillRect(0, 0, 300, 300)
    //
    //
    // // @ts-ignore
    // app.fillStyle = "#16a085"
    // // 画一个矩形
    // // @ts-ignore
    // app.fillRect(el.width / 2 - 50, el.height / 2 - 50, 100, 100)
    // ******************* 填充矩形 ******************
    
    // ******************* 矩形边 ******************
    // @ts-ignore
    // app.strokeStyle = "#8e44ad"
    // //调整线的宽度
    // // @ts-ignore
    // app.lineWidth=30
    // //线条交汇的边角
    // // @ts-ignore
    // app.lineJoin='round'
    // // 画一个矩形线条
    // // @ts-ignore
    // app.strokeRect(50,50,200,200)
    // ******************* 矩形边 ******************
    
    // ******************* 圆 ******************
    // @ts-ignore
    // app.fillStyle = "#16a085"
    // // @ts-ignore
    // app.strokeStyle = "red"
    // // @ts-ignore
    // app.lineWidth=20
    //
    // // @ts-ignore
    // app.arc(100,100,50,0,2*Math.PI)
    // // 绘制
    // // @ts-ignore
    // app.stroke();
    // // @ts-ignore
    // app.fill();
    // ******************* 圆 ******************
    
    // ******************* 三角形 ******************
    // // 开始一条路径,或重置当前的路径
    // // @ts-ignore
    // app.beginPath()
    // // 把路径移动到画布中的指定点,不创建线条
    // // @ts-ignore
    // app.moveTo(el.width/2,10)
    // // @ts-ignore
    // app.lineTo(el.width-10,222)
    // // @ts-ignore
    // app.lineTo(10,222)
    // // 闭合路径,创建从当前点到开始点的路径
    // // @ts-ignore
    // app.closePath()
    //
    // // @ts-ignore
    // app.strokeStyle = "red"
    // // @ts-ignore
    // app.lineWidth=2
    // // @ts-ignore
    // app.stroke();
    // ******************* 三角形 ******************
    
    // ******************* 渐变色 ******************
    // 创建线性渐变(用在画布内容上)
    // @ts-ignore
    const gradinet =app.createLinearGradient(0,0,300,300)
    
    gradinet.addColorStop(0,'#16a085')
    gradinet.addColorStop(0.5,'#e67e22')
    gradinet.addColorStop(1,'#9b59b6')
    // @ts-ignore
    app.fillStyle=gradinet
    // @ts-ignore
    app.fillRect(0,0,200,200)
    // ******************* 渐变色 ******************
    
    
    image.png
    ......
    // ******************* 渐变色 ******************
    // 创建线性渐变(用在画布内容上)
    // @ts-ignore
    const gradinet =app.createLinearGradient(20,20,200,200)
    
    gradinet.addColorStop(0,'#16a085')
    gradinet.addColorStop(0.5,'#e67e22')
    gradinet.addColorStop(1,'#9b59b6')
    // @ts-ignore
    // app.fillStyle=gradinet
    // // @ts-ignore
    // app.fillRect(0,0,200,200)
    // @ts-ignore
    app.strokeStyle=gradinet
    // @ts-ignore
    app.lineWidth=20
    // @ts-ignore
    app.lineJoin='round'
    // @ts-ignore
    app.strokeRect(20,20,200,200)
    // ******************* 渐变色 ******************
    ......
    
    image.png

    文字处理

    ......
    // ******************* 文字处理 ******************
    // @ts-ignore
    app.fillStyle = "#34495e"
    // @ts-ignore
    app.fillRect(0, 0, el.width, el.height)
    // @ts-ignore
    app.font = '20px 思源黑体-HW'
    // @ts-ignore
    app.fillStyle = 'white'
    // 调整文字基线
    // @ts-ignore
    app.textBaseline='top'
    // @ts-ignore
    app.fillText("坦克游戏", 50, 0)
    // ******************* 文字处理 ******************
    ......
    
    image.png

    也可以弄成线条。

    ......
    // ******************* 文字处理 ******************
    // @ts-ignore
    app.fillStyle = "#34495e"
    // @ts-ignore
    app.fillRect(0, 0, el.width, el.height)
    // @ts-ignore
    app.font = '60px 思源黑体-HW'
    // @ts-ignore
    app.strokeStyle = 'white'
    // 调整文字基线
    // @ts-ignore
    app.textBaseline='top'
    // @ts-ignore
    app.strokeText("坦克游戏", 50, 0)
    // ******************* 文字处理 ******************
    ......
    
    image.png

    也可以换成渐变效果

    ......
    // ******************* 文字处理 ******************
    // @ts-ignore
    app.fillStyle = "#34495e"
    // @ts-ignore
    app.fillRect(0, 0, el.width, el.height)
    // // @ts-ignore
    // app.font = '20px 思源黑体-HW'
    // // @ts-ignore
    // app.fillStyle = 'white'
    // // 调整文字基线
    // // @ts-ignore
    // app.textBaseline='top'
    // // @ts-ignore
    // app.fillText("坦克游戏", 50, 0)
    
    // @ts-ignore
    app.font = '60px 思源黑体-HW'
    // 创建线性渐变(用在画布内容上)
    // @ts-ignore
    const gradinet =app.createLinearGradient(20,20,200,200)
    
    gradinet.addColorStop(0,'#16a085')
    gradinet.addColorStop(0.5,'#e67e22')
    gradinet.addColorStop(1,'#9b59b6')
    // @ts-ignore
    app.strokeStyle = gradinet
    // 调整文字基线
    // @ts-ignore
    app.textBaseline='top'
    // @ts-ignore
    app.strokeText("坦克游戏", 50, 0)
    // ******************* 文字处理 ******************
    ......
    
    image.png

    贴图

    准备图片images/p2.jpeg

    p2.jpeg
    ......
    
    // ******************* 贴图 ******************
    const img=document.createElement('img')
    img.src='../images/p2.jpeg'
    img.onload=()=>{
        //将图片放入body中
        document.body.insertAdjacentElement('afterbegin',img)
    }
    // ******************* 贴图 ******************
    ......
    
    image.png
    ......
    // ******************* 贴图 ******************
    const img = document.createElement('img')
    img.src = '../images/p2.jpeg'
    img.onload = () => {
        //将图片放入body中
        // document.body.insertAdjacentElement('afterbegin',img)
        // @ts-ignore
        const pattren = app.createPattern(img, 'repeat')!
        // @ts-ignore
        app.fillStyle=pattren
        // @ts-ignore
        app.fillRect(0,0,300,300)
    }
    // ******************* 贴图 ******************
    ......
    
    image.png

    图片绘制

    ......
    // ******************* 绘制图片 ******************
    app.fillStyle="#000"
    // @ts-ignore
    app.fillRect(0,0,el.width,el.height)
    const img = document.createElement('img')
    img.src = '../images/p2.jpeg'
    img.onload = () => {
        // @ts-ignore
        app.drawImage(img, 0, 50,100,100)
    }
    // ******************* 绘制图片 ******************
    ......
    
    image.png

    实现随着画布等比例缩放

    ......
    // ******************* 绘制图片 ******************
    app.fillStyle = "#000"
    // @ts-ignore
    app.fillRect(0, 0, el.width, el.height)
    const img = document.createElement('img')
    img.src = '../images/p2.jpeg'
    img.onload = () => {
        // @ts-ignore
        el.width =  img.naturalWidth * scale(img, el)
        el.height =  img.naturalHeight * scale(img, el)
        // 保持图片和画布大小一致
        // @ts-ignore
        // app.fillRect(0, 0, el.width, el.height)
        // @ts-ignore
        app.drawImage(img, 0, 0, el.width, el.height)
    }
    
    // 实现缩略图效果
    const scale = (img: HTMLImageElement, el: HTMLCanvasElement) => {
        // naturalWidth: 原始图片的尺寸
        // 返回缩小比例(宽高的最小值)
        return Math.min(el.width / img.naturalWidth, el.height / img.naturalHeight)
    }
    // ******************* 绘制图片 ******************
    ......
    
    image.png

    随机填充色块

    ......
    // ******************* 随机填充色块 ******************
    app.fillStyle='#000'
    // @ts-ignore
    app.fillRect(0,0,300,300)
    
    for(let i=0;i<2000;i++){
        // @ts-ignore
        app.fillStyle="#fff"
        // @ts-ignore
        app.fillRect(Math.random()*el.width,Math.random()*el.height,2,2)
    }
    // ******************* 随机填充色块 ******************
    ......
    
    image.png

    随机填充色块-圆

    ......
    // ******************* 随机填充色块-圆 ******************
    // @ts-ignore
    app.fillStyle = '#000'
    // @ts-ignore
    app.fillRect(0, 0, 300, 300)
    
    for (let i = 0; i < 200; i++) {
        // @ts-ignore
        app.beginPath();//每次绘制一个新圆时需要重新绘制,不然会相互影响
        // @ts-ignore
        app.fillStyle = ["#e67e22", "#1abc9c", "#27ae60", "#2980b9", "#8e44ad", "#e74c3c"].sort(() => (Math.floor(Math.random() * 3) ? 1 : -1))[0]
        // 排序
        // @ts-ignore
        app.arc(
            Math.random() * (el.width),
            Math.random() * (el.height),
            10 + Math.random() * 10,//半径
            0,
            2 * Math.PI)
        // @ts-ignore
        app.fill()
    }
    // ******************* 随机填充色块-圆 ******************
    ......
    

    调整index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <link rel="icon" type="image/svg+xml" href="favicon.svg"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>Vite App</title>
    </head>
    <body>
    <div id="app"></div>
    <canvas id="canvas" width="300" height="300"  style="overflow: hidden;width: 300px;height: 300px"></canvas>
    <script type="module" src="/src/main.ts"></script>
    </body>
    </html>
    
    
    image.png

    相关文章

      网友评论

        本文标题:【Tank】1.0 canvas-基础使用

        本文链接:https://www.haomeiwen.com/subject/gtyqurtx.html