h5怎样通过canvas来实现滚动弹幕功能

这次给大家带来h5怎样通过canvas来实现滚动弹幕功能,通过canvas实现滚动弹幕功能的注意事项有哪些,下面就是实战案例,一起来看一下。

最近在着手开发弹幕视频网站,通过html5中的canvas实现了弹幕的功能。

那么闲言碎语不要讲,先说思路后上代码。

思路:从页面布局上来说就是将一块画布覆盖在了video标签产生的视频窗口之上,使用绝对定位就能实现了。最重要的就是js控制画布上弹幕的显示了,每一个弹幕都包装成一个对象,对象包含的属性有弹幕应该出现的时间,弹幕的颜色,弹幕是否是移动的以及弹幕的文本。弹幕对象拥有方法包含:设置弹幕的横纵坐标,弹幕的移动函数。实现的原理,在监听视频开始播放的事件,在视频开始播放时生成一个定时器,定时器每隔一个时间去遍历循环弹幕对象数组并根据对象的属性在画布的适当位置上绘制出弹幕,计时器中除了绘制弹幕的代码还有执行更新弹幕数组的代码。

那么下面开始直接上代码:

(function () {    window.onload=function () {        var video = document.getElementsByTagName("video")[0]        var cav = document.getElementsByTagName("canvas")[0]        //设置常量canvas的高度以及宽度        var cavWidth = 800        var cavHeight = 420        cav.width=cavWidth        cav.height=cavHeight        var ctx = cav.getContext("2d")        //存储弹幕对象的数组        var capObjs = []        var lastItemTime        var capHeight = 20        var inputEle = document.getElementsByClassName("caption-input-text")[0]        var sendEle = document.getElementsByClassName("caption-sendButton")[0]        var colorUl = document.getElementsByClassName("colorItems")[0]        var ismoveInputEle = document.getElementsByClassName("caption-input-ismove")[0]        //弹幕颜色        var colors=["#fff","#FFCCCC","#CCFFCC","#CCCCFF","#FFFFCC","#CCFFFF"]        var selectedColorIndex = 0        var prevPlayTime = 0        //测试数据的数组        var testArrayCopy = []        var capobjId = 0        //弹幕在画布中高度可能值组成的数组        var topObjs = [{blank:true , value : 20 ,index:0},                        {blank:true , value : 50 ,index:1},                        {blank:true , value : 80 ,index:2},                        {blank:true , value : 110 ,index:3},                        {blank:true , value : 140 ,index:4},                        {blank:true , value : 170 ,index:5},                        {blank:true , value : 200 ,index:6},                        {blank:true , value : 230 ,index:7},                        {blank:true , value : 260 ,index:8},                        {blank:true , value : 290 ,index:9},                        {blank:true , value : 320 ,index:10},                        {blank:true , value : 350 ,index:11},                        {blank:true , value : 380 ,index:12},                        {blank:true , value : 410 ,index:13}]//test data 测试数据var testArray = [{content:"ABCDEFGHIJKLMNOPQRSTUVWXYZ",time:"1",ismove:false,colorIndex:0},{content:"233333333333333",time:"2",ismove:true,colorIndex:0},{content:"干杯,哈哈哈~~~~~~",time:"2",ismove:true,colorIndex:5},{content:"干杯,哈哈哈~~~~~~",time:"2",ismove:true,colorIndex:4},{content:"干杯,哈哈哈~~~~~~",time:"2",ismove:true,colorIndex:4},{content:"干杯,哈哈哈~~~~~~",time:"2",ismove:true,colorIndex:0},{content:"干杯,哈哈哈~~~~~~",time:"2",ismove:true,colorIndex:0},{content:"233333333333333",time:"3",ismove:true,colorIndex:0},{content:"233333333333333",time:"3",ismove:true,colorIndex:0},{content:"233333333333333",time:"3",ismove:true,colorIndex:0},{content:"233333333333333",time:"3",ismove:true,colorIndex:0},{content:"233333333333333",time:"3",ismove:true,colorIndex:0},{content:"233333333333333",time:"3",ismove:true,colorIndex:0},{content:"233333333333333",time:"4",ismove:false,colorIndex:0},{content:"233333333333333",time:"5",ismove:true,colorIndex:4},{content:"233333333333333",time:"6",ismove:true,colorIndex:2},{content:"233333333333333",time:"7",ismove:true,colorIndex:2},{content:"233333333333333",time:"7",ismove:true,colorIndex:2},{content:"233333333333333",time:"7",ismove:true,colorIndex:2},{content:"233333333333333",time:"7",ismove:true,colorIndex:2},{content:"233333333333333",time:"7",ismove:true,colorIndex:2},{content:"233333333333333",time:"7",ismove:true,colorIndex:2},{content:"233333333333333",time:"8",ismove:true,colorIndex:0},{content:"233333333333333",time:"9",ismove:true,colorIndex:0},{content:"233333333333333",time:"10",ismove:true,colorIndex:0},{content:"老师说的非常好,我要好好学习了》》》》",time:"12",ismove:true,colorIndex:0},{content:"老师说的非常好,我要好好学习了》》》》",time:"13",ismove:true,colorIndex:0},{content:"老师说的非常好,我要好好学习了》》》》",time:"14",ismove:true,colorIndex:2},{content:"老师说的非常好,我要好好学习了》》》》",time:"15",ismove:false,colorIndex:0},{content:"老师说的非常好,我要好好学习了》》》》",time:"16",ismove:true,colorIndex:2},{content:"老师说的非常好,我要好好学习了》》》》",time:"17",ismove:true,colorIndex:3},{content:"老师说的非常好,我要好好学习了》》》》",time:"18",ismove:true,colorIndex:2},{content:"老师说的非常好,我要好好学习了》》》》",time:"19",ismove:true,colorIndex:0},{content:"老师说的非常好,我要好好学习了》》》》",time:"20",ismove:true,colorIndex:3},{content:"老师说的非常好,我要好好学习了》》》》",time:"21",ismove:true,colorIndex:0},{content:"老师说的非常好,我要好好学习了》》》》",time:"22",ismove:true,colorIndex:0},{content:"老铁们,小礼物走一波了,小汽车小火箭刷起来吧=========",time:"23",ismove:true,colorIndex:0},{content:"老铁们,小礼物走一波了,小汽车小火箭刷起来吧=========",time:"24",ismove:true,colorIndex:0},{content:"老铁们,小礼物走一波了,小汽车小火箭刷起来吧=========",time:"25",ismove:true,colorIndex:3},{content:"老铁们,小礼物走一波了,小汽车小火箭刷起来吧=========",time:"26",ismove:true,colorIndex:0},{content:"老铁们,小礼物走一波了,小汽车小火箭刷起来吧=========",time:"27",ismove:true,colorIndex:5},{content:"老铁们,小礼物走一波了,小汽车小火箭刷起来吧=========",time:"28",ismove:false,colorIndex:5},{content:"老铁们,小礼物走一波了,小汽车小火箭刷起来吧=========",time:"29",ismove:true,colorIndex:5},{content:"老铁们,小礼物走一波了,小汽车小火箭刷起来吧=========",time:"30",ismove:true,colorIndex:5},{content:"马上就下课了,瓦罗蓝大陆走起了~~~",time:"31",ismove:true,colorIndex:5},{content:"马上就下课了,瓦罗蓝大陆走起了~~~",time:"32",ismove:true,colorIndex:2},{content:"马上就下课了,瓦罗蓝大陆走起了~~~",time:"33",ismove:true,colorIndex:2},{content:"马上就下课了,瓦罗蓝大陆走起了~~~",time:"33",ismove:true,colorIndex:5},{content:"马上就下课了,瓦罗蓝大陆走起了~~~",time:"34",ismove:true,colorIndex:5},{content:"马上就下课了,瓦罗蓝大陆走起了~~~",time:"35",ismove:true,colorIndex:5},{content:"马上就下课了,瓦罗蓝大陆走起了~~~",time:"36",ismove:true,colorIndex:2},{content:"马上就下课了,瓦罗蓝大陆走起了~~~",time:"37",ismove:true,colorIndex:2}]        //将测试数据备份        copyArray(testArray , testArrayCopy)        /*弹幕对象的构造函数,参数分别是:1.ismove:弹幕是否是移动的弹幕,2.spe:弹幕的移动速度,3.col:弹幕的颜色,4.text:弹幕的文本*/        /*原型链方法 setTopValue设置纵坐标,setLeftValue设置横坐标,moving完成坐标的改变,setId完成id值的设置*/        function Caption( ismove , spe , col , text ) {            this.isMove = ismove            this.speed = spe            this.color = col || "#ff0"            this.content = text            this.latestTime = 0            this.width = text.length * 20            this.id = 0            this.topIndex = 0            this.occupyPos = true            this.top = 300            this.left = 0            this.setLeftValue()            this.setTopValue()        }        Caption.prototype.setTopValue = function  () {            for(var i = 0 ,len = topObjs.length ; i < len ; i++){                if (topObjs[i].blank) {                    this.top = topObjs[i].value                    this.topIndex = i                    topObjs[i].blank = false                    break                }            }        }        Caption.prototype.setLeftValue = function  () {            if (this.isMove) {                this.left = cavWidth            }            else {                var contentLength = this.content.length                var nowItemLeft = 420 - contentLength * 9                this.left = nowItemLeft            }        }        Caption.prototype.moving = function () {            if (this.isMove) {                this.left-=this.speed                if ( this.left + this.width  450) {                    topObjs[this.topIndex].blank = true                }            }        }        Caption.prototype.setId = function  () {            this.id = capobjId            capobjId++        }         var cap1 = new Caption(  false , 1 , 0 , "小礼物走一波,双击6666。。。。")        capObjs.push(cap1)        cap1.setId()                 //循环遍历数组,根据对象的属性绘制在画布上        function drawAllText () {            ctx.clearRect( 0 , 0 , cavWidth , cavHeight)            ctx.beginPath()            for(var i=0 , len = capObjs . length ; i < len ; i++ ){                ctx.fillStyle = capObjs[i].color                ctx.font = "bold 20px Courier New"                ctx.fillText( capObjs[i].content , capObjs[i].left , capObjs[i].top )                ctx.closePath()                capObjs[i].moving()                // if (capObjs[i].left = 0; i--) {                if (objs[i].left  450 ) {                    objs.splice(i , 1)                }             }        }                 //更新保存弹幕对象的数组        function updateArray () {            var now = parseInt( video.currentTime )            for (var i = testArray.length - 1; i >= 0; i--) {                var nowItemTime = parseInt(testArray[i].time)                if ( nowItemTime == now ) {                    //首次写的控制高度的方式,空间利用不充分,后来改为setTopValue中的方式                    // var nowItemLeft = getLeftValue(testArray[i])                    // var diffTime = Math.abs(nowItemTime - lastItemTime)                    // if (diffTime  400 ? 20 : capHeight                    // }                       var temcolor = colors[testArray[i].colorIndex]                    var temcap = new Caption (  testArray[i].ismove , 1 , temcolor , testArray[i].content  )                    capObjs.push(temcap)                    capObjs[capObjs.length - 1].setId()                    temcap = null                    testArray.splice(i,1)                }            }        }                 //当用户点击send发送弹幕的回调函数        function sendCaption (argument) {            var inputEleTxt = inputEle.value            var now = parseInt( video.currentTime )            var inputIsmoveValue = ismoveInputEle.checked            var temObj = {content:inputEleTxt,time:now,ismove:inputIsmoveValue,colorIndex:selectedColorIndex}            testArray.push(temObj)            inputEle.value = ""        }         // function getLeftValue (obj) {        //     if (obj.ismove) {        //         return 0        //     }        //     else {        //         var contentLength = obj.content.length        //         var nowItemLeft = 420 - contentLength * 9        //         return nowItemLeft        //     }        // }                 //重新启动canvas,用在人为导致进度条时间的改变        function reinitCav (argument) {            // testArray = testArrayCopy            copyArray(testArrayCopy , testArray)            capObjs = []            capHeight = 0            clearInterval(canvasTimer)            canvasTimer = null            initCanvas()        }         var canvasTimer = null                 //初始化canvas,用在开始播放时         function initCanvas () {             if (canvasTimer == null ) {                canvasTimer = setInterval(function (argument) {                    drawAllText()                    updateArray()                    refreshObjs(capObjs)                },10)             }                     }//end function initCanvas                 //复制数组        function copyArray (arr1 , arr2) {            for (var i =0 , len=arr1.length ; i  1) {                reinitCav()            }        }, false)                 //视频暂停执行代码        video.addEventListener("pause" , function () {            clearInterval(canvasTimer)            canvasTimer = null        })                 //点击send的监听事件        sendEle.addEventListener("click" , sendCaption)                 //input的回车监听事件        inputEle.addEventListener("keydown", function(e) {            var keynum = 0            keynum = window.event ? e.keyCode : e.which            if (keynum == 13) {                sendCaption()            }        })          var aaaa = function() {            alert(1)        }        aaaa()        // function b(aaaa){        //     return aaaa()        // }        // b()       }//end})()

相信看了这些案例你已经掌握了方法,更多精彩请关注创想鸟其它相关文章!

相关阅读:

HTML的table鼠标拖拽排序该如何实现

HTML 5之新增的特性该如何使用

怎样解决各种ie6-ie10的兼容问题

以上就是h5怎样通过canvas来实现滚动弹幕功能的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1545558.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月21日 17:04:18
下一篇 2025年12月21日 17:04:31

相关推荐

  • 用H5和C3实现简单的时钟效果

    这次给大家带来用h5和c3实现简单的时钟效果,用h5和c3实现简单的时钟效果的注意事项有哪些,下面就是实战案例,一起来看一下。 目的: 利用html5,css实现钟摆效果 知识点: 1) 利用position/left/top和calc()实现元素的水平和垂直居中; 2) 利用CSS3的animat…

    好文分享 2025年12月21日
    000
  • h5如何实现记住密码功能

    这次给大家带来h5如何实现记住密码功能,h5实现记住密码功能的注意事项有哪些,下面就是实战案例,一起来看一下。 HTML5 提供了两种在客户端存储数据的新方法: localStorage – 没有时间限制的数据存储 sessionStorage – 针对一个 session …

    好文分享 2025年12月21日
    000
  • H5的本地存储和本地数据库详细介绍

    这次给大家带来h5的本地存储和本地数据库详细介绍,使用h5的本地存储和本地数据库的注意事项有哪些,下面就是实战案例,一起来看一下。 本地存储 1.1 本地存储由来的背景 由于HTML4时代Cookie的大小、格式、存储数据格式等限制,网站应用如果想在浏览器端存储用户的部分信息,那么只能借助于Cook…

    好文分享 2025年12月21日
    000
  • 怎样用h5的sse服务器发送EventSource事件

    这次给大家带来怎样用h5的sse服务器发送eventsource事件,用h5的sse服务器发送eventsource事件的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 我前面文章讲过数据大屏,里面的数据时时更新。还有时时更新的股票数据,Facebook/Twitter 更新、估价更新、新的…

    好文分享 2025年12月21日
    000
  • HTML5的WEB界面中meta实列详解

    这次给大家带来html5的web界面中meta实列详解,使用html5的web界面中meta的注意事项有哪些,下面就是实战案例,一起来看一下。 简介 meta标签是HTML语言HEAD区的一个辅助性标签。 meta常用于定义页面的说明,关键字,最后修改日期,和其它的元数据。这些元数据将服务于浏览器(…

    好文分享 2025年12月21日
    000
  • 怎样用HTML实现滚动弹幕功能

    这次给大家带来怎样用html实现滚动弹幕功能,html实现滚动弹幕功能的注意事项有哪些,下面就是实战案例,一起来看一下。 主要的功能有;发送弹幕,设置弹幕的颜色,速度和类型,显示弹幕 已知缺陷:不能全屏 canvas没有做自适应 没有自定义播放器控件 没有根据播放时间显示相应的弹幕 弹幕不能实现悬停…

    好文分享 2025年12月21日
    000
  • 关于html5中图片抛物线运动技巧分享

    本文主要介绍了浅谈关于h5中图片抛物线运动的一些心得,详细的介绍了沿贝塞尔曲线运动的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能帮助到大家。 常见的, 物体/图片做抛物线或者更准确的说是沿贝塞尔曲线运动是H5开发中常见的需求, 那么如何快速的根据设计稿计算出运动路径是开发者首要解决…

    2025年12月21日
    000
  • canvas实现高阶贝塞尔曲线

    本文主要介绍了canvas实现高阶贝塞尔曲线(n阶贝塞尔曲线生成器),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 写在最前 由于原生的Canvas最高只支持到三阶贝塞尔曲线,那么我想添加多个控制点怎么办呢?(即便大部分复杂曲线都可以用3阶贝塞尔来模…

    2025年12月21日 好文分享
    000
  • canvas使用贝塞尔曲线平滑拟合折线段的方法详解

    本文主要介绍了基于canvas使用贝塞尔曲线平滑拟合折线段的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。 写在最前 本次分享一下在canvas中将绘制出来的折线段的棱角“磨平”,也就是通过贝塞尔曲线穿过各个描点来代替原有的折线图。 为…

    2025年12月21日 好文分享
    000
  • HTML5打开手机扫码功能及优缺点_html5教程技巧

    这篇文章主要介绍了html5打开手机扫码功能及优缺点的相关html5资料,对html5感兴趣的朋友可以参考下 1.解决的问题: 1.能够在微博客户端呼起摄像头扫描二维码并且解析; 2.能够在原生浏览器和微信客户端中扫描二维码并且解析; 2.优点: 立即学习“前端免费学习笔记(深入)”; web端或者…

    好文分享 2025年12月21日
    000
  • HTML5实现分享各大微信QQ等交流平台二维码功能

    本文主要介绍了html5实现分享到微信好友朋友圈qq好友qq空间微博二维码功能的实例代码,非常不错,具有参考借鉴价值,需要的朋友可以参考下,希望能帮助到大家。 这是分享按钮: 通用分享微信好友朋友圈QQQQ空间微博  这是js调用代码: var nativeShare = new NativeSha…

    好文分享 2025年12月21日
    000
  • HTML5 Ajax文件上传进度条如何显示

    这篇文章主要介绍了html5 ajax文件上传进度条是如何显示的,基于原生html5实现,不需要falsh支持,进度可以自定义显示,控制灵活,对html5上传进度条感兴趣的小伙伴们可以参考一下 原本打算使用jquery插件进行异步文件上传,比如uploadfy但是需要额外的支持,也有人用iframe…

    好文分享 2025年12月21日
    000
  • 巧用HTML5给按钮背景设计不同的动画

    如何巧用html5设计按钮背景不同动画特效,在该特效中,当鼠标滑过按钮时,使用css3   animation 来动画   background-size  和  background-position  属性,来实现各种背景动画效果。本文就和大家分享html5给按钮背景设计不同的动画简单实例。小编…

    2025年12月21日 好文分享
    000
  • 用h5做出微信的支付过程的实现步骤

    这次给大家实现的案例是用户在微信里打开网页的时候,也可以调用微信支付来完成下单功能。当然,微信官网的,开发文档也有很详细的介绍,但是今天我们来教大家怎样手动做出支付接口的开发。 以提交问题流程为例描述分答微信h5支付过程 1、提交问题domobiletutor方法 (1)费用 (2)支付说明 (3)…

    2025年12月21日
    000
  • 用H5做有特效的下拉框

    今天教大家如何用h5做出一个有小特效的下拉框。当你点击下拉框的内容会就出现在文本域中的一个小特效,下面来看一下详细案列代码。 HTML中有个下拉框,包含“风,雨,雷,电”,添加事件,当选择风时,文本域内出现选择 Title 风 雨 雷 电 function ShowToText(){ documen…

    好文分享 2025年12月21日
    000
  • html5中的DOM编程的实现步骤

    这次给大家介绍什么是dom编程,我们知道,dom是documentobjectmodel的缩写,中文名称是文档对象模型。同时dom也是处理html页面的标准编程接口,那么我们为什么要学习dom呢? 1,DOM可以让用户对网页元素进行交互操作 比如,当我点击了一个按钮,弹出一个对话框等操作。 2,DO…

    好文分享 2025年12月21日
    000
  • 服务端主动发送数据回客户端在H5里的实现步奏

    我们知道,在server sent event里,通过eventsource对象接收服务器发送事件的通知是有三个事件的,message, open, error这三种,今天就给大家演示一下服务端主动发送数据回客户端在h5里的实现步奏。 Server Sent Event Server Sent Ev…

    好文分享 2025年12月21日
    000
  • H5的多线程如何实现Web Worker

    很多人问过我,h5的多线程如何实现web worker的?当我们说到这个问题的时候首先你需要知道,什么是web worker,那么今天就来给大家解答下这个问题。 将JavaScript代码交给Web Worker在后台执行时,页面就可以在JavaScript运行期间依然可以响应用户操作,以防止出现页…

    好文分享 2025年12月21日
    000
  • h5里js和servlet实现文件上传的实现步骤

    这次教大家的是在h5里如何用js和servlet来实现文件上传,不过有一个前提条件,必须要是h5和jsp3.0版本,因为用到了新属性,获取file对象和后台得到part对象。 下面给大家看一个案列 前台jsp Insert title here name: 文件: 提交 function btu()…

    好文分享 2025年12月21日
    000
  • H5做出手机摇一摇功能的实现步骤

    今天教大家用html5来在网页里实现一个很炫酷的功能,手机摇一摇。如果你之前做过手机端的开发,可能对于这样的功能非常了解。但是下面,我们将在web上首次实现这个功能。 方向事件deviceorientation 该事件实在设备方向发生变化时触发, 使用方法如下; window.addEventLis…

    好文分享 2025年12月21日
    000

发表回复

登录后才能评论
关注微信