Last active
May 14, 2024 05:26
-
-
Save kallydev/be78960420f536503c28eb4f8de34879 to your computer and use it in GitHub Desktop.
Simple danmaku view implemented in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Danmaku { | |
elementQueue = null; | |
fps = 60; | |
trackSize = 8; | |
constructor(view) { | |
this.view = view; | |
this.view.width = 1920; | |
this.view.height = 1080; | |
this.context = view.getContext("2d"); | |
this.width = this.view.width; | |
this.height = this.view.height; | |
this.trackHeight = this.height / this.trackSize; | |
this.tracks = new Array(this.trackSize); | |
for (let i = 0; i < this.trackSize; i++) { | |
this.tracks[i] = new Track(this.trackHeight * (i + 1), this.width); | |
} | |
console.log(this) | |
} | |
add() { | |
for (let i = 0; i < this.trackSize; i++) { | |
let track = this.tracks[i]; | |
if (track.distance > 16) { | |
let element = this.poll(); | |
if (element != null) { | |
track.add(element.text, element.color); | |
} | |
break; | |
} | |
} | |
} | |
offer(text, color) { | |
let element = new Element(text, color, this.width); | |
if (this.elementQueue == null) { | |
this.elementQueue = element; | |
return | |
} | |
let tempElement = this.elementQueue; | |
while (tempElement != null) { | |
if (tempElement.nextElement == null) { | |
tempElement.nextElement = element; | |
return; | |
} | |
tempElement = tempElement.nextElement; | |
} | |
} | |
poll() { | |
let resultElement = this.elementQueue; | |
if (this.elementQueue != null) { | |
this.elementQueue = this.elementQueue.nextElement; | |
} | |
return resultElement; | |
} | |
draw() { | |
this.context.clearRect(0, 0, 1920, 1080); | |
this.context.save(); | |
for (let i = 0; i < this.trackSize; i++) { | |
let track = this.tracks[i]; | |
if (track.firstElement != null) { | |
let width = this.context.measureText(track.firstElement.text).width; | |
if (track.firstElement.left + width < 0) { | |
track.firstElement = track.firstElement.nextElement; | |
} | |
} | |
for (let tempElement = track.firstElement; tempElement != null; tempElement = tempElement.nextElement) { | |
this.context.font = "bold " + 64 + "px Arial"; | |
this.context.fillStyle = tempElement.color; | |
this.context.fillText(tempElement.text, tempElement.left, track.top); | |
tempElement.left -= 2; | |
if (tempElement.nextElement == null) { | |
let width = this.context.measureText(track.firstElement.text).width; | |
track.distance = this.width - (tempElement.left + width); | |
} | |
} | |
} | |
} | |
play() { | |
this.drawInterval = setInterval(() => { | |
this.draw(); | |
}, 1000 / this.fps); | |
this.putInterval = setInterval(() => { | |
this.add(); | |
}, 1000 / this.fps); | |
} | |
plase() { | |
clearInterval(this.drawInterval); | |
clearInterval(this.putInterval); | |
} | |
} | |
class Track { | |
constructor(top, left) { | |
this.top = top; | |
this.left = left; | |
this.distance = left; | |
this.firstElement = null; | |
} | |
add(text, color) { | |
let element = new Element(text, color, this.left); | |
if (this.firstElement == null) { | |
this.firstElement = element; | |
return | |
} | |
let tempElement = this.firstElement; | |
while (tempElement != null) { | |
if (tempElement.nextElement == null) { | |
tempElement.nextElement = element; | |
return; | |
} | |
tempElement = tempElement.nextElement; | |
} | |
} | |
} | |
class Element { | |
constructor(text, color, left) { | |
this.text = text; | |
this.color = color; | |
this.left = left; | |
this.nextElement = null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment