canvas绘图(动画)案例

动态字母瀑布背景

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>动态字母瀑布背景</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            height: 100vh;
        }

        #canvas-box {
            width: 100vw;
            height: 100vh;
            position: absolute;
        }
    </style>
</head>
<body>
<canvas id="canvas-box">
</canvas>
<script>
    /*
    * canvas字母背景
    * */
    const dom = document.getElementById("canvas-box")
    const ctx = dom.getContext('2d')

    const width = window.innerWidth
    const height = window.innerHeight

    // 设置画布宽度
    dom.width = width
    dom.height = height

    // 设置画布背景
    const bgColor = 'rgba(2,15,26,0.16)'

    // 设置列宽
    const columnWidth = 18
    const columnHeight = columnWidth + 3

    // 根据列宽计算列数量
    const columnNum = parseInt(width / columnWidth)

    function randomCode() {
        const str = "abcdefghijklmnopqrstuvwxyz"
        const randNum = parseInt(Math.random() * str.length)
        return str.split('')[randNum]

        /*
        * 随机字符
        * ASCII转字符 String.fromCharCode(code)
        * 字符转ASCII code.charCodeAt()
        * */
        // const code = parseInt(Math.random() * 122)
        // if (code < 60){
        //     return String.fromCharCode(code + 60)
        // }else{
        //     return String.fromCharCode(code)
        // }
    }

    function randomColor() {
        /*
        * 随机颜色 rgb
        * */
        const r = Math.random() * 255
        const g = Math.random() * 255
        const b = Math.random() * 255
        return `rgb(${r},${g},${b})`
    }

    /*设置随机列高度*/
    function randomRows() {
        const rowNum = height / columnWidth
        list.forEach((num, index) => {
            const h = parseInt(Math.random() * rows)
            /*确保每一列高度超过屏幕高度的一半*/
            list[index] = h < rowNum / 2? h + rowNum : h
        })
        return list
    }

    /*创建列表存储列高*/
    let list = new Array(columnNum)
    const rows = parseInt(height / columnHeight)
    /*列初始化*/
    list.fill(rows)

    /*文本字体与风格*/
    ctx.font = `${columnWidth}px Arial`;

    let column = 0
    let timer = null

    function drow() {
        if (timer) {
            clearInterval(timer)
        }
        timer = setInterval(() => {
            /*全屏背景覆盖,作用:淡化之前画的字母*/
            ctx.fillStyle = bgColor
            ctx.fillRect(0, 0, width, height)

            /*绘制一行*/
            for (let i = 0; i < columnNum; i++) {
                let thisHeight = 0
                ctx.fillStyle = randomColor()
                /*不同列高度不同,从设定的高度列表中读取列高度*/
                thisHeight = (column % list[i]) * columnHeight

                ctx.fillText(randomCode(), i * columnWidth, thisHeight)
            }
            /*下一行*/
            column++
            if (column % rows === 0) {
                /*重置列高*/
                randomRows()
            }
        }, 80)

    }
    drow()
</script>
</body>
</html>

雪花飘落背景

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>demo6</title>
    <style>
        body{
            margin: 0;
            width: 100vw;
            height: 100vh;
            overflow: hidden;
        }
        #canvas{
            background: black;
        }
    </style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
    const canvas = document.querySelector("#canvas")
    const ctx = canvas.getContext("2d")

    function init(){
        const {clientWidth:width,clientHeight:height} = document.body
        canvas.width = width
        canvas.height = height

        /*准备雪花对象数组*/
        const snowList = Array.from(new Array(Math.floor(width /  3))).map(()=> {
            return {
                X: Math.random() * width,
                Y: Math.random() * height,
                W: Math.random() * 4,
                stepX: Math.random() * 2 - 1,
                stepY: Math.random() + .2
            }
        })

        ctx.fillStyle = "#ffffff"

        const draw = () => {
            ctx.clearRect(0,0,width,height)
            ctx.beginPath()

            for (const snow of snowList) {
                ctx.rect(snow.X,snow.Y,snow.W,snow.W)
                snow.X = snow.X >= width || snow.X < 0 ? snow.stepX = -snow.stepX : snow.X + snow.stepX
                snow.Y = snow.Y > height? 0 :snow.Y + snow.stepY
            }
            ctx.fill()
            // requestAnimationFrame(draw)
        }
        setInterval(()=>{
            draw()
        },.01)
    }
    init()

    window.onresize = init

