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