2018-10-09 21:07:53 +08:00
|
|
|
class CanvasCache{
|
2019-11-28 14:04:40 +08:00
|
|
|
constructor(noSmoothing, w, h, scale){
|
|
|
|
this.noSmoothing = noSmoothing
|
2018-10-09 21:07:53 +08:00
|
|
|
if(w){
|
|
|
|
this.resize(w, h, scale)
|
|
|
|
}
|
2020-03-09 20:36:57 +08:00
|
|
|
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")
|
2019-11-28 14:04:40 +08:00
|
|
|
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
|
|
|
|
this.canvas.width = this.w * this.scale
|
|
|
|
this.canvas.height = this.h * this.scale
|
|
|
|
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
|
2020-03-09 20:36:57 +08:00
|
|
|
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
|
2020-03-09 20:36:57 +08:00
|
|
|
var oldest = {index: index}
|
2019-03-20 22:00:30 +08:00
|
|
|
this.map.forEach((oldImg, id) => {
|
2020-03-09 20:36:57 +08:00
|
|
|
if(oldImg.index < oldest.index){
|
2019-03-20 22:00:30 +08:00
|
|
|
oldest.id = id
|
2020-03-09 20:36:57 +08:00
|
|
|
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)
|
|
|
|
}
|
2020-03-09 20:36:57 +08:00
|
|
|
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
|
|
|
|
config.ctx.drawImage(this.canvas,
|
|
|
|
img.x * z |0, img.y * z |0, img.w * z |0, img.h * z |0,
|
|
|
|
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()
|
2018-12-03 08:02:03 +08:00
|
|
|
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(){
|
2019-04-05 04:40:11 +08:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|