SongSelect: Add sub-titles

This commit is contained in:
LoveEevee 2018-11-10 22:12:29 +03:00
parent 074ee68ce0
commit b6552ea25f
5 changed files with 104 additions and 23 deletions

10
app.py
View File

@ -161,22 +161,24 @@ def route_api_songs():
songs_out = [] songs_out = []
for song in songs: for song in songs:
song_id = song[0] song_id = song[0]
song_type = song[10] song_type = song[12]
preview = get_preview(song_id, song_type) preview = get_preview(song_id, song_type)
category_out = categories[song[9]] if song[9] in categories else def_category category_out = categories[song[11]] if song[11] in categories else def_category
songs_out.append({ songs_out.append({
'id': song_id, 'id': song_id,
'title': song[1], 'title': song[1],
'title_en': song[2], 'title_en': song[2],
'subtitle': song[3],
'subtitle_en': song[4],
'stars': [ 'stars': [
song[3], song[4], song[5], song[6], song[7] song[5], song[6], song[7], song[8], song[9]
], ],
'preview': preview, 'preview': preview,
'category': category_out['title'], 'category': category_out['title'],
'category_en': category_out['title_en'], 'category_en': category_out['title_en'],
'type': song_type, 'type': song_type,
'offset': song[11] 'offset': song[13]
}) })
return jsonify(songs_out) return jsonify(songs_out)

View File

