用javaScript写的简单弹幕

        大三用js写的简单弹幕效果,过去蛮久了,已经不记得当时怎么写的了。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            position: relative;
            margin: 0 auto;
            width: 676px;
            height: 380px;
            background-color: rgb(228, 225, 222);
        }

        canvas {
            position: absolute;
            width: 676px;
            height: 380px;
        }

        button {
            display: block;
            margin: 10px auto;
            width: 60px;
            height: 30px;
        }
    </style>
</head>

<body>
    <div>
        <canvas></canvas>
    </div>
    <button align="center">点击</button>
</body>
<script>
    var canvas = document.querySelector("canvas")
    var button = document.querySelector("button")
    var context = canvas.getContext("2d")
    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
    var frameID = 0
    //装填弹幕
    var arry = [
        { value: "好看好看", color: "red" }
        , { value: "ikun", color: "blue" }
        , { value: "我发的", color: "yellow" }
        , { value: "氛围", color: "pink" }
        , { value: "小黑子", color: "aliceblue" }
        , { value: "泰裤了", color: "green" }
        , { value: "大哥不能说,要和成为当晚的", color: "cadetblue" }
        , { value: "工作好难找啊!", color: "chocolate" }
        , { value: "啥都不说", color: "brown" }
        , { value: "注释很多自己看", color: "blueviolet" }]
    var instan = [null, null, null, null, null, null, null, null, null]//弹幕容量
    var hanEnd = [-1, -1, -1, -1]//该行的最后一个
    var han = [0, 0, 0, 0]//一行的文字容量最大为:676/20=33个
    var Barrage = function () {
        this.x //现在的x坐标
        this.y //现在的y坐标
        this.han //在哪一行
        this.moveX //速度
        this.value //文本内容
        this.color //文本颜色
        this.gentime
    }

    var flag = 0
    button.onclick = function () {
        if (flag == 0) {
            flag = 1
            render()
        } else {
            cancelAnimationFrame(frameID)
            flag = 0
        }
    }

    function radomBar() {//随机生成弹幕
        var index = parseInt((Math.random() * arry.length))
        if (index < arry.length) {

            var bar = new Barrage()
            bar.value = arry[index].value
            bar.color = arry[index].color
            bar.x = 676
            var hh = randomHan(bar.value)
            if (hh == null) { return }
            bar.han = hh//0 1 2 3行
            bar.y = 28 * (1 + bar.han)
            bar.moveX = randomMoveX(bar)
            for (var i = 0; i < instan.length; i++) {//
                if (instan[i] == null) {
                    instan[i] = bar
                    hanEnd[bar.han] = i//谁该行的行尾
                    break
                }
            }
        }
    }

    function randomMoveX(bar) {
        var moveX = 2
        if (hanEnd[bar.han] < 0) {
            return moveX
        }
        //生成了新的bar,那么之前的最后一个,就变成了倒数第二个
        //通过这一个计算速度,让他们不会覆盖在一起,1000 / 60 = 16.666
        var left = instan[hanEnd[bar.han]].x + instan[hanEnd[bar.han]].value.length * 22//当前倒数第二个左边的距离
        var t1 = 16.7 * left / instan[hanEnd[bar.han]].moveX//当前倒数第二个,从现在到移出画布的时间

        moveX = (canvas.width * 16.7) / t1//当前最后一个的速度
        if (moveX > 4) {//如果速度超过最大速度4,则随机
            moveX = 2 + Math.random() * 2
        }
        return moveX
    }

    function randomHan() {//随机行
        for (var i = 0; i < han.length; i++) {
            var index = parseInt(Math.random() * han.length)//随机行
            var right = 33 * 20 - han[index]//右边的剩余大小
            if (right >= 2 * 20) {//如果改行有剩余空间
                return index//返回随机行随机行
            }
        }
        return null
    }

    

    var render = function () {// 画布渲染
        context.clearRect(0, 0, canvas.width, canvas.height);// 清除画布
        radomBar()
        draw(instan);// 绘制画布上所有的圆圈圈
        frameID = requestAnimationFrame(render);// 继续渲染
    };

    function draw(a) {
        for (var i = 0; i < a.length; i++) {
            if (a[i] == null || a[i].value.length <= 0) { continue }
            var barrage = a[i]

            if (barrage.x < -(barrage.value.length * 20)) {
                var tmp = hanEnd.indexOf(i)
                if (tmp >= 0) {//更新行尾:这个文字已经移出画布了,如果这个是行尾,重新设为没有行尾
                    han[barrage.han] = 0
                    hanEnd[barrage.han] = -1
                }

                a[i] = null
                continue
            }
            barrage.x = barrage.x - barrage.moveX//更新x坐标
            var tmp = hanEnd.indexOf(i)
            if (tmp >= 0) {//更新行尾
                han[barrage.han] = barrage.x + barrage.value.length * 20
            }

            context.font = 'bold ' + 20 + 'px "microsoft yahei", sans-serif';
            context.fillStyle = barrage.color;
            context.fillText(barrage.value, barrage.x, barrage.y);
        }
    }


</script>

</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值