zoukankan      html  css  js  c++  java
  • canvas简述(一)

    canvas是HTML5推出的画布技术 有2D和3D 目前3D兼容性很差但相信随着VR的兴起 3D也会逐渐发力 目前只讲述关于2D 相关的API 以及 业务逻辑 常用场景 游戏等等

    API部分

        <style>
            canvas{
                border:solid 2px red
            }
        </style>
        <canvas id="cvs" width="800" height="800"></canvas>
    </head>
    <body>
    <script>
        //获取canvas以及其上下文对象
        var cvs = document.querySelector('#cvs')
        var ctx = cvs.getContext('2d')
    
        //开始绘制
    
        ctx.beginPath()
        ctx.moveTo(200,200)
        ctx.lineTo(200,400)
        ctx.lineTo(100,400)
        ctx.lineWidth = 15
        ctx.closePath()
        ctx.strokeStyle = 'red'
        ctx.fillStyle = 'blue'
        ctx.stroke()
        ctx.fill()
        //上面自己绘制了一个三角形
        
        
    
    </script>

    上面自己绘制了一个三角形 在canvas中的路径 良好的习惯每次 绘制结束 都要闭合 每次绘制开始都要重新开启路径 第一步定点 然后 绘制 路径 填充非常简单

    下面放canvas绘制矩形 以及 圆弧 以及 绘制图片的API demo

        ctx.fillStyle = 'red'
        ctx.fillRect(200,200,200,200)
    
        ctx.strokeStyle = 'blue'
        ctx.strokeRect(400,400,400,400)

    上面绘制了两个canvas预定义的 实心矩形和 空心矩形

    在绘制圆形之前首先要明白canvas 圆形绘制是根据弧度制的 也就是角度跟弧度弧度是成比例的 是什么一个关系 圆的周长 = 2πr  如果将360° 跟 周长划一个关系的话 那么必须提取一个唯一的变量那就是r 在不同大小的圆下r也是不同的 

    将r提取出来 周长 / 2π = r   360° / 2π = 57.29° 那么我们就可以说 无论在什么情况下 1r 的弧度就等于 = 57.29° 的角度 那么有了这个对等的关系就非常简单了 我们可以假设360°就是 2π 的弧度 实际上canvas也是这么实现的 这两个是常量 在角度 和 r 有一个对等的比例关系下 可以将其忽略 在这个前提下 那么如果我们要计算30°的弧度是多少就非常简单了 就是360 / 30 * 2π 这样我们就计算出了30 的弧度 下面讲述一下API用法

        //下面是圆弧的绘制
        ctx.arc(200,200,100,0,2 * Math.PI,false)
        ctx.fillStyle = 'red'
        ctx.lineWidth = 10
        ctx.strokeStyle = 'blue'
        ctx.fill()
        ctx.stroke()

    在canvas中所有呈现出来的元素立即被像素化 因此无法像DOM一样操作canvas中的元素 只能通过画布帧动画的概念来实现各种动画游戏效果

    下面一个圆球动画的简例:

        //获取canvas以及其上下文对象
        var cvs = document.querySelector('#cvs')
        var ctx = cvs.getContext('2d')
        let x = 100,
            x1 = 100,
            x2 = 100
        setInterval(function(){
            x += 20
            x1 += 40
            x2 += 60
            ctx.clearRect(0,0,800,800)
            ctx.beginPath()
            ctx.fillStyle = 'blue'
            ctx.arc(x,100,50,0,2*Math.PI,false)
            ctx.fill()
    
            ctx.beginPath()
            ctx.fillStyle = 'blue'
            ctx.arc(x1,200,50,0,2*Math.PI,false)
            ctx.fill()
    
            ctx.beginPath()
            ctx.fillStyle = 'blue'
            ctx.arc(x2,300,50,0,2*Math.PI,false)
            ctx.fill()
        },100)

     在多个元素运动和canvas游戏中一般采用的是 面向对象的方式 接下来用渐进增强的方式慢慢解析 

    <script>
        //获取canvas以及其上下文对象
        var cvs = document.querySelector('#cvs')
        var ctx = cvs.getContext('2d')
        //运动元素构造函数
        function Ball (x,y,r,speed){
            this.x = x
            this.y = y
            this.r = r
            this.speed = speed
            actorsAll.push(this)
        }
        const actorsAll = []
        //更新函数
        Ball.prototype.update = function(){
            this.x += this.speed
        }
        //渲染函数
        Ball.prototype.render = function(){
            ctx.beginPath()
            ctx.arc(this.x,this.y,this.r,0,2 * Math.PI,false)
            ctx.fillStyle = 'yellow'
            ctx.fill()
        }
        
        new Ball(100,100,30,1)
    
        new Ball(100,200,30,2)
    
        new Ball(100,300,30,3)
    
        new Ball(100,400,30,4)
    
        setInterval(function(){
            ctx.clearRect(0,0,800,800)
            actorsAll.forEach(value => {
                value.update()
                value.render()
            })
        })
    </script>

    使用面向会使代码更加的规整 已读 canvas中运用面向对象是一种非常好的思路

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            canvas{
                border:solid 2px red
            }
        </style>
        <canvas id="cvs" ></canvas>
    </head>
    <body>
    <script>
        //获取canvas以及其上下文对象
        var cvs = document.querySelector('#cvs')
        var ctx = cvs.getContext('2d')
    
        cvs.width = document.documentElement.clientWidth
        cvs.height = document.documentElement.clientHeight
        //运动元素构造函数
        function Ball(x,y){
            this.x = x
            this.y = y
            this.color = `rgba(${parseInt(Math.random()*256)},${parseInt(Math.random()*256)},${parseInt(Math.random()*256)},0.8)`
            this.r = 30
            this.dx = parseInt(Math.random() * 17) - 8
            this.dy = parseInt(Math.random() * 17) - 8
            actorAll.push(this)
        }
        const actorAll = []
        //渲染函数
        Ball.prototype.render = function(){
            ctx.beginPath()
            ctx.fillStyle = this.color
            ctx.arc(this.x,this.y,this.r,0,2 * Math.PI,false)
            ctx.fill()
        }
        //更新函数
        Ball.prototype.update = function(){
            console.log(this.x)
            console.log(this.y)
            this.x += this.dx
            this.y += this.dy
            this.r --
            if(this.r <= 0){
                this.godie()
            }
        }
        //删除函数
        Ball.prototype.godie = function(){
            actorAll.forEach((value,i) => {
                if(this === value){
                    actorAll.splice(i,1)
                }
            })
        }
        cvs.addEventListener('mousemove',function(event){
            new Ball(event.clientX,event.clientY)
        })
        setInterval(function(){
            ctx.clearRect(0,0,cvs.width,cvs.height)
            actorAll.forEach(value => {
                value.update()
                value.render()
            })
        },30)
    
    </script>
    </body>
    </html>
  • 相关阅读:
    PHP实现无限极分类
    html2canvas生成并下载图片
    一次线上问题引发的过程回顾和思考,以更换两台服务器结束
    Intellij IDEA启动项目报Command line is too long. Shorten command line for XXXApplication or also for
    mq 消费消息 与发送消息传参问题
    idea 创建不了 java 文件
    Java switch 中如何使用枚举?
    Collections排序
    在idea 设置 git 的用户名
    mongodb添加字段和创建自增主键
  • 原文地址:https://www.cnblogs.com/tengx/p/9245651.html
Copyright © 2011-2022 走看看