Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
T
Taiko Web
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Taiko Web
Commits
3679c279
Commit
3679c279
authored
Mar 30, 2020
by
LoveEevee
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add lyrics
parent
20b964ab
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
330 additions
and
5 deletions
+330
-5
public/src/css/debug.css
public/src/css/debug.css
+2
-1
public/src/css/game.css
public/src/css/game.css
+35
-0
public/src/js/assets.js
public/src/js/assets.js
+2
-1
public/src/js/controller.js
public/src/js/controller.js
+7
-0
public/src/js/debug.js
public/src/js/debug.js
+25
-0
public/src/js/loadsong.js
public/src/js/loadsong.js
+10
-1
public/src/js/lyrics.js
public/src/js/lyrics.js
+231
-0
public/src/js/songselect.js
public/src/js/songselect.js
+4
-2
public/src/js/view.js
public/src/js/view.js
+7
-0
public/src/views/debug.html
public/src/views/debug.html
+6
-0
public/src/views/game.html
public/src/views/game.html
+1
-0
No files found.
public/src/css/debug.css
View file @
3679c279
...
...
@@ -123,6 +123,7 @@
}
#debug
.autoplay-label
,
#debug
.branch-hide
{
#debug
.branch-hide
,
#debug
.lyrics-hide
{
display
:
none
;
}
public/src/css/game.css
View file @
3679c279
...
...
@@ -89,3 +89,38 @@
.fix-animations
*
{
animation
:
none
!important
;
}
#song-lyrics
{
position
:
absolute
;
right
:
calc
((
100vw
-
1280
/
720
*
100vh
)
/
2
+
100px
*
var
(
--scale
));
bottom
:
calc
(
44
/
720
*
100vh
-
30px
*
var
(
--scale
));
left
:
calc
((
100vw
-
1280
/
720
*
100vh
)
/
2
+
100px
*
var
(
--scale
));
text-align
:
center
;
font-family
:
Meiryo
,
sans-serif
;
font-weight
:
bold
;
font-size
:
calc
(
45px
*
var
(
--scale
));
line-height
:
1.2
;
}
#game
.portrait
{
right
:
calc
(
20px
*
var
(
--scale
));
left
:
calc
(
20px
*
var
(
--scale
));
}
#song-lyrics
.stroke
,
#song-lyrics
.fill
{
position
:
absolute
;
right
:
0
;
bottom
:
0
;
left
:
0
;
}
#song-lyrics
.stroke
{
-webkit-text-stroke
:
calc
(
7px
*
var
(
--scale
))
#00a
;
}
#song-lyrics
.fill
{
color
:
#fff
;
}
#song-lyrics
ruby
{
display
:
inline-flex
;
flex-direction
:
column-reverse
;
}
#song-lyrics
rt
{
line-height
:
1
;
}
public/src/js/assets.js
View file @
3679c279
...
...
@@ -32,7 +32,8 @@ var assets = {
"
logo.js
"
,
"
settings.js
"
,
"
scorestorage.js
"
,
"
account.js
"
"
account.js
"
,
"
lyrics.js
"
],
"
css
"
:
[
"
main.css
"
,
...
...
public/src/js/controller.js
View file @
3679c279
...
...
@@ -57,6 +57,10 @@ class Controller{
if
(
song
.
id
==
this
.
selectedSong
.
folder
){
this
.
mainAsset
=
song
.
sound
this
.
volume
=
song
.
volume
||
1
if
(
song
.
lyricsData
&&
!
multiplayer
&&
(
!
this
.
touchEnabled
||
this
.
autoPlayEnabled
)){
var
lyricsDiv
=
document
.
getElementById
(
"
song-lyrics
"
)
this
.
lyrics
=
new
Lyrics
(
song
.
lyricsData
,
selectedSong
.
offset
,
lyricsDiv
)
}
}
})
}
...
...
@@ -316,5 +320,8 @@ class Controller{
debugObj
.
debug
.
updateStatus
()
}
}
if
(
this
.
lyrics
){
this
.
lyrics
.
clean
()
}
}
}
public/src/js/debug.js
View file @
3679c279
...
...
@@ -17,6 +17,8 @@ class Debug{
this
.
branchSelect
=
this
.
branchSelectDiv
.
getElementsByTagName
(
"
select
"
)[
0
]
this
.
branchResetBtn
=
this
.
branchSelectDiv
.
getElementsByClassName
(
"
reset
"
)[
0
]
this
.
volumeDiv
=
this
.
byClass
(
"
music-volume
"
)
this
.
lyricsHideDiv
=
this
.
byClass
(
"
lyrics-hide
"
)
this
.
lyricsOffsetDiv
=
this
.
byClass
(
"
lyrics-offset
"
)
this
.
restartLabel
=
this
.
byClass
(
"
change-restart-label
"
)
this
.
restartCheckbox
=
this
.
byClass
(
"
change-restart
"
)
this
.
autoplayLabel
=
this
.
byClass
(
"
autoplay-label
"
)
...
...
@@ -50,6 +52,9 @@ class Debug{
this
.
volumeSlider
.
onchange
(
this
.
volumeChange
.
bind
(
this
))
this
.
volumeSlider
.
set
(
1
)
this
.
lyricsSlider
=
new
InputSlider
(
this
.
lyricsOffsetDiv
,
-
60
,
60
,
3
)
this
.
lyricsSlider
.
onchange
(
this
.
lyricsChange
.
bind
(
this
))
this
.
moveTo
(
100
,
100
)
this
.
restore
()
this
.
updateStatus
()
...
...
@@ -129,6 +134,9 @@ class Debug{
if
(
this
.
controller
.
parsedSongData
.
branches
){
this
.
branchHideDiv
.
style
.
display
=
"
block
"
}
if
(
this
.
controller
.
lyrics
){
this
.
lyricsHideDiv
.
style
.
display
=
"
block
"
}
var
selectedSong
=
this
.
controller
.
selectedSong
this
.
defaultOffset
=
selectedSong
.
offset
||
0
...
...
@@ -136,11 +144,13 @@ class Debug{
this
.
offsetChange
(
this
.
offsetSlider
.
get
(),
true
)
this
.
branchChange
(
null
,
true
)
this
.
volumeChange
(
this
.
volumeSlider
.
get
(),
true
)
this
.
lyricsChange
(
this
.
lyricsSlider
.
get
())
}
else
{
this
.
songHash
=
selectedSong
.
hash
this
.
offsetSlider
.
set
(
this
.
defaultOffset
)
this
.
branchReset
(
null
,
true
)
this
.
volumeSlider
.
set
(
this
.
controller
.
volume
)
this
.
lyricsSlider
.
set
(
this
.
controller
.
lyrics
?
this
.
controller
.
lyrics
.
vttOffset
/
1000
:
0
)
}
var
measures
=
this
.
controller
.
parsedSongData
.
measures
.
filter
((
measure
,
i
,
array
)
=>
{
...
...
@@ -174,6 +184,7 @@ class Debug{
this
.
restartBtn
.
style
.
display
=
""
this
.
autoplayLabel
.
style
.
display
=
""
this
.
branchHideDiv
.
style
.
display
=
""
this
.
lyricsHideDiv
.
style
.
display
=
""
this
.
controller
=
null
}
this
.
stopMove
()
...
...
@@ -194,6 +205,9 @@ class Debug{
branch
.
ms
=
branch
.
originalMS
+
offset
})
}
if
(
this
.
controller
.
lyrics
){
this
.
controller
.
lyrics
.
offsetChange
(
value
*
1000
)
}
if
(
this
.
restartCheckbox
.
checked
&&
!
noRestart
){
this
.
restartSong
()
}
...
...
@@ -213,6 +227,14 @@ class Debug{
this
.
restartSong
()
}
}
lyricsChange
(
value
,
noRestart
){
if
(
this
.
controller
&&
this
.
controller
.
lyrics
){
this
.
controller
.
lyrics
.
offsetChange
(
undefined
,
value
*
1000
)
}
if
(
this
.
restartCheckbox
.
checked
&&
!
noRestart
){
this
.
restartSong
()
}
}
restartSong
(){
if
(
this
.
controller
){
this
.
controller
.
restartSong
()
...
...
@@ -259,6 +281,7 @@ class Debug{
this
.
offsetSlider
.
clean
()
this
.
measureNumSlider
.
clean
()
this
.
volumeSlider
.
clean
()
this
.
lyricsSlider
.
clean
()
pageEvents
.
remove
(
window
,
[
"
mousedown
"
,
"
mouseup
"
,
"
touchstart
"
,
"
touchend
"
,
"
blur
"
,
"
resize
"
],
this
.
windowSymbol
)
pageEvents
.
mouseRemove
(
this
)
...
...
@@ -285,6 +308,8 @@ class Debug{
delete
this
.
branchSelect
delete
this
.
branchResetBtn
delete
this
.
volumeDiv
delete
this
.
lyricsHideDiv
delete
this
.
lyricsOffsetDiv
delete
this
.
restartCheckbox
delete
this
.
autoplayLabel
delete
this
.
autoplayCheckbox
...
...
public/src/js/loadsong.js
View file @
3679c279
...
...
@@ -142,6 +142,12 @@ class LoadSong{
this
.
addPromise
(
loader
.
ajax
(
url
).
then
(
data
=>
{
this
.
songData
=
data
.
replace
(
/
\0
/g
,
""
).
split
(
"
\n
"
)
}),
url
)
if
(
song
.
lyrics
&&
!
songObj
.
lyricsData
){
var
url
=
this
.
getSongDir
(
song
)
+
"
main.vtt
"
this
.
addPromise
(
loader
.
ajax
(
url
).
then
(
data
=>
{
songObj
.
lyricsData
=
data
}),
url
)
}
}
if
(
this
.
touchEnabled
&&
!
assets
.
image
[
"
touch_drum
"
]){
let
img
=
document
.
createElement
(
"
img
"
)
...
...
@@ -262,8 +268,11 @@ class LoadSong{
randInt
(
min
,
max
){
return
Math
.
floor
(
Math
.
random
()
*
(
max
-
min
+
1
))
+
min
}
getSongDir
(
selectedSong
){
return
gameConfig
.
songs_baseurl
+
selectedSong
.
folder
+
"
/
"
}
getSongPath
(
selectedSong
){
var
directory
=
gameConfig
.
songs_baseurl
+
selectedSong
.
folder
+
"
/
"
var
directory
=
this
.
getSongDir
(
selectedSong
)
if
(
selectedSong
.
type
===
"
tja
"
){
return
directory
+
"
main.tja
"
}
else
{
...
...
public/src/js/lyrics.js
0 → 100644
View file @
3679c279
class
Lyrics
{
constructor
(
file
,
songOffset
,
div
){
this
.
div
=
div
this
.
stroke
=
document
.
createElement
(
"
div
"
)
this
.
stroke
.
classList
.
add
(
"
stroke
"
)
div
.
appendChild
(
this
.
stroke
)
this
.
fill
=
document
.
createElement
(
"
div
"
)
this
.
fill
.
classList
.
add
(
"
fill
"
)
div
.
appendChild
(
this
.
fill
)
this
.
current
=
0
this
.
shown
=
-
1
this
.
songOffset
=
songOffset
||
0
this
.
vttOffset
=
0
this
.
rLinebreak
=
/
\n
|
\r\n
/
this
.
lines
=
this
.
parseFile
(
file
)
this
.
length
=
this
.
lines
.
length
}
parseFile
(
file
){
var
lines
=
[]
var
commands
=
file
.
split
(
/
\n\n
|
\r\n\r\n
/
)
var
arrow
=
"
-->
"
for
(
var
i
in
commands
){
var
matches
=
commands
[
i
].
match
(
this
.
rLinebreak
)
if
(
matches
){
var
cmd
=
commands
[
i
].
slice
(
0
,
matches
.
index
)
var
value
=
commands
[
i
].
slice
(
matches
.
index
+
1
)
}
else
{
var
cmd
=
commands
[
i
]
var
value
=
""
}
if
(
cmd
.
startsWith
(
"
WEBVTT
"
)){
var
nameValue
=
cmd
.
slice
(
7
).
split
(
"
;
"
)
for
(
var
j
in
nameValue
){
var
[
name
,
value
]
=
nameValue
[
j
].
split
(
"
:
"
)
if
(
name
.
trim
().
toLowerCase
()
===
"
offset
"
){
this
.
vttOffset
=
(
parseFloat
(
value
.
trim
())
||
0
)
*
1000
}
}
}
else
{
var
time
=
null
var
index
=
cmd
.
indexOf
(
arrow
)
if
(
index
!==
-
1
){
time
=
cmd
}
else
{
var
matches
=
value
.
match
(
rLinebreak
)
if
(
matches
){
var
value1
=
value
.
slice
(
0
,
matches
.
index
)
index
=
value1
.
indexOf
(
arrow
)
if
(
index
!==
-
1
){
time
=
value1
value
=
value
.
slice
(
index
)
}
}
}
if
(
time
!==
null
){
var
start
=
time
.
slice
(
0
,
index
)
var
end
=
time
.
slice
(
index
+
arrow
.
length
)
var
index
=
end
.
indexOf
(
"
"
)
if
(
index
!==
-
1
){
end
=
end
.
slice
(
0
,
index
)
}
var
text
=
value
.
trim
()
var
textLang
=
""
var
firstLang
=
-
1
var
index2
=
-
1
while
(
true
){
var
index1
=
text
.
indexOf
(
"
<lang
"
,
index2
+
1
)
if
(
firstLang
===
-
1
){
firstLang
=
index1
}
if
(
index1
!==
-
1
){
index2
=
text
.
indexOf
(
"
>
"
,
index1
+
6
)
if
(
index2
===
-
1
){
break
}
var
lang
=
text
.
slice
(
index1
+
6
,
index2
).
toLowerCase
()
if
(
strings
.
id
===
lang
){
var
index3
=
text
.
indexOf
(
"
<lang
"
,
index2
+
1
)
if
(
index3
!==
-
1
){
textLang
=
text
.
slice
(
index2
+
1
,
index3
)
}
else
{
textLang
=
text
.
slice
(
index2
+
1
)
}
}
}
else
{
break
}
}
if
(
!
textLang
){
textLang
=
firstLang
===
-
1
?
text
:
text
.
slice
(
0
,
firstLang
)
}
lines
.
push
({
start
:
this
.
convertTime
(
start
),
end
:
this
.
convertTime
(
end
),
text
:
textLang
})
}
}
}
return
lines
}
convertTime
(
time
){
if
(
time
.
startsWith
(
"
-
"
)){
var
mul
=
-
1
time
=
time
.
slice
(
1
)
}
else
{
var
mul
=
1
}
var
array
=
time
.
split
(
"
:
"
)
if
(
array
.
length
===
2
){
var
h
=
0
var
m
=
array
[
0
]
var
s
=
array
[
1
]
}
else
{
var
h
=
parseInt
(
array
[
0
])
var
m
=
array
[
1
]
var
s
=
array
[
2
]
}
var
index
=
s
.
indexOf
(
"
,
"
)
if
(
index
!==
-
1
){
s
=
s
.
slice
(
0
,
index
)
+
"
.
"
+
s
.
slice
(
index
+
1
)
}
return
((
h
*
60
+
parseInt
(
m
))
*
60
+
parseFloat
(
s
))
*
1000
*
mul
}
update
(
ms
){
if
(
this
.
current
>=
this
.
length
){
return
}
ms
+=
this
.
songOffset
+
this
.
vttOffset
var
currentLine
=
this
.
lines
[
this
.
current
]
while
(
currentLine
&&
ms
>
currentLine
.
end
){
currentLine
=
this
.
lines
[
++
this
.
current
]
}
if
(
this
.
shown
!==
this
.
current
){
if
(
currentLine
&&
ms
>=
currentLine
.
start
){
this
.
setText
(
this
.
lines
[
this
.
current
].
text
)
this
.
shown
=
this
.
current
}
else
if
(
this
.
shown
!==
-
1
){
this
.
setText
(
""
)
this
.
shown
=
-
1
}
}
}
setText
(
text
){
this
.
stroke
.
innerHTML
=
this
.
fill
.
innerHTML
=
""
var
hasRuby
=
false
while
(
text
){
var
matches
=
text
.
match
(
this
.
rLinebreak
)
var
index1
=
matches
?
matches
.
index
:
-
1
var
index2
=
text
.
indexOf
(
"
<ruby>
"
)
if
(
index1
!==
-
1
&&
(
index2
===
-
1
||
index2
>
index1
)){
this
.
textNode
(
text
.
slice
(
0
,
index1
))
this
.
linebreakNode
()
text
=
text
.
slice
(
index1
+
matches
[
0
].
length
)
}
else
if
(
index2
!==
-
1
){
hasRuby
=
true
this
.
textNode
(
text
.
slice
(
0
,
index2
))
text
=
text
.
slice
(
index2
+
6
)
var
index
=
text
.
indexOf
(
"
</ruby>
"
)
if
(
index
!==
-
1
){
var
ruby
=
text
.
slice
(
0
,
index
)
text
=
text
.
slice
(
index
+
7
)
}
else
{
var
ruby
=
text
text
=
""
}
var
index
=
ruby
.
indexOf
(
"
<rt>
"
)
if
(
index
!==
-
1
){
var
node1
=
ruby
.
slice
(
0
,
index
)
ruby
=
ruby
.
slice
(
index
+
4
)
var
index
=
ruby
.
indexOf
(
"
</rt>
"
)
if
(
index
!==
-
1
){
var
node2
=
ruby
.
slice
(
0
,
index
)
}
else
{
var
node2
=
ruby
}
}
else
{
var
node1
=
ruby
var
node2
=
""
}
this
.
rubyNode
(
node1
,
node2
)
}
else
{
this
.
textNode
(
text
)
break
}
}
}
insertNode
(
func
){
this
.
stroke
.
appendChild
(
func
())
this
.
fill
.
appendChild
(
func
())
}
textNode
(
text
){
this
.
insertNode
(()
=>
document
.
createTextNode
(
text
))
}
linebreakNode
(){
this
.
insertNode
(()
=>
document
.
createElement
(
"
br
"
))
}
rubyNode
(
node1
,
node2
){
this
.
insertNode
(()
=>
{
var
ruby
=
document
.
createElement
(
"
ruby
"
)
var
rt
=
document
.
createElement
(
"
rt
"
)
ruby
.
appendChild
(
document
.
createTextNode
(
node1
))
rt
.
appendChild
(
document
.
createTextNode
(
node2
))
ruby
.
appendChild
(
rt
)
return
ruby
})
}
setScale
(
ratio
){
this
.
div
.
style
.
setProperty
(
"
--scale
"
,
ratio
)
}
offsetChange
(
songOffset
,
vttOffset
){
if
(
typeof
songOffset
!==
"
undefined
"
){
this
.
songOffset
=
songOffset
}
if
(
typeof
vttOffset
!==
"
undefined
"
){
this
.
vttOffset
=
vttOffset
}
this
.
setText
(
""
)
this
.
current
=
0
this
.
shown
=
-
1
}
clean
(){
if
(
this
.
shown
!==
-
1
){
this
.
setText
(
""
)
}
delete
this
.
div
delete
this
.
stroke
delete
this
.
fill
delete
this
.
lines
}
}
public/src/js/songselect.js
View file @
3679c279
...
...
@@ -127,7 +127,8 @@ class SongSelect{
maker
:
song
.
maker
,
canJump
:
true
,
hash
:
song
.
hash
||
song
.
title
,
order
:
song
.
order
order
:
song
.
order
,
lyrics
:
song
.
lyrics
})
}
this
.
songs
.
sort
((
a
,
b
)
=>
{
...
...
@@ -802,7 +803,8 @@ class SongSelect{
"
offset
"
:
selectedSong
.
offset
,
"
songSkin
"
:
selectedSong
.
songSkin
,
"
stars
"
:
selectedSong
.
courses
[
diff
].
stars
,
"
hash
"
:
selectedSong
.
hash
"
hash
"
:
selectedSong
.
hash
,
"
lyrics
"
:
selectedSong
.
lyrics
},
autoplay
,
multiplayer
,
touch
)
}
toOptions
(
moveBy
){
...
...
public/src/js/view.js
View file @
3679c279
...
...
@@ -247,6 +247,9 @@
}
this
.
fillComboCache
()
this
.
setDonBgHeight
()
if
(
this
.
controller
.
lyrics
){
this
.
controller
.
lyrics
.
setScale
(
ratio
/
this
.
pixelRatio
)
}
resized
=
true
}
else
if
(
this
.
controller
.
game
.
paused
&&
!
document
.
hasFocus
()){
return
...
...
@@ -283,6 +286,10 @@
this
.
setDonBgHeight
()
}
if
(
this
.
controller
.
lyrics
){
this
.
controller
.
lyrics
.
update
(
ms
)
}
ctx
.
save
()
ctx
.
translate
(
0
,
frameTop
)
...
...
public/src/views/debug.html
View file @
3679c279
...
...
@@ -24,6 +24,12 @@
<div
class=
"music-volume input-slider"
>
<span
class=
"reset"
>
x
</span><input
type=
"text"
value=
""
readonly
><span
class=
"minus"
>
-
</span><span
class=
"plus"
>
+
</span>
</div>
<div
class=
"lyrics-hide"
>
<div>
Lyrics offset:
</div>
<div
class=
"lyrics-offset input-slider"
>
<span
class=
"reset"
>
x
</span><input
type=
"text"
value=
""
readonly
><span
class=
"minus"
>
-
</span><span
class=
"plus"
>
+
</span>
</div>
</div>
<label
class=
"change-restart-label"
><input
class=
"change-restart"
type=
"checkbox"
>
Restart on change
</label>
<label
class=
"autoplay-label"
><input
class=
"autoplay"
type=
"checkbox"
>
Auto play
</label>
<div
class=
"bottom-btns"
>
...
...
public/src/views/game.html
View file @
3679c279
...
...
@@ -8,6 +8,7 @@
<div
id=
"touch-drum-img"
></div>
</div>
<canvas
id=
"canvas"
></canvas>
<div
id=
"song-lyrics"
></div>
<div
id=
"touch-buttons"
>
<div
id=
"touch-full-btn"
></div><div
id=
"touch-pause-btn"
></div>
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment