Songselect: Add cache for shadows
This commit is contained in:
parent
a5f2f2b8de
commit
190beb224d
@ -50,6 +50,7 @@
|
|||||||
<script src="/src/js/canvasdraw.js"></script>
|
<script src="/src/js/canvasdraw.js"></script>
|
||||||
<script src="/src/js/loader.js"></script>
|
<script src="/src/js/loader.js"></script>
|
||||||
<script src="/src/js/canvastest.js"></script>
|
<script src="/src/js/canvastest.js"></script>
|
||||||
|
<script src="/src/js/canvascache.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -34,8 +34,6 @@
|
|||||||
}
|
}
|
||||||
.click-to-continue::before{
|
.click-to-continue::before{
|
||||||
-webkit-text-stroke: 0.25em #f00;
|
-webkit-text-stroke: 0.25em #f00;
|
||||||
|
filter: blur(0.3vmin);
|
||||||
left: auto;
|
left: auto;
|
||||||
}
|
}
|
||||||
#screen:not(.disable-blur) .click-to-continue::before{
|
|
||||||
filter: blur(0.3vmin);
|
|
||||||
}
|
|
||||||
|
67
public/src/js/canvascache.js
Normal file
67
public/src/js/canvascache.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
class CanvasCache{
|
||||||
|
constructor(w, h, scale){
|
||||||
|
this.canvas = document.createElement("canvas")
|
||||||
|
this.ctx = this.canvas.getContext("2d")
|
||||||
|
this.map = new Map()
|
||||||
|
if(w){
|
||||||
|
this.resize(w, h, scale)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resize(w, h, scale){
|
||||||
|
this.map.clear()
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
get(config, callback){
|
||||||
|
var img = this.map.get(config.id)
|
||||||
|
var saved = false
|
||||||
|
if(!img){
|
||||||
|
var w = config.w
|
||||||
|
var h = config.h
|
||||||
|
this.x += this.lastW + 1
|
||||||
|
if(this.x + w > this.w){
|
||||||
|
this.x = 0
|
||||||
|
this.y += this.lastH + 1
|
||||||
|
}
|
||||||
|
this.lastW = w
|
||||||
|
this.lastH = Math.max(this.lastH, h)
|
||||||
|
img = {
|
||||||
|
x: this.x,
|
||||||
|
y: this.y,
|
||||||
|
w: w,
|
||||||
|
h: h
|
||||||
|
}
|
||||||
|
this.map.set(config.id, img)
|
||||||
|
|
||||||
|
saved = true
|
||||||
|
this.ctx.save()
|
||||||
|
this.ctx.translate(img.x |0, img.y |0)
|
||||||
|
this.ctx.beginPath()
|
||||||
|
this.ctx.rect(0, 0, img.w |0, img.h |0)
|
||||||
|
this.ctx.clip()
|
||||||
|
|
||||||
|
callback(this.ctx)
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clean(){
|
||||||
|
delete this.map
|
||||||
|
delete this.ctx
|
||||||
|
delete this.canvas
|
||||||
|
}
|
||||||
|
}
|
@ -60,6 +60,10 @@
|
|||||||
uppercaseDigit: /[A-ZA-Z0-90-9]/
|
uppercaseDigit: /[A-ZA-Z0-90-9]/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.songFrameCache = new CanvasCache()
|
||||||
|
this.diffStarCache = new CanvasCache()
|
||||||
|
this.crownCache = new CanvasCache()
|
||||||
|
|
||||||
this.tmpCanvas = document.createElement("canvas")
|
this.tmpCanvas = document.createElement("canvas")
|
||||||
this.tmpCtx = this.tmpCanvas.getContext("2d")
|
this.tmpCtx = this.tmpCanvas.getContext("2d")
|
||||||
}
|
}
|
||||||
@ -95,15 +99,34 @@
|
|||||||
|
|
||||||
ctx.save()
|
ctx.save()
|
||||||
|
|
||||||
this.shadow({
|
var shadowBg = (ctx, noForce) => {
|
||||||
ctx: ctx,
|
this.shadow({
|
||||||
fill: "rgba(0, 0, 0, 0.5)",
|
ctx: ctx,
|
||||||
blur: 10,
|
fill: "rgba(0, 0, 0, 0.5)",
|
||||||
x: 5,
|
blur: 10,
|
||||||
y: 5
|
x: 5,
|
||||||
})
|
y: 5,
|
||||||
ctx.fillStyle = "#000"
|
force: !noForce
|
||||||
ctx.fillRect(x, y, w, h)
|
})
|
||||||
|
ctx.fillStyle = "#000"
|
||||||
|
ctx.fillRect(0, 0, w, h)
|
||||||
|
}
|
||||||
|
if(config.cached){
|
||||||
|
if(this.songFrameCache.w !== config.frameCache.w){
|
||||||
|
this.songFrameCache.resize(config.frameCache.w, config.frameCache.h, config.frameCache.ratio)
|
||||||
|
}
|
||||||
|
this.songFrameCache.get({
|
||||||
|
ctx: ctx,
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
w: w + 15,
|
||||||
|
h: h + 15,
|
||||||
|
id: "shadow" + config.cached
|
||||||
|
}, shadowBg)
|
||||||
|
}else{
|
||||||
|
ctx.translate(x, y)
|
||||||
|
shadowBg(ctx, true)
|
||||||
|
}
|
||||||
|
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
ctx.save()
|
ctx.save()
|
||||||
@ -211,15 +234,7 @@
|
|||||||
var ctx = config.ctx
|
var ctx = config.ctx
|
||||||
var inputText = config.text
|
var inputText = config.text
|
||||||
var mul = config.fontSize / 40
|
var mul = config.fontSize / 40
|
||||||
var ura = false
|
|
||||||
|
|
||||||
if(inputText.endsWith(" (裏)")){
|
|
||||||
inputText = inputText.slice(0, -4)
|
|
||||||
ura = true
|
|
||||||
}else if(inputText.endsWith("(裏)")){
|
|
||||||
inputText = inputText.slice(0, -3)
|
|
||||||
ura = true
|
|
||||||
}
|
|
||||||
var string = inputText.split("")
|
var string = inputText.split("")
|
||||||
var drawn = []
|
var drawn = []
|
||||||
|
|
||||||
@ -246,7 +261,7 @@
|
|||||||
}else if(r.tilde.test(symbol)){
|
}else if(r.tilde.test(symbol)){
|
||||||
// Rotated hyphen, tilde
|
// Rotated hyphen, tilde
|
||||||
if(symbol === "~"){
|
if(symbol === "~"){
|
||||||
symbol = "~"
|
symbol = "~"
|
||||||
}
|
}
|
||||||
drawn.push({text: symbol, x: 0, y: 2, h: 35, rotate: true})
|
drawn.push({text: symbol, x: 0, y: 2, h: 35, rotate: true})
|
||||||
}else if(r.tall.test(symbol)){
|
}else if(r.tall.test(symbol)){
|
||||||
@ -281,18 +296,8 @@
|
|||||||
ctx.save()
|
ctx.save()
|
||||||
ctx.translate(config.x, config.y)
|
ctx.translate(config.x, config.y)
|
||||||
|
|
||||||
var scale = 1
|
if(config.height && drawnHeight > config.height){
|
||||||
if(config.height){
|
ctx.scale(1, config.height / drawnHeight)
|
||||||
var height = config.height - (ura ? 52 * mul : 0)
|
|
||||||
if(drawnHeight > height){
|
|
||||||
scale = height / drawnHeight
|
|
||||||
ctx.scale(1, scale)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ura){
|
|
||||||
// Circled ura
|
|
||||||
drawn.push({text: "裏", x: 0, y: 18, h: 52, ura: true, scale: [1, 1 / scale]})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var actions = []
|
var actions = []
|
||||||
@ -322,7 +327,7 @@
|
|||||||
currentX += 20 * mul
|
currentX += 20 * mul
|
||||||
}
|
}
|
||||||
var currentY = offsetY + symbol.y * mul
|
var currentY = offsetY + symbol.y * mul
|
||||||
if(symbol.rotate || symbol.scale || symbol.svg || symbol.ura){
|
if(symbol.rotate || symbol.scale || symbol.svg){
|
||||||
saved = true
|
saved = true
|
||||||
ctx.save()
|
ctx.save()
|
||||||
|
|
||||||
@ -347,23 +352,7 @@
|
|||||||
}else{
|
}else{
|
||||||
ctx.textAlign = "center"
|
ctx.textAlign = "center"
|
||||||
}
|
}
|
||||||
if(symbol.ura){
|
ctx[action + "Text"](symbol.text, currentX, currentY)
|
||||||
ctx.font = (30 * mul) + "px Meiryo"
|
|
||||||
ctx.textBaseline = "center"
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.arc(currentX, currentY + (21.5 * mul), (18 * mul), 0, Math.PI * 2)
|
|
||||||
if(action === "stroke"){
|
|
||||||
ctx.fillStyle = config.outline
|
|
||||||
ctx.fill()
|
|
||||||
}else if(action === "fill"){
|
|
||||||
ctx.strokeStyle = config.fill
|
|
||||||
ctx.lineWidth = 2.5 * mul
|
|
||||||
ctx.fillText(symbol.text, currentX, currentY)
|
|
||||||
}
|
|
||||||
ctx.stroke()
|
|
||||||
}else{
|
|
||||||
ctx[action + "Text"](symbol.text, currentX, currentY)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
offsetY += symbol.h * mul
|
offsetY += symbol.h * mul
|
||||||
if(saved){
|
if(saved){
|
||||||
@ -463,7 +452,8 @@
|
|||||||
fill: "rgba(0, 0, 0, " + (1 / (layer.shadow[3] || 2)) + ")",
|
fill: "rgba(0, 0, 0, " + (1 / (layer.shadow[3] || 2)) + ")",
|
||||||
blur: layer.shadow[2],
|
blur: layer.shadow[2],
|
||||||
x: layer.shadow[0],
|
x: layer.shadow[0],
|
||||||
y: layer.shadow[1]
|
y: layer.shadow[1],
|
||||||
|
force: config.forceShadow
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
var offsetX = 0
|
var offsetX = 0
|
||||||
@ -629,19 +619,35 @@
|
|||||||
diffStar(config){
|
diffStar(config){
|
||||||
var ctx = config.ctx
|
var ctx = config.ctx
|
||||||
ctx.save()
|
ctx.save()
|
||||||
ctx.fillStyle = config.songSel ? "#fff" : "#f72568"
|
|
||||||
if(config.songSel){
|
if(config.songSel){
|
||||||
this.shadow({
|
if(this.diffStarCache.scale !== config.ratio){
|
||||||
|
this.diffStarCache.resize(30, 30, config.ratio)
|
||||||
|
}
|
||||||
|
var offset = 30 / 2 - 18 / 2
|
||||||
|
this.diffStarCache.get({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
fill: "#fff",
|
x: config.x - 9 - offset,
|
||||||
blur: 10
|
y: config.y - 9 - offset,
|
||||||
|
w: 30,
|
||||||
|
h: 30,
|
||||||
|
id: "star"
|
||||||
|
}, ctx => {
|
||||||
|
ctx.fillStyle = "#fff"
|
||||||
|
this.shadow({
|
||||||
|
ctx: ctx,
|
||||||
|
fill: "#fff",
|
||||||
|
blur: 10,
|
||||||
|
force: true
|
||||||
|
})
|
||||||
|
ctx.translate(offset, offset)
|
||||||
|
ctx.fill(this.diffStarPath)
|
||||||
})
|
})
|
||||||
ctx.translate(config.x - 9, config.y - 9)
|
|
||||||
}else{
|
}else{
|
||||||
|
ctx.fillStyle = "#f72568"
|
||||||
ctx.translate(config.x - 10.5, config.y - 9.5)
|
ctx.translate(config.x - 10.5, config.y - 9.5)
|
||||||
ctx.scale(1.1, 1.1)
|
ctx.scale(1.1, 1.1)
|
||||||
|
ctx.fill(this.diffStarPath)
|
||||||
}
|
}
|
||||||
ctx.fill(this.diffStarPath)
|
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,14 +714,27 @@
|
|||||||
ctx.translate(-47, -39)
|
ctx.translate(-47, -39)
|
||||||
ctx.miterLimit = 1.7
|
ctx.miterLimit = 1.7
|
||||||
|
|
||||||
ctx.save()
|
if(!this.crownCache.w){
|
||||||
ctx.strokeStyle = "#fff"
|
this.crownCache.resize(140, 140, config.ratio)
|
||||||
ctx.lineWidth = 35
|
|
||||||
if(!disableBlur){
|
|
||||||
ctx.filter = "blur(1.5px)"
|
|
||||||
}
|
}
|
||||||
ctx.stroke(this.crownPath)
|
var offset = 140 / 2 - 94 / 2
|
||||||
ctx.restore()
|
this.crownCache.get({
|
||||||
|
ctx: ctx,
|
||||||
|
x: -offset,
|
||||||
|
y: -offset,
|
||||||
|
w: 140,
|
||||||
|
h: 140,
|
||||||
|
id: "crown"
|
||||||
|
}, ctx => {
|
||||||
|
ctx.save()
|
||||||
|
ctx.translate(offset, offset)
|
||||||
|
ctx.strokeStyle = "#fff"
|
||||||
|
ctx.lineWidth = 35
|
||||||
|
ctx.miterLimit = 1.7
|
||||||
|
ctx.filter = "blur(1.5px)"
|
||||||
|
ctx.stroke(this.crownPath)
|
||||||
|
ctx.restore()
|
||||||
|
})
|
||||||
|
|
||||||
if(config.shine){
|
if(config.shine){
|
||||||
ctx.strokeStyle = "#fff"
|
ctx.strokeStyle = "#fff"
|
||||||
@ -770,7 +789,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
shadow(config){
|
shadow(config){
|
||||||
if(!disableBlur){
|
if(!disableBlur || config.force){
|
||||||
var ctx = config.ctx
|
var ctx = config.ctx
|
||||||
if(config.fill){
|
if(config.fill){
|
||||||
ctx.shadowColor = config.fill
|
ctx.shadowColor = config.fill
|
||||||
@ -790,4 +809,12 @@
|
|||||||
getMS(){
|
getMS(){
|
||||||
return +new Date
|
return +new Date
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clean(){
|
||||||
|
this.songFrameCache.clean()
|
||||||
|
this.diffStarCache.clean()
|
||||||
|
this.crownCache.clean()
|
||||||
|
delete this.tmpCtx
|
||||||
|
delete this.tmpCanvas
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ class CanvasTest{
|
|||||||
this.canvas.height = height
|
this.canvas.height = height
|
||||||
this.ctx = this.canvas.getContext("2d")
|
this.ctx = this.canvas.getContext("2d")
|
||||||
this.ctx.scale(pixelRatio, pixelRatio)
|
this.ctx.scale(pixelRatio, pixelRatio)
|
||||||
|
this.ratio = pixelRatio
|
||||||
this.draw = new CanvasDraw()
|
this.draw = new CanvasDraw()
|
||||||
this.font = "serif"
|
this.font = "serif"
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ class CanvasTest{
|
|||||||
innerBorder: this.songAsset.innerBorder,
|
innerBorder: this.songAsset.innerBorder,
|
||||||
background: "#efb058",
|
background: "#efb058",
|
||||||
borderStyle: ["#ffe7bd", "#c68229"],
|
borderStyle: ["#ffe7bd", "#c68229"],
|
||||||
|
ratio: this.ratio,
|
||||||
innerContent: () => {}
|
innerContent: () => {}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -138,6 +140,7 @@ class CanvasTest{
|
|||||||
this.ctx.fillText(text, x, y)
|
this.ctx.fillText(text, x, y)
|
||||||
}
|
}
|
||||||
clean(){
|
clean(){
|
||||||
|
this.draw.clean()
|
||||||
delete this.ctx
|
delete this.ctx
|
||||||
delete this.canvas
|
delete this.canvas
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,6 @@ class Loader{
|
|||||||
if(result > 1000 / 50){
|
if(result > 1000 / 50){
|
||||||
// Less than 50 fps with blur enabled
|
// Less than 50 fps with blur enabled
|
||||||
disableBlur = true
|
disableBlur = true
|
||||||
this.screen.classList.add("disable-blur")
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ class Scoresheet{
|
|||||||
this.numbers = "001122334455667788900112233445".split("")
|
this.numbers = "001122334455667788900112233445".split("")
|
||||||
|
|
||||||
this.draw = new CanvasDraw()
|
this.draw = new CanvasDraw()
|
||||||
|
this.canvasCache = new CanvasCache()
|
||||||
|
|
||||||
this.gamepad = new Gamepad({
|
this.gamepad = new Gamepad({
|
||||||
"13": ["a", "b", "start", "ls", "rs"]
|
"13": ["a", "b", "start", "ls", "rs"]
|
||||||
@ -130,6 +131,8 @@ class Scoresheet{
|
|||||||
ctx.scale(ratio, ratio)
|
ctx.scale(ratio, ratio)
|
||||||
this.canvas.style.width = (winW / this.pixelRatio) + "px"
|
this.canvas.style.width = (winW / this.pixelRatio) + "px"
|
||||||
this.canvas.style.height = (winH / this.pixelRatio) + "px"
|
this.canvas.style.height = (winH / this.pixelRatio) + "px"
|
||||||
|
|
||||||
|
this.canvasCache.resize(winW / ratio, 80 + 1, ratio)
|
||||||
}else if(!document.hasFocus() && this.state.screen === "scoresShown"){
|
}else if(!document.hasFocus() && this.state.screen === "scoresShown"){
|
||||||
return
|
return
|
||||||
}else{
|
}else{
|
||||||
@ -237,36 +240,47 @@ class Scoresheet{
|
|||||||
ctx.scale(ratio, ratio)
|
ctx.scale(ratio, ratio)
|
||||||
ctx.translate(frameLeft, frameTop)
|
ctx.translate(frameLeft, frameTop)
|
||||||
|
|
||||||
this.draw.layeredText({
|
this.canvasCache.get({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: "成績発表",
|
x: 0,
|
||||||
fontSize: 48,
|
y: 0,
|
||||||
fontFamily: this.font,
|
w: winW,
|
||||||
x: 23,
|
h: 80,
|
||||||
y: 15,
|
id: "results"
|
||||||
letterSpacing: 3
|
}, ctx => {
|
||||||
}, [
|
this.draw.layeredText({
|
||||||
{x: -2, y: -2, outline: "#000", letterBorder: 22},
|
ctx: ctx,
|
||||||
{},
|
text: "成績発表",
|
||||||
{x: 2, y: 2, shadow: [2, 2, 7]},
|
fontSize: 48,
|
||||||
{x: 2, y: 2, outline: "#ad1516", letterBorder: 10},
|
fontFamily: this.font,
|
||||||
{x: -2, y: -2, outline: "#ff797b"},
|
x: 23,
|
||||||
{outline: "#f70808"},
|
y: 15,
|
||||||
{fill: "#fff", shadow: [-1, 1, 3, 1.5]}
|
letterSpacing: 3,
|
||||||
])
|
forceShadow: true
|
||||||
|
}, [
|
||||||
this.draw.layeredText({
|
{x: -2, y: -2, outline: "#000", letterBorder: 22},
|
||||||
ctx: ctx,
|
{},
|
||||||
text: this.results.title,
|
{x: 2, y: 2, shadow: [2, 2, 7]},
|
||||||
fontSize: 40,
|
{x: 2, y: 2, outline: "#ad1516", letterBorder: 10},
|
||||||
fontFamily: this.font,
|
{x: -2, y: -2, outline: "#ff797b"},
|
||||||
x: 1257,
|
{outline: "#f70808"},
|
||||||
y: 20,
|
{fill: "#fff", shadow: [-1, 1, 3, 1.5]}
|
||||||
align: "right"
|
])
|
||||||
}, [
|
|
||||||
{outline: "#000", letterBorder: 10, shadow: [1, 1, 3]},
|
this.draw.layeredText({
|
||||||
{fill: "#fff"}
|
ctx: ctx,
|
||||||
])
|
text: this.results.title,
|
||||||
|
fontSize: 40,
|
||||||
|
fontFamily: this.font,
|
||||||
|
x: 1257,
|
||||||
|
y: 20,
|
||||||
|
align: "right",
|
||||||
|
forceShadow: true
|
||||||
|
}, [
|
||||||
|
{outline: "#000", letterBorder: 10, shadow: [1, 1, 3]},
|
||||||
|
{fill: "#fff"}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
ctx.save()
|
ctx.save()
|
||||||
for(var p = 0; p < players; p++){
|
for(var p = 0; p < players; p++){
|
||||||
@ -470,7 +484,8 @@ class Scoresheet{
|
|||||||
x: 395,
|
x: 395,
|
||||||
y: 218,
|
y: 218,
|
||||||
scale: crownScale,
|
scale: crownScale,
|
||||||
shine: shine
|
shine: shine,
|
||||||
|
ratio: ratio
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.restore()
|
ctx.restore()
|
||||||
@ -649,6 +664,8 @@ class Scoresheet{
|
|||||||
}
|
}
|
||||||
|
|
||||||
clean(){
|
clean(){
|
||||||
|
this.draw.clean()
|
||||||
|
this.canvasCache.clean()
|
||||||
assets.sounds["bgm_result"].stop()
|
assets.sounds["bgm_result"].stop()
|
||||||
snd.musicGain.fadeIn()
|
snd.musicGain.fadeIn()
|
||||||
this.redrawRunning = false
|
this.redrawRunning = false
|
||||||
|
@ -132,13 +132,19 @@ class SongSelect{
|
|||||||
marginLeft: 18,
|
marginLeft: 18,
|
||||||
width: 82,
|
width: 82,
|
||||||
selectedWidth: 382,
|
selectedWidth: 382,
|
||||||
|
fullWidth: 912,
|
||||||
height: 452,
|
height: 452,
|
||||||
|
fullHeight: 502,
|
||||||
border: 6,
|
border: 6,
|
||||||
innerBorder: 8,
|
innerBorder: 8,
|
||||||
letterBorder: 12
|
letterBorder: 12
|
||||||
}
|
}
|
||||||
|
|
||||||
this.draw = new CanvasDraw()
|
this.draw = new CanvasDraw()
|
||||||
|
this.songTitleCache = new CanvasCache()
|
||||||
|
this.selectTextCache = new CanvasCache()
|
||||||
|
this.categoryCache = new CanvasCache()
|
||||||
|
this.difficultyCache = new CanvasCache()
|
||||||
|
|
||||||
this.difficulty = ["かんたん", "ふつう", "むずかしい", "おに"]
|
this.difficulty = ["かんたん", "ふつう", "むずかしい", "おに"]
|
||||||
this.difficultyId = ["easy", "normal", "hard", "oni"]
|
this.difficultyId = ["easy", "normal", "hard", "oni"]
|
||||||
@ -530,6 +536,24 @@ class SongSelect{
|
|||||||
ctx.scale(ratio, ratio)
|
ctx.scale(ratio, ratio)
|
||||||
this.canvas.style.width = (winW / this.pixelRatio) + "px"
|
this.canvas.style.width = (winW / this.pixelRatio) + "px"
|
||||||
this.canvas.style.height = (winH / this.pixelRatio) + "px"
|
this.canvas.style.height = (winH / this.pixelRatio) + "px"
|
||||||
|
|
||||||
|
var borders = (this.songAsset.border + this.songAsset.innerBorder) * 2
|
||||||
|
this.songTitleCache.resize((this.songAsset.width - borders + 1) * this.songs.length, (this.songAsset.height - borders + 1) * 2, ratio + 0.5)
|
||||||
|
|
||||||
|
this.selectTextCache.resize((280 + 53 + 60 + 1) * 2, this.songAsset.marginTop + 15, ratio + 0.5)
|
||||||
|
|
||||||
|
var categories = 0
|
||||||
|
var lastCategory
|
||||||
|
this.songs.forEach(song => {
|
||||||
|
var cat = (song.category || "") + song.skin.outline
|
||||||
|
if(lastCategory !== cat){
|
||||||
|
lastCategory = cat
|
||||||
|
categories++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.categoryCache.resize(280, (this.songAsset.marginTop + 1) * categories , ratio + 0.5)
|
||||||
|
|
||||||
|
this.difficultyCache.resize((44 + 56 + 2) * 4, 135 + 10, ratio + 0.5)
|
||||||
}else if(!document.hasFocus()){
|
}else if(!document.hasFocus()){
|
||||||
this.pointer(false)
|
this.pointer(false)
|
||||||
return
|
return
|
||||||
@ -567,39 +591,60 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(screen === "title" || screen === "titleFadeIn" || screen === "song"){
|
if(screen === "title" || screen === "titleFadeIn" || screen === "song"){
|
||||||
this.draw.layeredText({
|
this.selectTextCache.get({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: "曲をえらぶ",
|
x: frameLeft,
|
||||||
fontSize: 48,
|
y: frameTop,
|
||||||
fontFamily: this.font,
|
w: 280 + 53 + 60,
|
||||||
x: frameLeft + 53,
|
h: this.songAsset.marginTop + 15,
|
||||||
y: frameTop + 30,
|
id: "song"
|
||||||
letterSpacing: 2
|
}, ctx => {
|
||||||
}, [
|
this.draw.layeredText({
|
||||||
{x: -2, y: -2, outline: "#000", letterBorder: 22},
|
ctx: ctx,
|
||||||
{},
|
text: "曲をえらぶ",
|
||||||
{x: 2, y: 2, shadow: [3, 3, 3]},
|
fontSize: 48,
|
||||||
{x: 2, y: 2, outline: "#ad1516", letterBorder: 10},
|
fontFamily: this.font,
|
||||||
{x: -2, y: -2, outline: "#ff797b"},
|
x: 53,
|
||||||
{outline: "#f70808"},
|
y: 30,
|
||||||
{fill: "#fff", shadow: [-1, 1, 3, 1.5]}
|
letterSpacing: 2,
|
||||||
])
|
forceShadow: true
|
||||||
|
}, [
|
||||||
|
{x: -2, y: -2, outline: "#000", letterBorder: 22},
|
||||||
|
{},
|
||||||
|
{x: 2, y: 2, shadow: [3, 3, 3]},
|
||||||
|
{x: 2, y: 2, outline: "#ad1516", letterBorder: 10},
|
||||||
|
{x: -2, y: -2, outline: "#ff797b"},
|
||||||
|
{outline: "#f70808"},
|
||||||
|
{fill: "#fff", shadow: [-1, 1, 3, 1.5]}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
var category = this.songs[this.selectedSong].category
|
var category = this.songs[this.selectedSong].category
|
||||||
if(category){
|
if(category){
|
||||||
this.draw.layeredText({
|
var selectedSong = this.songs[this.selectedSong]
|
||||||
|
this.categoryCache.get({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: category,
|
x: winW / 2 - 280 / 2,
|
||||||
fontSize: 40,
|
y: frameTop,
|
||||||
fontFamily: this.font,
|
w: 280,
|
||||||
x: winW / 2,
|
h: this.songAsset.marginTop,
|
||||||
y: frameTop + 38,
|
id: category + selectedSong.skin.outline
|
||||||
width: 255,
|
}, ctx => {
|
||||||
align: "center"
|
this.draw.layeredText({
|
||||||
}, [
|
ctx: ctx,
|
||||||
{outline: this.songs[this.selectedSong].skin.outline, letterBorder: 12, shadow: [3, 3, 3]},
|
text: category,
|
||||||
{fill: "#fff"}
|
fontSize: 40,
|
||||||
])
|
fontFamily: this.font,
|
||||||
|
x: 280 / 2,
|
||||||
|
y: 38,
|
||||||
|
width: 255,
|
||||||
|
align: "center",
|
||||||
|
forceShadow: true
|
||||||
|
}, [
|
||||||
|
{outline: selectedSong.skin.outline, letterBorder: 12, shadow: [3, 3, 3]},
|
||||||
|
{fill: "#fff"}
|
||||||
|
])
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,6 +713,12 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.songFrameCache = {
|
||||||
|
w: this.songAsset.width + this.songAsset.selectedWidth + this.songAsset.fullWidth + (15 + 1) * 3,
|
||||||
|
h: this.songAsset.fullHeight + 16,
|
||||||
|
ratio: ratio
|
||||||
|
}
|
||||||
|
|
||||||
if(screen === "title" || screen === "titleFadeIn" || screen === "song"){
|
if(screen === "title" || screen === "titleFadeIn" || screen === "song"){
|
||||||
for(var i = this.selectedSong - 1; ; i--){
|
for(var i = this.selectedSong - 1; ; i--){
|
||||||
var highlight = 0
|
var highlight = 0
|
||||||
@ -726,8 +777,8 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
var selectedHeight = this.songAsset.height
|
var selectedHeight = this.songAsset.height
|
||||||
if(screen === "difficulty"){
|
if(screen === "difficulty"){
|
||||||
selectedWidth = 912
|
selectedWidth = this.songAsset.fullWidth
|
||||||
selectedHeight = 502
|
selectedHeight = this.songAsset.fullHeight
|
||||||
highlight = 0
|
highlight = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,29 +795,41 @@ class SongSelect{
|
|||||||
highlight: highlight,
|
highlight: highlight,
|
||||||
noCrop: screen === "difficulty",
|
noCrop: screen === "difficulty",
|
||||||
animateMS: this.state.moveMS,
|
animateMS: this.state.moveMS,
|
||||||
|
cached: selectedWidth === this.songAsset.fullWidth ? 3 : (selectedWidth === this.songAsset.selectedWidth ? 2 : (selectedWidth === this.songAsset.width ? 1 : 0)),
|
||||||
|
frameCache: this.songFrameCache,
|
||||||
innerContent: (x, y, w, h) => {
|
innerContent: (x, y, w, h) => {
|
||||||
ctx.strokeStyle = "#000"
|
ctx.strokeStyle = "#000"
|
||||||
if(screen === "title" || screen === "titleFadeIn" || screen === "song"){
|
if(screen === "title" || screen === "titleFadeIn" || screen === "song"){
|
||||||
var opened = ((selectedWidth - this.songAsset.width) / (this.songAsset.selectedWidth - this.songAsset.width))
|
var opened = ((selectedWidth - this.songAsset.width) / (this.songAsset.selectedWidth - this.songAsset.width))
|
||||||
var songSel = true
|
var songSel = true
|
||||||
}else{
|
}else{
|
||||||
this.draw.layeredText({
|
this.selectTextCache.get({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: "むずかしさをえらぶ",
|
x: x - 144 - 53,
|
||||||
fontSize: 46,
|
y: y - 24 - 30,
|
||||||
fontFamily: this.font,
|
w: 280 + 53 + 60,
|
||||||
x: x - 144,
|
h: this.songAsset.marginTop + 15,
|
||||||
y: y - 24,
|
id: "difficulty"
|
||||||
width: 280
|
}, ctx => {
|
||||||
}, [
|
this.draw.layeredText({
|
||||||
{x: -2, y: -2, outline: "#000", letterBorder: 23},
|
ctx: ctx,
|
||||||
{shadow: [3, 3, 3]},
|
text: "むずかしさをえらぶ",
|
||||||
{x: 2, y: 2},
|
fontSize: 46,
|
||||||
{x: 2, y: 2, outline: "#ad1516", letterBorder: 10},
|
fontFamily: this.font,
|
||||||
{x: -2, y: -2, outline: "#ff797b"},
|
x: 53,
|
||||||
{outline: "#f70808"},
|
y: 30,
|
||||||
{fill: "#fff", shadow: [-1, 1, 3, 1.5]}
|
width: 280,
|
||||||
])
|
forceShadow: true
|
||||||
|
}, [
|
||||||
|
{x: -2, y: -2, outline: "#000", letterBorder: 23},
|
||||||
|
{},
|
||||||
|
{x: 2, y: 2, shadow: [3, 3, 3]},
|
||||||
|
{x: 2, y: 2, outline: "#ad1516", letterBorder: 10},
|
||||||
|
{x: -2, y: -2, outline: "#ff797b"},
|
||||||
|
{outline: "#f70808"},
|
||||||
|
{fill: "#fff", shadow: [-1, 1, 3, 1.5]}
|
||||||
|
])
|
||||||
|
})
|
||||||
var opened = 1
|
var opened = 1
|
||||||
var songSel = false
|
var songSel = false
|
||||||
var _x = x + 62
|
var _x = x + 62
|
||||||
@ -883,16 +946,26 @@ class SongSelect{
|
|||||||
border: 4.5
|
border: 4.5
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.draw.verticalText({
|
var offset = (songSel ? 44 : 56) / 2
|
||||||
|
this.difficultyCache.get({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: this.difficulty[i],
|
x: _x - offset,
|
||||||
x: _x,
|
|
||||||
y: songSel ? _y + 10 : _y + 23,
|
y: songSel ? _y + 10 : _y + 23,
|
||||||
width: songSel ? 44 : 56,
|
w: songSel ? 44 : 56,
|
||||||
height: songSel ? (i === 1 ? 66 : 88) : (i === 0 ? 130 : i === 1 ? 110 : 135),
|
h: (songSel ? 88 : 135) + 10,
|
||||||
fill: "#000",
|
id: this.difficulty[i] + (songSel ? "1" : "0")
|
||||||
fontSize: songSel ? 25 : (i === 2 ? 45 : 40),
|
}, ctx => {
|
||||||
fontFamily: this.font
|
this.draw.verticalText({
|
||||||
|
ctx: ctx,
|
||||||
|
text: this.difficulty[i],
|
||||||
|
x: offset,
|
||||||
|
y: 0,
|
||||||
|
width: songSel ? 44 : 56,
|
||||||
|
height: songSel ? (i === 1 ? 66 : 88) : (i === 0 ? 130 : (i === 1 ? 110 : 135)),
|
||||||
|
fill: "#000",
|
||||||
|
fontSize: songSel ? 25 : (i === 2 ? 45 : 40),
|
||||||
|
fontFamily: this.font
|
||||||
|
})
|
||||||
})
|
})
|
||||||
for(var j = 0; j < 10; j++){
|
for(var j = 0; j < 10; j++){
|
||||||
if(songSel){
|
if(songSel){
|
||||||
@ -910,7 +983,8 @@ class SongSelect{
|
|||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
songSel: songSel,
|
songSel: songSel,
|
||||||
x: _x,
|
x: _x,
|
||||||
y: yPos
|
y: yPos,
|
||||||
|
ratio: ratio
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -959,23 +1033,37 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
ctx.globalAlpha = 1 - Math.max(0, opened - 0.5) * 2
|
ctx.globalAlpha = 1 - Math.max(0, opened - 0.5) * 2
|
||||||
ctx.fillStyle = selectedSkin.background
|
ctx.fillStyle = selectedSkin.background
|
||||||
ctx.fillRect(x,y,w,h)
|
ctx.fillRect(x, y, w, h)
|
||||||
ctx.globalAlpha = 1
|
ctx.globalAlpha = 1
|
||||||
var textX = Math.max(w - 37, w / 2)
|
var borders = (this.songAsset.border + this.songAsset.innerBorder) * 2
|
||||||
|
var textW = this.songAsset.width - borders
|
||||||
|
var textH = this.songAsset.height - borders
|
||||||
|
var textX = Math.max(w - 37 - textW / 2, w / 2 - textW / 2)
|
||||||
var textY = opened * 12 + (1 - opened) * 7
|
var textY = opened * 12 + (1 - opened) * 7
|
||||||
this.draw.verticalText({
|
this.songTitleCache.get({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: currentSong.title,
|
|
||||||
x: x + textX,
|
x: x + textX,
|
||||||
y: y + textY,
|
y: y + textY - 7,
|
||||||
width: w,
|
w: textW,
|
||||||
height: h - 35,
|
h: textH,
|
||||||
fill: "#fff",
|
id: currentSong.title + selectedSkin.outline,
|
||||||
outline: selectedSkin.outline,
|
}, ctx => {
|
||||||
outlineSize: this.songAsset.letterBorder,
|
this.draw.verticalText({
|
||||||
fontSize: 40,
|
ctx: ctx,
|
||||||
fontFamily: this.font
|
text: currentSong.title,
|
||||||
|
x: textW / 2,
|
||||||
|
y: 7,
|
||||||
|
width: textW,
|
||||||
|
height: textH - 35,
|
||||||
|
fill: "#fff",
|
||||||
|
outline: selectedSkin.outline,
|
||||||
|
outlineSize: this.songAsset.letterBorder,
|
||||||
|
fontSize: 40,
|
||||||
|
fontFamily: this.font
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
//ctx.fillStyle="#f00"
|
||||||
|
//ctx.fillRect(textX,textY,textW,textH)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1014,19 +1102,30 @@ class SongSelect{
|
|||||||
config.outline = config.song.skin.outline
|
config.outline = config.song.skin.outline
|
||||||
config.text = config.song.title
|
config.text = config.song.title
|
||||||
config.animateMS = this.state.moveMS
|
config.animateMS = this.state.moveMS
|
||||||
|
config.cached = 1
|
||||||
|
config.frameCache = this.songFrameCache
|
||||||
config.innerContent = (x, y, w, h) => {
|
config.innerContent = (x, y, w, h) => {
|
||||||
this.draw.verticalText({
|
this.songTitleCache.get({
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
text: config.text,
|
x: x,
|
||||||
x: x + w / 2,
|
y: y,
|
||||||
y: y + 7,
|
w: w,
|
||||||
width: w,
|
h: h,
|
||||||
height: h - 35,
|
id: config.text + config.outline,
|
||||||
fill: "#fff",
|
}, ctx => {
|
||||||
outline: config.outline,
|
this.draw.verticalText({
|
||||||
outlineSize: this.songAsset.letterBorder,
|
ctx: ctx,
|
||||||
fontSize: 40,
|
text: config.text,
|
||||||
fontFamily: this.font
|
x: w / 2,
|
||||||
|
y: 7,
|
||||||
|
width: w,
|
||||||
|
height: h - 35,
|
||||||
|
fill: "#fff",
|
||||||
|
outline: config.outline,
|
||||||
|
outlineSize: this.songAsset.letterBorder,
|
||||||
|
fontSize: 40,
|
||||||
|
fontFamily: this.font
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.draw.songFrame(config)
|
this.draw.songFrame(config)
|
||||||
@ -1137,6 +1236,11 @@ class SongSelect{
|
|||||||
}
|
}
|
||||||
|
|
||||||
clean(){
|
clean(){
|
||||||
|
this.draw.clean()
|
||||||
|
this.songTitleCache.clean()
|
||||||
|
this.selectTextCache.clean()
|
||||||
|
this.categoryCache.clean()
|
||||||
|
this.difficultyCache.clean()
|
||||||
assets.sounds["bgm_songsel"].stop()
|
assets.sounds["bgm_songsel"].stop()
|
||||||
if(!this.bgmEnabled){
|
if(!this.bgmEnabled){
|
||||||
snd.musicGain.fadeIn()
|
snd.musicGain.fadeIn()
|
||||||
|
Loading…
Reference in New Issue
Block a user