@ -50,8 +50,9 @@
comma: /[,.]/, comma: /[,.]/,
ideographicComma: /[、。]/, ideographicComma: /[、。]/,
apostrophe: /[']/, apostrophe: /[']/,
degree: /[゚°]/,
brackets: /[\(\))「」『』]/, brackets: /[\(\))「」『』]/,
tilde: /[\-~]/, tilde: /[\-~]/,
tall: /[bdfh-l-t0-9-9♪]/, tall: /[bdfh-l-t0-9-9♪]/,
uppercase: /[A-Z-]/, uppercase: /[A-Z-]/,
lowercase: /[a-z-z・]/, lowercase: /[a-z-z・]/,
@ -283,15 +284,20 @@
}else if(symbol === "ー"){ }else if(symbol === "ー"){
// Long-vowel mark // Long-vowel mark
drawn.push({realText: symbol, svg: this.longVowelMark, x: -4, y: 5, h: 33, scale: [mul, mul]}) drawn.push({realText: symbol, svg: this.longVowelMark, x: -4, y: 5, h: 33, scale: [mul, mul]})
}else if(symbol === "∀"){
drawn.push({text: symbol, x: 0, y: 3, h: 39, rotate: true})
}else if(r.comma.test(symbol)){ }else if(r.comma.test(symbol)){
// Comma, full stop // Comma, full stop
drawn.push({text: symbol, x: 16, y: -7, h: 0, scale: [1.2, 0.7]}) drawn.push({text: symbol, x: 13, y: -9, h: 13, scale: [1.2, 0.7]})
}else if(r.ideographicComma.test(symbol)){ }else if(r.ideographicComma.test(symbol)){
// Ideographic comma, full stop // Ideographic comma, full stop
drawn.push({text: symbol, x: 16, y: -16, h: 18}) drawn.push({text: symbol, x: 16, y: -16, h: 18})
}else if(r.apostrophe.test(symbol)){ }else if(r.apostrophe.test(symbol)){
// Apostrophe // Apostrophe
drawn.push({realText: symbol, text: ",", x: 20, y: -39, h: 0, scale: [1.2, 0.7]}) drawn.push({realText: symbol, text: ",", x: 20, y: -39, h: 0, scale: [1.2, 0.7]})
}else if(r.degree.test(symbol)){
// Degree
drawn.push({text: symbol, x: 16, y: 3, h: 18})
}else if(r.brackets.test(symbol)){ }else if(r.brackets.test(symbol)){
// Rotated brackets // Rotated brackets
drawn.push({text: symbol, x: 0, y: -5, h: 25, rotate: true}) drawn.push({text: symbol, x: 0, y: -5, h: 25, rotate: true})
@ -359,6 +365,10 @@
} }
} }
if(config.align === "bottom"){
drawn.reverse()
}
var drawnHeight = 0 var drawnHeight = 0
for(let symbol of drawn){ for(let symbol of drawn){
if(config.letterSpacing){ if(config.letterSpacing){
@ -382,9 +392,16 @@
style.transform = "" style.transform = ""
} }
var scaling = 1
if(config.height && drawnHeight > config.height){ if(config.height && drawnHeight > config.height){
var scaling = config.height / drawnHeight scaling = config.height / drawnHeight
ctx.scale(1, scaling) if(config.align === "bottom"){
ctx.translate(40 * mul, 0)
ctx.scale(scaling, scaling)
ctx.translate(-40 * mul, 0)
}else{
ctx.scale(1, scaling)
}
if(config.selectable){ if(config.selectable){
style.transform = "scale(1, " + scaling + ")" style.transform = "scale(1, " + scaling + ")"
style.top = (config.y + (config.height - drawnHeight) / 2 - 15 / 2 * scaling) * scale + "px" style.top = (config.y + (config.height - drawnHeight) / 2 - 15 / 2 * scaling) * scale + "px"
@ -407,12 +424,19 @@
if(action === "stroke"){ if(action === "stroke"){
ctx.strokeStyle = config.outline ctx.strokeStyle = config.outline
ctx.lineWidth = config.outlineSize * mul ctx.lineWidth = config.outlineSize * mul
if(config.align === "bottom"){
ctx.lineWidth /= scaling
}
ctx.lineJoin = "round" ctx.lineJoin = "round"
ctx.miterLimit = 1 ctx.miterLimit = 1
}else if(action === "fill"){ }else if(action === "fill"){
ctx.fillStyle = config.fill ctx.fillStyle = config.fill
} }
var offsetY = 0 if(config.align === "bottom"){
var offsetY = drawnHeight > config.height ? drawnHeight : config.height
}else{
var offsetY = 0
}
for(let symbol of drawn){ for(let symbol of drawn){
var saved = false var saved = false
@ -421,7 +445,10 @@
currentX += 20 * mul currentX += 20 * mul
} }
var currentY = offsetY + symbol.y * mul var currentY = offsetY + symbol.y * mul
offsetY += symbol.h * mul if(config.align === "bottom"){
currentY -= symbol.h * mul
}
offsetY = offsetY + symbol.h * mul * (config.align === "bottom" ? -1 : 1)
if(action === "selectable"){ if(action === "selectable"){
let div = document.createElement("div") let div = document.createElement("div")
div.classList.add("stroke-sub") div.classList.add("stroke-sub")

View File

@ -85,7 +85,8 @@ pageEvents.add(versionDiv, ["click", "touchend"], () => {
resizeRoot() resizeRoot()
setInterval(resizeRoot, 100) setInterval(resizeRoot, 100)
pageEvents.keyAdd(debugObj, "all", "down", event => { pageEvents.keyAdd(debugObj, "all", "down", event => {
if(event.keyCode === 186 && event.ctrlKey && event.shiftKey && !event.altKey){ if((event.keyCode === 186 || event.keyCode === 59) && event.ctrlKey && event.shiftKey && !event.altKey){
// Semicolon
if(debugObj.state === "open"){ if(debugObj.state === "open"){
debugObj.debug.minimise() debugObj.debug.minimise()
}else if(debugObj.state === "minimised"){ }else if(debugObj.state === "minimised"){
@ -95,6 +96,7 @@ pageEvents.keyAdd(debugObj, "all", "down", event => {
} }
} }
if(event.keyCode === 82 && debugObj.debug && debugObj.controller){ if(event.keyCode === 82 && debugObj.debug && debugObj.controller){
// R
debugObj.controller.restartSong() debugObj.controller.restartSong()
} }
}) })

View File

@ -91,6 +91,7 @@ class SongSelect{
this.songs.push({ this.songs.push({
id: song.id, id: song.id,
title: song.title, title: song.title,
subtitle: song.subtitle,
skin: song.category in this.songSkin ? this.songSkin[song.category] : this.songSkin.default, skin: song.category in this.songSkin ? this.songSkin[song.category] : this.songSkin.default,
stars: song.stars, stars: song.stars,
category: song.category, category: song.category,
@ -218,6 +219,8 @@ class SongSelect{
this.songSelect.style.backgroundImage = "url('" + assets.image["bg_genre_" + sort].src + "')" this.songSelect.style.backgroundImage = "url('" + assets.image["bg_genre_" + sort].src + "')"
this.previewId = 0 this.previewId = 0
this.previewList = Array(5)
var skipStart = fromTutorial || p2.session var skipStart = fromTutorial || p2.session
this.state = { this.state = {
screen: fadeIn ? "titleFadeIn" : (skipStart ? "song" : "title"), screen: fadeIn ? "titleFadeIn" : (skipStart ? "song" : "title"),
@ -708,7 +711,11 @@ class SongSelect{
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 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.songTitleCache.resize(
(this.songAsset.width - borders + 1) * this.songs.length,
(this.songAsset.height - borders + 1) * 3,
ratio + 0.5
)
this.selectTextCache.resize((280 + 53 + 60 + 1) * 2, this.songAsset.marginTop + 15, ratio + 0.5) this.selectTextCache.resize((280 + 53 + 60 + 1) * 2, this.songAsset.marginTop + 15, ratio + 0.5)
@ -1285,30 +1292,55 @@ class SongSelect{
drawDifficulty(ctx, i, currentUra) drawDifficulty(ctx, i, currentUra)
} }
} }
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
if(currentSong.subtitle){
this.songTitleCache.get({
ctx: ctx,
x: x + textX - textW,
y: y + textY,
w: textW,
h: textH,
id: currentSong.subtitle,
}, ctx => {
this.draw.verticalText({
ctx: ctx,
text: currentSong.subtitle,
x: textW / 2,
y: 7,
width: textW,
height: textH - 35,
fill: "#fff",
outline: "#000",
outlineSize: 14,
fontSize: 28,
fontFamily: this.font,
align: "bottom"
})
})
}
if(!songSel && currentSong.stars[4]){ if(!songSel && currentSong.stars[4]){
var fade = ((ms - this.state.screenMS) % 1200) / 1200 var fade = ((ms - this.state.screenMS) % 1200) / 1200
var _x = x + 402 + 4 * 100 + fade * 25 var _x = x + 402 + 4 * 100 + fade * 25
var _y = y + 258 var _y = y + 258
ctx.save() ctx.fillStyle = "rgba(0, 0, 0, " + 0.2 * this.draw.easeInOut(1 - fade) + ")"
ctx.globalAlpha = this.draw.easeInOut(1 - fade)
ctx.fillStyle = "#e0be28"
ctx.beginPath() ctx.beginPath()
ctx.moveTo(_x - 35, _y - 25) ctx.moveTo(_x - 35, _y - 25)
ctx.lineTo(_x - 10, _y) ctx.lineTo(_x - 10, _y)
ctx.lineTo(_x - 35, _y + 25) ctx.lineTo(_x - 35, _y + 25)
ctx.fill() ctx.fill()
ctx.restore()
} }
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 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
this.songTitleCache.get({ this.songTitleCache.get({
ctx: ctx, ctx: ctx,
x: x + textX, x: x + textX,
@ -1551,15 +1583,17 @@ class SongSelect{
var currentId = this.previewId var currentId = this.previewId
this.previewing = this.selectedSong this.previewing = this.selectedSong
} }
var songObj = assets.songs.find(song => song.id == id) var songObj = this.previewList.find(song => song && song.id === id)
if(songObj.preview_sound){ if(songObj){
if(!loadOnly){ if(!loadOnly){
this.preview = songObj.preview_sound this.preview = songObj.preview_sound
this.preview.gain = snd.previewGain this.preview.gain = snd.previewGain
this.previewLoaded(startLoad, songObj.preview_time) this.previewLoaded(startLoad, songObj.preview_time)
} }
}else{ }else{
songObj = {id: id}
var previewFilename = prvTime > 0.1 ? "/preview.mp3" : "/main.mp3" var previewFilename = prvTime > 0.1 ? "/preview.mp3" : "/main.mp3"
var loadPreview = previewFilename => { var loadPreview = previewFilename => {
@ -1575,6 +1609,14 @@ class SongSelect{
songObj.preview_sound = sound songObj.preview_sound = sound
this.preview = sound this.preview = sound
this.previewLoaded(startLoad, songObj.preview_time) this.previewLoaded(startLoad, songObj.preview_time)
var oldPreview = this.previewList.shift()
if(oldPreview){
oldPreview.preview_sound.clean()
}
this.previewList.push(songObj)
}else{
sound.clean()
} }
}) })
} }
@ -1714,6 +1756,11 @@ class SongSelect{
} }
this.redrawRunning = false this.redrawRunning = false
this.endPreview() this.endPreview()
this.previewList.forEach(song => {
if(song){
song.preview_sound.clean()
}
})
pageEvents.keyRemove(this, "all") pageEvents.keyRemove(this, "all")
pageEvents.remove(loader.screen, ["mousemove", "mouseleave", "mousedown", "touchstart"]) pageEvents.remove(loader.screen, ["mousemove", "mouseleave", "mousedown", "touchstart"])
pageEvents.remove(p2, "message") pageEvents.remove(p2, "message")

View File

@ -206,4 +206,7 @@ class Sound{
} }
} }
} }
clean(){
delete this.buffer
}
} }