</script>
</body>
</html>

带线的粒子😄

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动态粒子背景</title>
    <style>
        body {
            padding: 0;
            margin: 0;
        }

        #canvas {
            position: fixed;
            width: 100vw;
            height: 100vh;
            /*background: #0f3766;*/
        }
    </style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>

    class Point {
        constructor(size) {
            const canvasNode = document.querySelector("#canvas")
            this.stepX = Math.random() > 0.5 ? this.getRandom(.4, .6) : -this.getRandom(.4, .6)
            this.stepY = Math.random() > 0.5 ? this.getRandom(.3, .5) : -this.getRandom(.3, .5)
            this.canvasWidth = canvasNode.offsetWidth
            this.canvasHeight = canvasNode.offsetHeight
            this.x = Math.random() * this.canvasWidth
            this.y = Math.random() * this.canvasHeight
            this.size = size ? size : this.getRandom(1, 2)
        }

        getRandom(min, max) {
            return Math.random() * (max - min) + min
        }

        sport() {
            this.x += this.stepX
            this.y += this.stepY
            if (this.x < 0 || this.x > this.canvasWidth) {
                this.stepX = -this.stepX
            }
            if (this.y < 0 || this.y > this.canvasHeight) {
                this.stepY = -this.stepY
            }
        }
    }

    class Particle {
        canvasNode = null
        canvas = null
        pointNum = 0  // 粒子数量
        pointList = []
        velocity = 0
        drawLineDistance = 150 // 画线距离
        timer = null

        constructor(pointNum = 20, valocity = 10) {
            // 初始化画布
            this.canvasNode = document.querySelector("#canvas")
            this.canvas = this.canvasNode.getContext("2d")
            const {offsetWidth, offsetHeight} = this.canvasNode
            this.canvasNode.width = offsetWidth
            this.canvasNode.height = offsetHeight
            // 设定点的数量,动画速度,背景颜色
            this.pointNum = pointNum
            this.velocity = valocity //值越大,速度越慢
            this.canvasNode.style.backgroundColor = "rgba(0,0,0,0.92)"
            // 创建点
            this.createPoints()

            const that = this
            this.draw(that)
        }

        createPoints() {
            for (let i = 0; i < this.pointNum; i++) {
                const point = new Point()
                this.pointList.push(point)
            }
        }

        clearCanvas() {
            const {offsetWidth, offsetHeight} = this.canvasNode
            this.canvas.clearRect(0, 0, offsetWidth, offsetHeight)
        }
        clearTimer(){
            clearTimeout(this.timer)
        }

        // 计算两个坐标之间的距离
        getPointsDistance(pointOne, pointTwo) {
            const {x: xOne, y: yOne} = pointOne
            const {x: xTwo, y: yTwo} = pointTwo
            const x = Math.abs(xOne - xTwo)
            const y = Math.abs(yOne - yTwo)
            return Math.sqrt(x * x + y * y)
        }

        drawPoint() {
            this.canvas.fillStyle = "#d3d3d3"
            for (const point of this.pointList) {
                this.canvas.beginPath()
                this.canvas.arc(point.x, point.y, point.size, 0, Math.PI * 2, false)
                this.canvas.fill()
                this.canvas.closePath()
                point.sport()
            }
        }

        drawLine() {
            this.canvas.lineWidth = ".7"
            for (let i = 0; i < this.pointList.length; i++) {
                for (let j = i + 1; j < this.pointList.length; j++) {
                    const distance = this.getPointsDistance(this.pointList[i], this.pointList[j])
                    if (distance > this.drawLineDistance) continue
                    this.canvas.beginPath()
                    this.canvas.strokeStyle = `rgba(234, 234, 234, ${(this.drawLineDistance - distance) / this.drawLineDistance * 0.8})`
                    this.canvas.moveTo(this.pointList[i].x, this.pointList[i].y)
                    this.canvas.lineTo(this.pointList[j].x, this.pointList[j].y)
                    this.canvas.stroke()
                    this.canvas.closePath()
                }
            }

        }

        draw(that) {
            that.clearCanvas()
            that.drawPoint()
            that.drawLine()
            clearTimeout(that.timer)
            that.timer = setTimeout(() => {
                that.draw(that)
            }, that.velocity)
        }
    }

    let particle = new Particle(100, 10)
    // 当window 尺寸变化时,重新创建绘画实例
    window.onresize = function () {
        // 这里必须清除定时器,否则会有多个绘画实例
        particle.clearTimer()
        particle = new Particle(100,10)
    }
