• 企业400电话
  • 网络优化推广
  • AI电话机器人
  • 呼叫中心
  • 全 部 栏 目

    网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    利用Canvas模仿百度贴吧客户端loading小球的方法示例
    POST TIME:2021-10-16 23:50

    前言

    最近看到两个好玩的 demo,效果图如下:

    今天趁着周末有空,用 H5 的 Canvas 仿了一下。这篇文章只实现第一个效果图。
     

    这是我实现的效果:

    实现原理

    实现原理是参考简书的那篇文章,这里不再复述。现在我们来一步一步实现这样的效果。

    第零步:画一个圆

    源码如下:

    运行效果如下:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>百度贴吧客户端Loading小球</title>
        <style>
            canvas {
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
    <canvas id="canvas" width="500" height="500"></canvas>
    <script>
        var canvas = document.getElementById('canvas')
        var ctx = canvas.getContext('2d')
        canvas.width = 500
        canvas.height = 500
    
        var grid = canvas.width / 4
        var cx = canvas.width / 2 // 圆中心点 x 坐标
        var cy = canvas.height / 2 // 圆中心点 y 坐标
    
        function circle() {
            ctx.beginPath()
            ctx.arc(cx, cy, grid / 2, 0, 2 * Math.PI)
        }
    
        circle()
        ctx.stroke()
    </script>
    </body>
    </html>

    这个 demo 只涉及 Canvas 最简单的用法。

    第一步:绘制蓝色的“贴”字

    使用 ctx.fillText,在圆的中心绘制一个蓝色的“帖”字。文字粗体、水平居中。

    代码如下:

    function text(fillStyle) {
        var fontSize = size / 250 * 120
        ctx.font = 'bold ' + fontSize + 'px Arial'
        ctx.textAlign = 'center'
        ctx.fillStyle = fillStyle
        ctx.fillText('贴', cx, cy + fontSize * 0.3)
    }
    
    text('#29a3fe')

    效果如下:

    第二步:绘制蓝色的波浪

    var waveSize = size / 6 // 波浪大小
    var x = 0 // 波浪位置偏移大小
    
    function curve() {
        ctx.beginPath()
        ctx.moveTo(cx - size + x + size / 2, cy)
        ctx.quadraticCurveTo(cx - size + size / 4 + x + size / 2, cy - waveSize, cx - size + size / 2 + x + size / 2, cy)
        ctx.quadraticCurveTo(cx - size + size * 3 / 4 + x + size / 2, cy + waveSize, cx - size + size + x + size / 2, cy)
    
        ctx.quadraticCurveTo(cx + size / 4 + x + size / 2, cy - waveSize, cx + size / 2 + x + size / 2, cy)
        ctx.quadraticCurveTo(cx + size * 3 / 4 + x + size / 2, cy + waveSize, cx + size + x + size / 2, cy)
        ctx.lineTo(cx + size + x + size / 2, canvas.height)
        ctx.lineTo(cx - size + x + size / 2, canvas.height)
        ctx.lineTo(cx - size + x + size / 2, cy)
        ctx.closePath()
    }
    
    ctx.fillStyle = '#29a3fe'
    curve()
    ctx.fill()

    效果如下:

    第三步:绘制白色的“贴”字

    curve()
    ctx.clip()
    text('#f00')

    第一句代码 curve() 创建了一个波浪形状的路径,和第三步不同的是,这里并没有使用 ctx.fill() 填充路径,而是使用了 ctx.clip() 裁剪路径,这样的话,后面绘制的路径(包括文字)只有在剪裁区域内才能显示。

    为了和背景色区分开来,我把“贴”字改成红色。

    效果如下:

    第四步:绘制运动的波浪

    function loop(){
        ctx.clearRect(0, 0, canvas.width, canvas.height)
    
        x -= 1.5
        x = x % size
    
        ctx.save()
    
        circle()
        ctx.stroke()
     
        ctx.fillStyle = '#29a3fe'
        curve()
        ctx.fill()
    
        ctx.restore()
    
        requestAnimationFrame(loop)
    }
    loop()

    效果如下:

    第五步:整合前面的内容

    效果如下:

    第六步:剪裁圆形

    把第零步的:

    circle()
    ctx.stroke()

    改成:

    circle()
    ctx.clip()

    这样就能把圆形外面的形状剪裁掉,然后就大功告成了。

    最后,附上完整源码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            html,
            body {
                height: 100%;
            }
            canvas {
                border: 1px solid #ccc;
            }
        </style>
    </head>
    <body>
    <canvas id="canvas" width="500" height="500"></canvas>
    <script>
        var canvas = document.getElementById('canvas')
        var ctx = canvas.getContext('2d')
        canvas.width = 500
        canvas.height = 500
    
        var size = canvas.width / 4 // 圆的大小
        var cx = canvas.width / 2 // 圆中心点 x 坐标
        var cy = canvas.height / 2 // 圆中心点 y 坐标
        var waveSize = size / 6 // 波浪大小
        var x = 0 // 波浪位置偏移大小
    
        function circle() {
            ctx.beginPath()
            ctx.arc(cx, cy, size / 2, 0, 2 * Math.PI)
        }
    
        function curve() {
            ctx.beginPath()
            ctx.moveTo(cx - size + x + size / 2, cy)
            ctx.quadraticCurveTo(cx - size + size / 4 + x + size / 2, cy - waveSize, cx - size + size / 2 + x + size / 2, cy)
            ctx.quadraticCurveTo(cx - size + size * 3 / 4 + x + size / 2, cy + waveSize, cx - size + size + x + size / 2, cy)
    
            ctx.quadraticCurveTo(cx + size / 4 + x + size / 2, cy - waveSize, cx + size / 2 + x + size / 2, cy)
            ctx.quadraticCurveTo(cx + size * 3 / 4 + x + size / 2, cy + waveSize, cx + size + x + size / 2, cy)
            ctx.lineTo(cx + size + x + size / 2, canvas.height)
            ctx.lineTo(cx - size + x + size / 2, canvas.height)
            ctx.lineTo(cx - size + x + size / 2, cy)
            ctx.closePath()
        }
    
        function text(fillStyle) {
            var fontSize = size / 250 * 120
            ctx.font = 'bold ' + fontSize + 'px Arial'
            ctx.textAlign = 'center'
            ctx.fillStyle = fillStyle
            ctx.fillText('贴', cx, cy + fontSize * 0.3)
        }
    
        function loop(){
            ctx.clearRect(0, 0, canvas.width, canvas.height)
    
            x -= 1.5
            x = x % size
    
            ctx.save()
    
            circle()
            ctx.clip()
    
            text('#29a3fe')
    
            ctx.fillStyle = '#29a3fe'
            curve()
            ctx.fill()
    
            curve()
            ctx.clip()
    
            text('#fff')
    
            ctx.restore()
    
            requestAnimationFrame(loop)
        }
        loop()
    </script>
    </body>
    </html>

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
     

  • 相关文章
  • 

    关于我们 | 付款方式 | 荣誉资质 | 业务提交 | 代理合作


    © 2016-2020 巨人网络通讯

    时间:9:00-21:00 (节假日不休)

    地址:江苏信息产业基地11号楼四层

    《增值电信业务经营许可证》 苏B2-20120278

    X

    截屏,微信识别二维码

    微信号:veteran88

    (点击微信号复制,添加好友)

     打开微信