japanese-drum-game/public/src/js/canvascache.js

130 lines
2.6 KiB
JavaScript
Raw Normal View History

2018-10-09 21:07:53 +08:00
class CanvasCache{
constructor(...args){
this.init(...args)
}
init(noSmoothing, w, h, scale){
this.noSmoothing = noSmoothing
2018-10-09 21:07:53 +08:00
if(w){
this.resize(w, h, scale)
}
this.index = Number.MIN_SAFE_INTEGER
2018-10-09 21:07:53 +08:00
}
resize(w, h, scale){
2018-10-25 22:18:41 +08:00
if(this.canvas){
this.map.clear()
}else{
this.map = new Map()
this.canvas = document.createElement("canvas")
this.ctx = this.canvas.getContext("2d")
if(this.noSmoothing){
this.ctx.imageSmoothingEnabled = false
}
2018-10-25 22:18:41 +08:00
}
2018-10-09 21:07:53 +08:00
this.scale = scale
this.x = 0
this.y = 0
this.w = w
this.h = h
this.lastW = 0
this.lastH = 0
Bug fixes - Change song select mouse wheel song scrolling to be instant - Clicking on don chan in account settings toggles the animation - If the music is too long for the chart, the results screen is shown earlier - Fix weird BPM values freezing the browser (zero, negative, and very large) - Add a warning to the page when JavaScript is disabled in the browser - Fix Chrome auto dark mode by forcing light mode on the page - Add a meta keywords tag to the page - Fix plugin names getting cut off in the menu - Delay the function editing of the EditFunction class in plugins to the start() function instead of load() - When stopping one of the plugins, all the plugins have to be stopped in reverse order and started again so that patched code of a stopped plugin does not linger around - Fix importing plugins that have a SyntaxError - Fix plugins getting the same internal name when added without one, causing them to not appear in the plugin settings - Support editing args in EditFunction for plugins - Prevent multiple websockets from being opened - Fix page freezing after selecting Random song with no songs - Fix the back button being repeated twice when there are no songs - Fix /admin/users not accepting case insensitive usernames - Pressing enter on the Delete Account field does the expected action instead of refreshing the page - Better error message when custom folder access is denied - Fix being able to start netplay in custom songs after refreshing the page (#383) - Fix an error when importing songs from previous session and clicking on the white spot where you normally start multiplayer session - Fix canvas elements becoming smaller than 1x1 resolution and crashing the game (#390) - Fix song frame shadow cache on song select not being cleared when resizing the browser window, causing it to become blurry - Fix a pause-restart error when you hit both confirm keys on the restart button
2022-02-18 04:50:07 +08:00
this.canvas.width = Math.max(1, this.w * this.scale)
this.canvas.height = Math.max(1, this.h * this.scale)
2018-10-09 21:07:53 +08:00
this.ctx.scale(this.scale, this.scale)
}
2018-10-25 22:18:41 +08:00
get(config, callback, setOnly){
2018-10-09 21:07:53 +08:00
var img = this.map.get(config.id)
2018-10-25 22:18:41 +08:00
if(img && setOnly || !img && !callback){
return
}
2018-10-09 21:07:53 +08:00
var saved = false
var index = this.index++
2018-10-09 21:07:53 +08:00
if(!img){
var w = config.w
var h = config.h
2019-03-20 22:00:30 +08:00
this.x += this.lastW + (this.lastW ? 1 : 0)
2018-10-09 21:07:53 +08:00
if(this.x + w > this.w){
this.x = 0
this.y += this.lastH + 1
}
2019-03-20 22:00:30 +08:00
if(this.y + h > this.h){
var clear = true
var oldest = {index: index}
2019-03-20 22:00:30 +08:00
this.map.forEach((oldImg, id) => {
if(oldImg.index < oldest.index){
2019-03-20 22:00:30 +08:00
oldest.id = id
oldest.index = oldImg.index
2019-03-20 22:00:30 +08:00
}
})
var oldImg = this.map.get(oldest.id)
this.map.delete(oldest.id)
img = {
x: oldImg.x,
y: oldImg.y,
w: w,
h: h
}
}else{
var clear = false
this.lastW = w
this.lastH = Math.max(this.lastH, h)
img = {
x: this.x,
y: this.y,
w: w,
h: h
}
2018-10-09 21:07:53 +08:00
}
saved = true
this.ctx.save()
this.ctx.translate(img.x |0, img.y |0)
2019-03-20 22:00:30 +08:00
if(clear){
this.ctx.clearRect(0, 0, (img.w |0) + 1, (img.h |0) + 1)
}
2018-10-09 21:07:53 +08:00
this.ctx.beginPath()
this.ctx.rect(0, 0, img.w |0, img.h |0)
this.ctx.clip()
2019-03-20 22:00:30 +08:00
this.map.set(config.id, img)
2018-10-09 21:07:53 +08:00
callback(this.ctx)
}
img.index = index
2018-10-25 22:18:41 +08:00
if(setOnly){
this.ctx.restore()
return
}
2018-10-09 21:07:53 +08:00
var z = this.scale
var sx = (img.x + (config.sx || 0)) * z |0
var sy = (img.y + (config.sy || 0)) * z |0
var sw = (config.sw || img.w) * z |0
var sh = (config.sh || img.h) * z |0
2018-10-09 21:07:53 +08:00
config.ctx.drawImage(this.canvas,
sx, sy, sw, sh,
2018-10-09 21:07:53 +08:00
config.x |0, config.y |0, config.w |0, config.h |0
)
if(saved){
this.ctx.restore()
}
}
2018-10-25 22:18:41 +08:00
set(config, callback){
return this.get(config, callback, true)
}
2018-12-03 01:45:03 +08:00
clear(){
this.x = 0
this.y = 0
this.lastW = 0
this.lastH = 0
this.map.clear()
this.ctx.clearRect(0, 0, this.w, this.h)
2018-12-03 01:45:03 +08:00
}
2018-10-09 21:07:53 +08:00
clean(){
if(!this.canvas){
return
}
2019-03-20 22:00:30 +08:00
this.resize(1, 1, 1)
2018-10-09 21:07:53 +08:00
delete this.map
delete this.ctx
delete this.canvas
}
}