Home > Web Front-end > H5 Tutorial > Example explanation of using canvas to create barrage function in html5

Example explanation of using canvas to create barrage function in html5

巴扎黑
Release: 2017-09-14 09:43:38
Original
3857 people have browsed it

This article mainly introduces relevant information on examples of using canvas to implement the barrage function in HTML5. Friends who need it can refer to it.

I have recently started to develop a barrage video website and implemented the barrage function through canvas in html5. screen function.

So don’t talk nonsense, talk about your ideas first and then write the code.

Idea: In terms of page layout, a canvas is covered on the video window generated by the video tag, and this can be achieved using absolute positioning. The most important thing is that js controls the display of barrages on the canvas. Each barrage is packaged into an object. The properties contained in the object include the time when the barrage should appear, the color of the barrage, whether the barrage is moving and the barrage. text. The methods owned by the barrage object include: setting the horizontal and vertical coordinates of the barrage, and the movement function of the barrage. The principle of implementation is to monitor the event of the video starting to play, and generate a timer when the video starts playing. The timer traverses the cyclic barrage object array at every other time and draws the barrage at the appropriate position on the canvas according to the properties of the object. , in addition to the code for drawing the barrage, the timer also contains the code for updating the barrage array.

The picture below is a screenshot of the barrage effect

Then start the code directly:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

(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 < cavWidth && this.occupyPos) {

                    this.occupyPos = false

                    topObjs[this.topIndex].blank = true

                }

            }

            else{

                this.latestTime += 1

                if (this.latestTime > 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 < - cavWidth ) {

                    // capObjs.splice (i ,1)

                    // if excute this statement , will has fault because some item in array is null

                    // solution is : write a new function to refresh the array  

                // }

            }

        }

         

        //更新数组,当对象已经超出范围的时候从数组删除这个对象

        function refreshObjs(objs) {

            for (var i = objs.length - 1; i >= 0; i--) {

                if (objs[i].left < - cavWidth || objs[i].latestTime > 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 < 6) {

                    //     capHeight += 30

                    //     capHeight = capHeight > 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 < len ; i++) {

                    arr2[i] = arr1[i]

                }   

        }

 

        //color select event 用户发送弹幕的颜色控制代码

        colorUl.addEventListener("click", function( e ){

            var prevSelectItemId = ""

            switch (selectedColorIndex) {

                case 0:

                    prevSelectItemId = "colorItemFrist"

                    break;

                case 1:

                    prevSelectItemId = "colorItemSecond"

                    break;

                case 2:

                    prevSelectItemId = "colorItemThrid"

                    break;

                case 3:

                    prevSelectItemId = "colorItemFourth"

                    break;

                case 4:

                    prevSelectItemId = "colorItemFifth"

                    break;

                case 5:

                    prevSelectItemId = "colorItemSixth"

                    break;

                default:

                    // statements_def

                    break;

            }

            var prevSelectItem = document.getElementById(prevSelectItemId)

            prevSelectItem.className = ""

            var eventTarget = e.target

            eventTarget.className = "selectedColor"

            var eveTarId = eventTarget.id.substring(9)

            switch (eveTarId) {

                case "Frist":

                    selectedColorIndex = 0

                    break;

                case "Second":

                    selectedColorIndex = 1

                    break;

                case "Thrid":

                    selectedColorIndex = 2

                    break;

                case "Fourth":

                    selectedColorIndex = 3

                    break;

                case "Fifth":

                    selectedColorIndex = 4

                    break;

                case "Sixth":

                    selectedColorIndex = 5

                    break;

                default:

                    // statements_def

                    break;

            }

        }, false)

 

        video.addEventListener("playing" , function () {

            initCanvas()

        })

         

        //进度条改变执行代码

        video.addEventListener("timeupdate", function  () {

            var nowPlayTime = video.currentTime

            var diffTime = Math.abs(nowPlayTime - prevPlayTime)

            prevPlayTime = nowPlayTime

            if (diffTime > 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

})()

Copy after login

Hope it can be helpful to students who want to make barrages. You can also go to github to download the complete project code: gitbub project address

The above is the detailed content of Example explanation of using canvas to create barrage function in html5. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template