2019-01-28 09:57:18 +08:00
|
|
|
|
class Logo{
|
2022-02-11 22:28:22 +08:00
|
|
|
|
constructor(...args){
|
|
|
|
|
this.init(...args)
|
|
|
|
|
}
|
|
|
|
|
init(){
|
2019-01-28 09:57:18 +08:00
|
|
|
|
this.canvas = document.getElementById("logo")
|
|
|
|
|
this.ctx = this.canvas.getContext("2d")
|
Custom scripting, #song=, translations
- A song can be linked directly by adding "#song=<id>" to the url, replace `<id>` with the id in the database, after loading it jumps immediately jumps to the difficulty selection
- Added tutorial translations
- Fixed song preview not playing
- Use text fallback for the logo when there are no vectors
- Increased combo cache by 1 pixel
- A custom javascript file can be loaded from config.json by defining "custom_js" value
- Added lots of events to help writing custom js files: `version-link, title-screen, language-change, song-select, song-select-move, song-select-difficulty, song-select-back, about, about-link, tutorial, import-songs, import-songs-default, session, session-start, session-end, debug, load-song, load-song-player2, load-song-unfocused, load-song-cancel, load-song-error, game-start, key-events, p2-game-end, p2-disconnected, p2-abandoned, pause, unpause, pause-restart, pause-song-select, game-lag, scoresheet, scoresheet-player2`
- Event syntax example:
```js
addEventListener("game-start", event => {
console.log("game-start", event.detail)
})
```
2019-02-14 17:32:45 +08:00
|
|
|
|
this.pathSvg = failedTests.indexOf("Path2D SVG") === -1 && vectors.logo1
|
2019-01-30 00:10:56 +08:00
|
|
|
|
this.symbolFont = "TnT, Meiryo, sans-serif"
|
2019-01-28 09:57:18 +08:00
|
|
|
|
this.symbols = [{
|
2019-01-30 00:10:56 +08:00
|
|
|
|
x: 315, y: 18, xAlt: 15, scale: true, text: "ブ",
|
|
|
|
|
path: new Path2D(vectors.logo5)
|
2019-01-28 09:57:18 +08:00
|
|
|
|
}, {
|
2019-01-30 00:10:56 +08:00
|
|
|
|
x: 267, y: 50, yAlt: -34, scale: true, text: "ェ",
|
|
|
|
|
path: new Path2D(vectors.logo4)
|
2019-01-28 09:57:18 +08:00
|
|
|
|
}, {
|
2019-01-30 00:10:56 +08:00
|
|
|
|
x: 197, y: 7, xAlt: 15, scale: true, text: "ウ",
|
|
|
|
|
path: new Path2D(vectors.logo3)
|
2019-01-28 09:57:18 +08:00
|
|
|
|
}, {
|
2019-01-30 00:10:56 +08:00
|
|
|
|
x: 87, y: 7, xAlt: 15, text: "鼓",
|
|
|
|
|
path: new Path2D(vectors.logo2),
|
|
|
|
|
shadow: new Path2D(vectors.logo2Shadow)
|
2019-01-28 09:57:18 +08:00
|
|
|
|
}, {
|
2019-01-30 00:10:56 +08:00
|
|
|
|
x: 22, y: 16, xAlt: 10, scaleAlt: true, text: "太",
|
|
|
|
|
path: new Path2D(vectors.logo1)
|
2019-01-28 09:57:18 +08:00
|
|
|
|
}]
|
|
|
|
|
pageEvents.add(window, "resize", this.update.bind(this))
|
|
|
|
|
}
|
|
|
|
|
updateSubtitle(){
|
|
|
|
|
this.subtitleGradient = ["#df600d", "#d8446f", "#b2147b", "#428ac2", "#1f9099"]
|
|
|
|
|
this.subtitle = []
|
|
|
|
|
this.subtitleW = 0
|
|
|
|
|
var index = 0
|
|
|
|
|
var latinLowercase = /[a-z]/
|
|
|
|
|
for(var i = 0; i < strings.taikoWeb.length; i++){
|
|
|
|
|
var letter = strings.taikoWeb[i]
|
|
|
|
|
var width = 57
|
|
|
|
|
if(letter === "ェ"){
|
|
|
|
|
width = 40
|
|
|
|
|
}else if(letter === " "){
|
|
|
|
|
width = 20
|
|
|
|
|
}else if(letter === "i"){
|
|
|
|
|
width = 22
|
|
|
|
|
}else if(letter === "T"){
|
|
|
|
|
width = 30
|
|
|
|
|
}else if(latinLowercase.test(letter)){
|
|
|
|
|
width = 38
|
|
|
|
|
}
|
|
|
|
|
this.subtitle.push({
|
|
|
|
|
letter: letter,
|
|
|
|
|
x: this.subtitleW + width / 2,
|
|
|
|
|
index: letter === " " ? index : index++
|
|
|
|
|
})
|
|
|
|
|
this.subtitleW += width
|
|
|
|
|
}
|
|
|
|
|
this.update()
|
|
|
|
|
}
|
|
|
|
|
update(){
|
|
|
|
|
var ctx = this.ctx
|
|
|
|
|
ctx.save()
|
|
|
|
|
|
|
|
|
|
this.width = 1170
|
|
|
|
|
this.height = 390
|
|
|
|
|
var pixelRatio = window.devicePixelRatio || 1
|
|
|
|
|
var winW = this.canvas.offsetWidth * pixelRatio
|
|
|
|
|
var winH = this.canvas.offsetHeight * pixelRatio
|
2022-02-18 04:50:07 +08:00
|
|
|
|
this.canvas.width = Math.max(1, winW)
|
|
|
|
|
this.canvas.height = Math.max(1, winH)
|
2019-01-28 09:57:18 +08:00
|
|
|
|
ctx.scale(winW / this.width, winH / this.height)
|
|
|
|
|
|
|
|
|
|
ctx.lineJoin = "round"
|
|
|
|
|
ctx.miterLimit = 1
|
|
|
|
|
ctx.textBaseline = "top"
|
|
|
|
|
ctx.textAlign = "center"
|
2019-01-30 00:10:56 +08:00
|
|
|
|
if(!this.pathSvg){
|
|
|
|
|
ctx.font = "100px " + this.symbolFont
|
|
|
|
|
}
|
2019-01-28 09:57:18 +08:00
|
|
|
|
|
|
|
|
|
for(var i = 0; i < this.symbols.length; i++){
|
|
|
|
|
ctx.strokeStyle = "#3f0406"
|
|
|
|
|
ctx.lineWidth = 13.5
|
|
|
|
|
this.drawSymbol(this.symbols[i], "stroke", 4)
|
|
|
|
|
}
|
2019-01-30 00:10:56 +08:00
|
|
|
|
ctx.font = this.bold(strings.font) + "55px " + strings.font
|
2019-01-28 09:57:18 +08:00
|
|
|
|
this.subtitleIterate((letter, x) => {
|
|
|
|
|
ctx.lineWidth = strings.id === "en" ? 19 : 18.5
|
|
|
|
|
ctx.strokeStyle = "#3f0406"
|
|
|
|
|
ctx.strokeText(letter, x, 315)
|
|
|
|
|
})
|
2019-01-30 00:10:56 +08:00
|
|
|
|
if(this.pathSvg){
|
|
|
|
|
ctx.fillStyle = "#3f0406"
|
|
|
|
|
ctx.fillRect(400, 180, 30, 50)
|
|
|
|
|
}else{
|
|
|
|
|
ctx.font = "100px " + this.symbolFont
|
|
|
|
|
}
|
2019-01-28 09:57:18 +08:00
|
|
|
|
for(var i = 0; i < this.symbols.length; i++){
|
|
|
|
|
var symbol = this.symbols[i]
|
|
|
|
|
ctx.strokeStyle = "#7c361e"
|
|
|
|
|
ctx.lineWidth = 13.5
|
|
|
|
|
this.drawSymbol(symbol, "stroke")
|
|
|
|
|
ctx.strokeStyle = "#fff"
|
|
|
|
|
ctx.lineWidth = 7.5
|
|
|
|
|
this.drawSymbol(symbol, "stroke")
|
2019-01-30 00:10:56 +08:00
|
|
|
|
if(this.pathSvg){
|
|
|
|
|
var grd = ctx.createLinearGradient(0, 55 - symbol.y, 0, 95 - symbol.y)
|
|
|
|
|
grd.addColorStop(0, "#a41f1e")
|
|
|
|
|
grd.addColorStop(1, "#a86a29")
|
|
|
|
|
ctx.fillStyle = grd
|
|
|
|
|
this.drawSymbol(symbol, "fill")
|
|
|
|
|
ctx.save()
|
|
|
|
|
ctx.scale(symbol.scale ? 2.8 : 3.2, 3.2)
|
|
|
|
|
ctx.translate(symbol.x, symbol.y)
|
|
|
|
|
ctx.clip(symbol.path)
|
|
|
|
|
}
|
2019-01-28 09:57:18 +08:00
|
|
|
|
grd = ctx.createLinearGradient(0, 55 - symbol.y, 0, 95 - symbol.y)
|
|
|
|
|
grd.addColorStop(0, "#d80e11")
|
|
|
|
|
grd.addColorStop(1, "#e08f19")
|
|
|
|
|
ctx.fillStyle = grd
|
2019-01-30 00:10:56 +08:00
|
|
|
|
if(this.pathSvg){
|
|
|
|
|
ctx.translate(3, 2)
|
|
|
|
|
ctx.fill(symbol.shadow || symbol.path)
|
|
|
|
|
ctx.restore()
|
|
|
|
|
}else{
|
|
|
|
|
this.drawSymbol(symbol, "fill")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(this.pathSvg){
|
|
|
|
|
ctx.fillStyle = "#fff"
|
|
|
|
|
ctx.fillRect(382, 85, 30, 15)
|
|
|
|
|
ctx.fillRect(402, 145, 15, 15)
|
|
|
|
|
}else{
|
|
|
|
|
ctx.font = this.bold(strings.font) + "55px " + strings.font
|
2019-01-28 09:57:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.subtitleIterate((letter, x) => {
|
|
|
|
|
ctx.lineWidth = strings.id === "en" ? 19 : 18.5
|
|
|
|
|
ctx.strokeStyle = "#7c361e"
|
|
|
|
|
ctx.strokeText(letter, x, 305)
|
|
|
|
|
})
|
|
|
|
|
this.subtitleIterate((letter, x, i) => {
|
|
|
|
|
ctx.lineWidth = strings.id === "en" ? 11 : 9.5
|
|
|
|
|
ctx.strokeStyle = this.getSubtitleGradient(i)
|
|
|
|
|
ctx.fillStyle = "#fff"
|
|
|
|
|
ctx.strokeText(letter, x, 305)
|
|
|
|
|
ctx.fillText(letter, x, 305)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ctx.restore()
|
|
|
|
|
}
|
|
|
|
|
drawSymbol(symbol, action, y){
|
|
|
|
|
var ctx = this.ctx
|
|
|
|
|
ctx.save()
|
2019-01-30 00:10:56 +08:00
|
|
|
|
ctx.scale((symbol.scale || !this.pathSvg && symbol.scaleAlt) ? 2.8 : 3.2, 3.2)
|
2019-01-28 09:57:18 +08:00
|
|
|
|
ctx.translate(symbol.x, symbol.y + (y || 0))
|
2019-01-30 00:10:56 +08:00
|
|
|
|
if(this.pathSvg){
|
|
|
|
|
ctx[action](symbol.path)
|
|
|
|
|
}else{
|
|
|
|
|
ctx[action + "Text"](symbol.text, 30 + (symbol.xAlt || 0), -4 + (symbol.yAlt || 0))
|
|
|
|
|
}
|
2019-01-28 09:57:18 +08:00
|
|
|
|
ctx.restore()
|
|
|
|
|
}
|
|
|
|
|
subtitleIterate(func){
|
|
|
|
|
for(var i = this.subtitle.length; i--;){
|
|
|
|
|
var subtitleObj = this.subtitle[i]
|
|
|
|
|
var x = (this.width - this.subtitleW) / 2 + subtitleObj.x
|
|
|
|
|
func(subtitleObj.letter, x, subtitleObj.index)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
getSubtitleGradient(index){
|
|
|
|
|
var sign = 1
|
|
|
|
|
var position = 0
|
|
|
|
|
var length = this.subtitleGradient.length - 1
|
|
|
|
|
while(index >= 0){
|
|
|
|
|
if(sign === 1){
|
|
|
|
|
position = index % length
|
|
|
|
|
}else{
|
|
|
|
|
position = length - (index % length)
|
|
|
|
|
}
|
|
|
|
|
sign *= -1
|
|
|
|
|
index -= length
|
|
|
|
|
}
|
|
|
|
|
return this.subtitleGradient[position]
|
|
|
|
|
}
|
|
|
|
|
bold(font){
|
|
|
|
|
return font === "Microsoft YaHei, sans-serif" ? "bold " : ""
|
|
|
|
|
}
|
|
|
|
|
clean(){
|
|
|
|
|
pageEvents.remove(window, "resize")
|
|
|
|
|
delete this.symbols
|
|
|
|
|
delete this.ctx
|
|
|
|
|
delete this.canvas
|
|
|
|
|
}
|
|
|
|
|
}
|