</script>
</body>
</html>

图片验证码

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>canvas验证码</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            height: 100vh;
            display: grid;
            place-items: center;
        }

        #canvas{
            width: 100px;
            aspect-ratio: 2 / 1;
        }
    </style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
    const dom = document.getElementById("canvas")
    const ctx = dom.getContext("2d")

    const width = dom.clientWidth
    const height = dom.clientHeight

    // 设置宽度
    dom.width = width
    dom.height = height

    /*设定字符串*/
    let str = randomCode(4)

    /*随机色*/
    function randomColor() {
        const r = Math.random() * 255
        const g = Math.random() * 255
        const b = Math.random() * 255
        return `rgb(${r},${g},${b})`
    }
    /*渐变色*/
    function GradualChangeColor(){
        let grd=ctx.createLinearGradient(width*0.2,width*0.05,width*0.5,width*0.75);
        grd.addColorStop(0,randomColor());
        grd.addColorStop(1,randomColor());
        return grd
    }
    /*绘制背景*/
    function bgDrow(){
        ctx.fillStyle = GradualChangeColor()
        ctx.fillRect(0, 0, width, height)
    }
    /*画线*/
    function lineDrow(){
        let nodeNum = parseInt(Math.random() * 5 + 5)
        let lineWidth = Math.random() * 2
        function pos(){
            let x = Math.random() * width
            let y = Math.random() * height
            return [x,y]
        }
        ctx.strokStyle = GradualChangeColor()
        ctx.beginPath();
        ctx.moveTo(...pos());
        ctx.lineWidth = lineWidth
        for (let i = 0; i < nodeNum; i++) {
            ctx.lineTo(...pos())
        }
        ctx.stroke();
    }
    /*绘制文字*/
    function textDraw(){
        str = randomCode(4)
        ctx.clearRect(0, 0, width, height)
        bgDrow()
        lineDrow()
        const fontSize = 0.6 * height
        const list = str.split('')
        const font = ["Arial", "Inter", "Helvetica"]
        let top = 0
        let left = 5
        for (const number of list) {
            let i = Math.floor(Math.random() * font.length)
            ctx.font=`${fontSize}px ${font[i]}`;
            ctx.fillStyle = GradualChangeColor()
            ctx.strokStyle = GradualChangeColor()
            top = Math.random() * height
            top = top > fontSize? top : top + fontSize / 2
            Math.random() > 0.5 ? ctx.fillText(number,left,top) : ctx.strokeText(number,left,top)
            left += width / list.length
        }
    }

    /*指定长度随机字符*/
    function randomCode(length) {
        const strArr = "1234567890abcdefghijklmnopqrstuvwxyz"
        let randNum = 0
        let strList = []
        for (let i = 0; i < length; i++) {
            randNum = parseInt(Math.random() * strArr.length)
            strList.push(strArr.split('')[randNum])
        }
        return strList.join('')
    }
    textDraw()
    dom.onclick = textDraw
</script>
</body>
</html>

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳当空丶赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值