SongSelect: Selectable text, assets cleanup, and bug fixes
This commit is contained in:
parent
0d1444de0c
commit
d7900ca083
@ -4,7 +4,7 @@
|
||||
}
|
||||
@font-face{
|
||||
font-family: Kozuka;
|
||||
src: url("/assets/fonts/KozGoPro-Bold.otf") format("truetype");
|
||||
src: url("/assets/fonts/Kozuka.otf") format("truetype");
|
||||
}
|
||||
html,
|
||||
body{
|
||||
@ -23,6 +23,7 @@ body{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #fe7839 url("/assets/img/bg-pattern-1.png") top center;
|
||||
background-size: 30vh;
|
||||
font-family: TnT, Meiryo, sans-serif;
|
||||
}
|
||||
#assets{
|
||||
@ -265,6 +266,30 @@ kbd{
|
||||
height: 12.5vmin;
|
||||
opacity: 0.5;
|
||||
}
|
||||
#song-sel-selectable{
|
||||
position: absolute;
|
||||
opacity: 1;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
white-space: pre-wrap;
|
||||
user-select: all;
|
||||
cursor: text;
|
||||
color: transparent;
|
||||
}
|
||||
#song-sel-selectable:focus{
|
||||
background: #ffdb2c;
|
||||
color: #000;
|
||||
}
|
||||
#song-sel-selectable .stroke-sub{
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
#song-sel-selectable .stroke-sub::before{
|
||||
-webkit-text-stroke: 0;
|
||||
}
|
||||
#song-sel-selectable:focus .stroke-sub::before{
|
||||
-webkit-text-stroke: 0.25em #fff;
|
||||
}
|
||||
|
||||
#version {
|
||||
position: fixed;
|
||||
|
@ -53,9 +53,11 @@
|
||||
brackets: /[\((\))「」『』]/,
|
||||
tilde: /[\--~~]/,
|
||||
tall: /[bbddffh-lh-ltt0-90-9♪]/,
|
||||
uppercase: /[A-ZA-Z!!]/,
|
||||
uppercase: /[A-ZA-Z]/,
|
||||
lowercase: /[a-za-z・]/,
|
||||
latin: /[A-ZA-Z!!a-za-z・]/,
|
||||
latin: /[A-ZA-Za-za-z・]/,
|
||||
exclamation: /[!!\?? ]/,
|
||||
question: /[\??]/,
|
||||
smallHiragana: /[ぁぃぅぇぉっゃゅょァィゥェォッャュョ]/,
|
||||
hiragana: /[\u3040-\u30ff]/,
|
||||
todo: /[トド]/,
|
||||
@ -63,7 +65,7 @@
|
||||
em: /[mwmw]/,
|
||||
emCap: /[MWMW]/,
|
||||
rWidth: /[abdfIjo-rtvabdfIjo-rtv]/,
|
||||
lWidth: /[ilil!!]/,
|
||||
lWidth: /[ilil]/,
|
||||
uppercaseDigit: /[A-ZA-Z0-90-9]/
|
||||
}
|
||||
|
||||
@ -266,13 +268,16 @@
|
||||
var drawn = []
|
||||
|
||||
var r = this.regex
|
||||
for(let symbol of string){
|
||||
var previousSymbol = ""
|
||||
|
||||
for(var i = 0; i < string.length; i++){
|
||||
let symbol = string[i]
|
||||
if(symbol === " "){
|
||||
// Space
|
||||
drawn.push({text: symbol, x: 0, y: 0, h: 18})
|
||||
}else if(symbol === "ー"){
|
||||
// Long-vowel mark
|
||||
drawn.push({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(r.comma.test(symbol)){
|
||||
// Comma, full stop
|
||||
drawn.push({text: symbol, x: 16, y: -7, h: 0, scale: [1.2, 0.7]})
|
||||
@ -281,16 +286,13 @@
|
||||
drawn.push({text: symbol, x: 16, y: -16, h: 18})
|
||||
}else if(r.apostrophe.test(symbol)){
|
||||
// Apostrophe
|
||||
drawn.push({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.brackets.test(symbol)){
|
||||
// Rotated brackets
|
||||
drawn.push({text: symbol, x: 0, y: -5, h: 25, rotate: true})
|
||||
}else if(r.tilde.test(symbol)){
|
||||
// Rotated hyphen, tilde
|
||||
if(symbol === "~"){
|
||||
symbol = "~"
|
||||
}
|
||||
drawn.push({text: symbol, x: 0, y: 2, h: 35, rotate: true})
|
||||
drawn.push({realText: symbol, text: symbol === "~" ? "~" : symbol, x: 0, y: 2, h: 35, rotate: true})
|
||||
}else if(r.tall.test(symbol)){
|
||||
// Tall latin script lowercase, numbers
|
||||
drawn.push({text: symbol, x: 0, y: 4, h: 34, scale: [1.05, 0.9]})
|
||||
@ -300,6 +302,46 @@
|
||||
}else if(r.lowercase.test(symbol)){
|
||||
// Latin script lower case
|
||||
drawn.push({text: symbol, x: 0, y: -1, h: 28, scale: [1.05, 0.9]})
|
||||
}else if(r.exclamation.test(symbol)){
|
||||
// Exclamation mark
|
||||
var toDraw = [symbol]
|
||||
for(var repeat = 1; repeat - 1 < i; repeat++){
|
||||
if(!r.exclamation.test(string[i - repeat])){
|
||||
break
|
||||
}
|
||||
toDraw.push(string[i - repeat])
|
||||
}
|
||||
if(repeat > 1){
|
||||
drawn.splice(i - repeat + 1, repeat)
|
||||
var allExclamations = !toDraw.find(a => a !== "!")
|
||||
|
||||
for(var j = 1; j < repeat + 1; j++){
|
||||
var text = string[i - repeat + j]
|
||||
if(allExclamations){
|
||||
var y = 18
|
||||
var h = 61
|
||||
}else{
|
||||
var y = 8
|
||||
var h = 37
|
||||
}
|
||||
if(i === repeat - 1){
|
||||
h -= y - 4
|
||||
y = 4
|
||||
}
|
||||
|
||||
drawn.push({
|
||||
text: text,
|
||||
x: ((j - 1) - (repeat - 1) / 2) * 15,
|
||||
y: y - (j === 1 ? 0 : h),
|
||||
h: j === 1 ? h : 0,
|
||||
scale: r.question.test(text) ? [0.6, 0.95] : false
|
||||
})
|
||||
}
|
||||
}else{
|
||||
drawn.push({text: symbol, x: 0, y: 8, h: 37,
|
||||
scale: r.question.test(symbol) ? [0.7, 0.95] : false
|
||||
})
|
||||
}
|
||||
}else if(r.smallHiragana.test(symbol)){
|
||||
// Small hiragana, small katakana
|
||||
drawn.push({text: symbol, x: 0, y: -8, h: 25, right: true})
|
||||
@ -323,8 +365,25 @@
|
||||
ctx.save()
|
||||
ctx.translate(config.x, config.y)
|
||||
|
||||
if(config.selectable){
|
||||
config.selectable.innerHTML = ""
|
||||
var scale = config.selectableScale
|
||||
var style = config.selectable.style
|
||||
style.left = (config.x - config.width / 2) * scale + "px"
|
||||
style.top = config.y * scale + "px"
|
||||
style.width = config.width * scale + "px"
|
||||
style.height = (drawnHeight+15) * scale + "px"
|
||||
style.fontSize = 40 * mul * scale + "px"
|
||||
style.transform = ""
|
||||
}
|
||||
|
||||
if(config.height && drawnHeight > config.height){
|
||||
ctx.scale(1, config.height / drawnHeight)
|
||||
var scaling = config.height / drawnHeight
|
||||
ctx.scale(1, scaling)
|
||||
if(config.selectable){
|
||||
style.transform = "scale(1, " + scaling + ")"
|
||||
style.top = (config.y + (config.height - drawnHeight) / 2 - 15 / 2 * scaling) * scale + "px"
|
||||
}
|
||||
}
|
||||
|
||||
var actions = []
|
||||
@ -334,6 +393,9 @@
|
||||
if(config.fill){
|
||||
actions.push("fill")
|
||||
}
|
||||
if(config.selectable){
|
||||
actions.push("selectable")
|
||||
}
|
||||
for(let action of actions){
|
||||
ctx.font = config.fontSize + "px " + config.fontFamily
|
||||
ctx.textBaseline = "top"
|
||||
@ -354,6 +416,34 @@
|
||||
currentX += 20 * mul
|
||||
}
|
||||
var currentY = offsetY + symbol.y * mul
|
||||
offsetY += symbol.h * mul
|
||||
if(action === "selectable"){
|
||||
let div = document.createElement("div")
|
||||
div.classList.add("stroke-sub")
|
||||
let text = symbol.realText || symbol.text
|
||||
let textWidth = ctx.measureText(text).width
|
||||
let transform = []
|
||||
if(symbol.scale){
|
||||
transform.push("scale(" + symbol.scale[0] + "," + symbol.scale[1] + ")")
|
||||
}
|
||||
if(symbol.rotate || symbol.realText === "ー"){
|
||||
transform.push("rotate(90deg)")
|
||||
}
|
||||
if(transform.length){
|
||||
div.style.transform = transform.join(" ")
|
||||
}
|
||||
if(symbol.right){
|
||||
currentX = currentX + config.width / 2 - textWidth
|
||||
}else{
|
||||
currentX = currentX + config.width / 2 - textWidth / 2
|
||||
}
|
||||
div.style.left = currentX * scale + "px"
|
||||
div.style.top = currentY * scale + "px"
|
||||
div.appendChild(document.createTextNode(text))
|
||||
div.setAttribute("alt", text)
|
||||
config.selectable.appendChild(div)
|
||||
continue
|
||||
}
|
||||
if(symbol.rotate || symbol.scale || symbol.svg){
|
||||
saved = true
|
||||
ctx.save()
|
||||
@ -381,7 +471,6 @@
|
||||
}
|
||||
ctx[action + "Text"](symbol.text, currentX, currentY)
|
||||
}
|
||||
offsetY += symbol.h * mul
|
||||
if(saved){
|
||||
ctx.restore()
|
||||
}
|
||||
@ -396,13 +485,12 @@
|
||||
ctx.save()
|
||||
|
||||
var string = config.text.split("")
|
||||
if(config.align === "right"){
|
||||
string.reverse()
|
||||
}
|
||||
var drawn = []
|
||||
|
||||
var r = this.regex
|
||||
for(let symbol of string){
|
||||
for(var i = 0; i < string.length; i++){
|
||||
let symbol = string[i]
|
||||
|
||||
if(symbol === "-"){
|
||||
drawn.push({text: symbol, x: -4, y: 0, w: 28, scale: [0.8, 1]})
|
||||
}else if(symbol === "™"){
|
||||
@ -411,6 +499,8 @@
|
||||
drawn.push({text: symbol, x: 0, y: 0, w: 10})
|
||||
}else if(symbol === "'"){
|
||||
drawn.push({text: ",", x: 0, y: -15, w: 7, scale: [1, 0.7]})
|
||||
}else if(symbol === "?"){
|
||||
drawn.push({text: symbol, x: 0, y: -1, w: 12, scale: [0.7, 0.95]})
|
||||
}else if(r.en.test(symbol)){
|
||||
// n-width
|
||||
drawn.push({text: symbol, x: 0, y: 0, w: 28, scale: [1, 0.95]})
|
||||
@ -429,6 +519,16 @@
|
||||
}else if(r.uppercaseDigit.test(symbol)){
|
||||
// Latin script uppercase, digits
|
||||
drawn.push({text: symbol, x: 0, y: -2, w: 32})
|
||||
}else if(r.exclamation.test(symbol)){
|
||||
// Exclamation mark
|
||||
var nextExclamation = string[i + 1] ? r.exclamation.test(string[i + 1]) : false
|
||||
drawn.push({
|
||||
text: symbol,
|
||||
x: nextExclamation ? 4 : -1,
|
||||
y: 0,
|
||||
w: nextExclamation ? 16 : 28,
|
||||
scale: symbol === "?" ? [0.7, 0.95] : false
|
||||
})
|
||||
}else if(r.smallHiragana.test(symbol)){
|
||||
// Small hiragana, small katakana
|
||||
drawn.push({text: symbol, x: 0, y: 0, w: 30})
|
||||
@ -440,6 +540,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
if(config.align === "right"){
|
||||
drawn.reverse()
|
||||
}
|
||||
|
||||
var drawnWidth = 0
|
||||
for(let symbol of drawn){
|
||||
if(config.letterSpacing){
|
||||
|
@ -26,6 +26,8 @@ class Controller{
|
||||
this.view = new View(this, backgroundURL, this.selectedSong.title, this.selectedSong.difficulty)
|
||||
this.mekadon = new Mekadon(this, this.game)
|
||||
this.keyboard = new Keyboard(this)
|
||||
|
||||
this.playedSounds = {}
|
||||
}
|
||||
run(syncWith){
|
||||
this.loadUIEvents()
|
||||
@ -34,8 +36,8 @@ class Controller{
|
||||
this.startMainLoop()
|
||||
if(syncWith){
|
||||
syncWith.run()
|
||||
syncWith.elapsedTime = this.game.elapsedTime
|
||||
syncWith.startDate = this.game.startDate
|
||||
syncWith.game.elapsedTime = this.game.elapsedTime
|
||||
syncWith.game.startDate = this.game.startDate
|
||||
this.syncWith = syncWith
|
||||
}
|
||||
if(!this.multiplayer){
|
||||
@ -76,6 +78,7 @@ class Controller{
|
||||
requestAnimationFrame(() => {
|
||||
if(this.syncWith){
|
||||
this.syncWith.game.elapsedTime = this.game.elapsedTime
|
||||
this.syncWith.game.startDate = this.game.startDate
|
||||
}
|
||||
this.mainLoop()
|
||||
if(this.syncWith){
|
||||
@ -161,7 +164,11 @@ class Controller{
|
||||
}
|
||||
}
|
||||
playSound(id, time){
|
||||
assets.sounds[id + this.snd].play(time)
|
||||
var ms = (+new Date) + (time || 0) * 1000
|
||||
if(!(id in this.playedSounds) || ms > this.playedSounds[id] + 30){
|
||||
assets.sounds[id + this.snd].play(time)
|
||||
this.playedSounds[id] = ms
|
||||
}
|
||||
}
|
||||
playSoundMeka(soundID, time){
|
||||
var meka = ""
|
||||
|
@ -109,15 +109,15 @@ class ParseOsu{
|
||||
var timingPoints = []
|
||||
var indexes = this.getStartEndIndexes("TimingPoints")
|
||||
var lastBeatInterval = parseInt(this.data[indexes.start].split(",")[1])
|
||||
for(var i = indexes.start; i<= indexes.end; i++){
|
||||
for(var i = indexes.start; i <= indexes.end; i++){
|
||||
var values = this.data[i].split(",")
|
||||
var start = parseInt(values[this.osu.OFFSET])
|
||||
var msOrPercent = parseFloat(values[this.osu.MSPERBEAT])
|
||||
if(i == indexes.start){
|
||||
start = 0
|
||||
this.beatInfo.beatInterval = msOrPercent
|
||||
this.beatInfo.bpm = Math.floor(1000 / this.beatInfo.beatInterval * 60)
|
||||
}
|
||||
var beatReset = false
|
||||
if(msOrPercent < 0){
|
||||
var sliderMultiplier = this.difficulty.lastMultiplier / Math.abs(msOrPercent / 100)
|
||||
}else{
|
||||
@ -126,35 +126,61 @@ class ParseOsu{
|
||||
this.difficulty.originalMultiplier = sliderMultiplier
|
||||
}
|
||||
this.difficulty.lastMultiplier = sliderMultiplier
|
||||
beatReset = true
|
||||
}
|
||||
timingPoints.push({
|
||||
start: start + this.offset,
|
||||
sliderMultiplier: sliderMultiplier,
|
||||
measure: parseInt(values[this.osu.METER]),
|
||||
gogoTime: parseInt(values[this.osu.KIAIMODE]),
|
||||
beatMS: 1000 / this.difficulty.lastMultiplier
|
||||
beatMS: 1000 / this.difficulty.lastMultiplier,
|
||||
beatReset: beatReset
|
||||
})
|
||||
}
|
||||
return timingPoints
|
||||
}
|
||||
parseMeasures(){
|
||||
var measures = []
|
||||
var measureNumber = 0
|
||||
for(var i = 0; i<this.timingPoints.length; i++){
|
||||
if(this.timingPoints[i + 1]){
|
||||
var limit = this.timingPoints[i + 1].start - this.offset
|
||||
}else{
|
||||
var limit = this.circles[this.circles.length - 1].getMS() - this.offset
|
||||
}
|
||||
for(var start = this.timingPoints[i].start; start <= limit; start += this.beatInfo.beatInterval){
|
||||
if(measureNumber === 0){
|
||||
measures.push({
|
||||
ms: start + this.offset,
|
||||
originalMS: start + this.offset,
|
||||
speed: this.timingPoints[i].sliderMultiplier
|
||||
})
|
||||
|
||||
for(var i = 0; i < this.timingPoints.length; i++){
|
||||
var currentTiming = this.timingPoints[i]
|
||||
var firstTiming = i === 0
|
||||
|
||||
var limit = this.circles[this.circles.length - 1].endTime + currentTiming.beatMS
|
||||
|
||||
for(var j = i + 1; j < this.timingPoints.length; j++){
|
||||
var nextTiming = this.timingPoints[j]
|
||||
var newLimit = nextTiming.start
|
||||
if(nextTiming.measure !== currentTiming.measure || nextTiming.beatReset){
|
||||
limit = newLimit - currentTiming.beatMS
|
||||
break
|
||||
}
|
||||
measureNumber = (measureNumber + 1) % (this.timingPoints[i].measure + 1)
|
||||
i = j
|
||||
}
|
||||
|
||||
var start = currentTiming.start
|
||||
var interval = currentTiming.beatMS * currentTiming.measure
|
||||
if(firstTiming){
|
||||
while(start >= interval){
|
||||
start -= interval
|
||||
}
|
||||
}
|
||||
for(var ms = start; ms <= limit; ms += interval){
|
||||
|
||||
var speed = currentTiming.sliderMultiplier
|
||||
for(var j = 0; j < this.timingPoints.length; j++){
|
||||
var timingPoint = this.timingPoints[j]
|
||||
if(j !== 0 && timingPoint.start - this.offset > ms){
|
||||
break
|
||||
}
|
||||
speed = timingPoint.sliderMultiplier
|
||||
}
|
||||
|
||||
measures.push({
|
||||
ms: ms,
|
||||
originalMS: ms,
|
||||
speed: speed
|
||||
})
|
||||
}
|
||||
}
|
||||
return measures
|
||||
@ -253,7 +279,7 @@ class ParseOsu{
|
||||
|
||||
for(var j = 0; j < this.timingPoints.length; j++){
|
||||
var timingPoint = this.timingPoints[j]
|
||||
if(timingPoint.start - this.offset > start){
|
||||
if(j !== 0 && timingPoint.start - this.offset > start){
|
||||
break
|
||||
}
|
||||
speed = timingPoint.sliderMultiplier
|
||||
|
@ -300,6 +300,15 @@
|
||||
scroll: scroll
|
||||
}
|
||||
if(lastDrumroll){
|
||||
if(symbol === "9"){
|
||||
currentMeasure.push({
|
||||
endDrumroll: lastDrumroll,
|
||||
bpm: bpm,
|
||||
scroll: scroll
|
||||
})
|
||||
lastDrumroll = false
|
||||
break
|
||||
}
|
||||
circleObj.endDrumroll = lastDrumroll
|
||||
}
|
||||
if(symbol === "7" || symbol === "9"){
|
||||
|
@ -139,6 +139,9 @@ class Scoresheet{
|
||||
}
|
||||
}else{
|
||||
ctx.scale(ratio, ratio)
|
||||
if(!this.canvasCache.canvas){
|
||||
this.canvasCache.resize(winW / ratio, 80 + 1, ratio)
|
||||
}
|
||||
}
|
||||
this.winW = winW
|
||||
this.winH = winH
|
||||
@ -406,36 +409,38 @@ class Scoresheet{
|
||||
|
||||
if(elapsed >= 800){
|
||||
ctx.save()
|
||||
ctx.translate(frameLeft, frameTop)
|
||||
|
||||
ctx.globalAlpha = Math.min(1, (elapsed - 800) / 500)
|
||||
|
||||
for(var p = 0; p < players; p++){
|
||||
var results = this.results
|
||||
if(p === 1){
|
||||
results = p2.results
|
||||
ctx.translate(0, p2Offset)
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0)
|
||||
this.draw.alpha(Math.min(1, (elapsed - 800) / 500), ctx, ctx => {
|
||||
ctx.scale(ratio, ratio)
|
||||
ctx.translate(frameLeft, frameTop)
|
||||
|
||||
for(var p = 0; p < players; p++){
|
||||
var results = this.results
|
||||
if(p === 1){
|
||||
results = p2.results
|
||||
ctx.translate(0, p2Offset)
|
||||
}
|
||||
var gaugePercent = Math.round(results.gauge / 2) / 50
|
||||
var w = 712
|
||||
this.draw.gauge({
|
||||
ctx: ctx,
|
||||
x: 558 + w,
|
||||
y: 116,
|
||||
clear: 25 / 50,
|
||||
percentage: gaugePercent,
|
||||
font: this.font,
|
||||
scale: w / 788,
|
||||
scoresheet: true
|
||||
})
|
||||
this.draw.soul({
|
||||
ctx: ctx,
|
||||
x: 1215,
|
||||
y: 144,
|
||||
scale: 36 / 42,
|
||||
cleared: gaugePercent - 1 / 50 >= 25 / 50
|
||||
})
|
||||
}
|
||||
var gaugePercent = Math.round(results.gauge / 2) / 50
|
||||
var w = 712
|
||||
this.draw.gauge({
|
||||
ctx: ctx,
|
||||
x: 558 + w,
|
||||
y: 116,
|
||||
clear: 25 / 50,
|
||||
percentage: gaugePercent,
|
||||
font: this.font,
|
||||
scale: w / 788,
|
||||
scoresheet: true
|
||||
})
|
||||
this.draw.soul({
|
||||
ctx: ctx,
|
||||
x: 1215,
|
||||
y: 144,
|
||||
scale: 36 / 42,
|
||||
cleared: gaugePercent - 1 / 50 >= 25 / 50
|
||||
})
|
||||
}
|
||||
})
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
|
@ -242,17 +242,21 @@ class SongSelect{
|
||||
|
||||
this.startP2()
|
||||
|
||||
this.redrawRunning = true
|
||||
this.redrawBind = this.redraw.bind(this)
|
||||
this.redraw()
|
||||
pageEvents.keyAdd(this, "all", "down", this.keyDown.bind(this))
|
||||
pageEvents.add(this.canvas, "mousemove", this.mouseMove.bind(this))
|
||||
pageEvents.add(this.canvas, ["mousedown", "touchstart"], this.mouseDown.bind(this))
|
||||
pageEvents.add(window, "mousemove", this.mouseMove.bind(this))
|
||||
pageEvents.add(window, ["mousedown", "touchstart"], this.mouseDown.bind(this))
|
||||
if(touchEnabled && fullScreenSupported){
|
||||
this.touchFullBtn = document.getElementById("touch-full-btn")
|
||||
this.touchFullBtn.style.display = "block"
|
||||
pageEvents.add(this.touchFullBtn, "touchend", toggleFullscreen)
|
||||
}
|
||||
|
||||
this.selectable = document.getElementById("song-sel-selectable")
|
||||
this.selectableText = ""
|
||||
|
||||
this.redrawRunning = true
|
||||
this.redrawBind = this.redraw.bind(this)
|
||||
this.redraw()
|
||||
}
|
||||
|
||||
keyDown(event, code){
|
||||
@ -321,6 +325,15 @@ class SongSelect{
|
||||
}
|
||||
|
||||
mouseDown(event){
|
||||
if(event.target === this.selectable || event.target.parentNode === this.selectable){
|
||||
this.selectable.focus()
|
||||
}else{
|
||||
getSelection().removeAllRanges()
|
||||
this.selectable.blur()
|
||||
}
|
||||
if(event.target !== this.canvas){
|
||||
return
|
||||
}
|
||||
if(event.type === "mousedown"){
|
||||
if(event.which !== 1){
|
||||
return
|
||||
@ -643,6 +656,8 @@ class SongSelect{
|
||||
this.categoryCache.resize(280, (this.songAsset.marginTop + 1) * categories , ratio + 0.5)
|
||||
|
||||
this.difficultyCache.resize((44 + 56 + 2) * 5, 135 + 10, ratio + 0.5)
|
||||
|
||||
this.selectableText = ""
|
||||
}else if(!document.hasFocus()){
|
||||
this.pointer(false)
|
||||
return
|
||||
@ -1223,9 +1238,30 @@ class SongSelect{
|
||||
fontFamily: this.font
|
||||
})
|
||||
})
|
||||
if(!songSel && this.selectableText !== currentSong.title){
|
||||
this.draw.verticalText({
|
||||
ctx: ctx,
|
||||
text: currentSong.title,
|
||||
x: x + textX + textW / 2,
|
||||
y: y + textY,
|
||||
width: textW,
|
||||
height: textH - 35,
|
||||
fontSize: 40,
|
||||
fontFamily: this.font,
|
||||
selectable: this.selectable,
|
||||
selectableScale: this.ratio / this.pixelRatio
|
||||
})
|
||||
this.selectable.style.display = ""
|
||||
this.selectableText = currentSong.title
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if(screen !== "difficulty" && this.selectableText){
|
||||
this.selectableText = ""
|
||||
this.selectable.style.display = "none"
|
||||
}
|
||||
|
||||
if(songSelMoving){
|
||||
this.draw.highlight({
|
||||
ctx: ctx,
|
||||
@ -1423,11 +1459,12 @@ class SongSelect{
|
||||
this.redrawRunning = false
|
||||
this.endPreview()
|
||||
pageEvents.keyRemove(this, "all")
|
||||
pageEvents.remove(this.canvas, ["mousemove", "mousedown", "touchstart"])
|
||||
pageEvents.remove(window, ["mousemove", "mousedown", "touchstart"])
|
||||
if(this.touchEnabled && fullScreenSupported){
|
||||
pageEvents.remove(this.touchFullBtn, "click")
|
||||
delete this.touchFullBtn
|
||||
}
|
||||
delete this.selectable
|
||||
delete this.ctx
|
||||
delete this.canvas
|
||||
}
|
||||
|
@ -49,11 +49,16 @@
|
||||
if(this.controller.touchEnabled){
|
||||
this.touchDrumDiv = document.getElementById("touch-drum")
|
||||
this.touchDrumImg = document.getElementById("touch-drum-img")
|
||||
|
||||
if(this.controller.autoPlayEnabled){
|
||||
this.touchDrumDiv.style.display = "none"
|
||||
}else{
|
||||
pageEvents.add(this.canvas, "touchstart", this.ontouch.bind(this))
|
||||
}
|
||||
|
||||
this.gameDiv.classList.add("touch-visible")
|
||||
document.getElementById("version").classList.add("version-hide")
|
||||
|
||||
pageEvents.add(this.canvas, "touchstart", this.ontouch.bind(this))
|
||||
|
||||
this.touchFullBtn = document.getElementById("touch-full-btn")
|
||||
pageEvents.add(this.touchFullBtn, "touchend", toggleFullscreen)
|
||||
if(!fullScreenSupported){
|
||||
@ -1036,7 +1041,7 @@
|
||||
ctx.strokeText(text, textX, textY)
|
||||
ctx.fillText(text, textX, textY)
|
||||
|
||||
if(drumroll){
|
||||
if(drumroll === 2){
|
||||
ctx.strokeText(longText[1], textX + endX, textY)
|
||||
ctx.fillText(longText[1], textX + endX, textY)
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
<div id="song-select">
|
||||
<canvas id="song-sel-canvas"></canvas>
|
||||
<div id="song-sel-selectable" tabindex="1"></div>
|
||||
<img id="touch-full-btn" src="/assets/img/touch_fullscreen.png">
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user