From 68d69d4a0ae45c8c10c33a0284db991c5a0516d1 Mon Sep 17 00:00:00 2001 From: LoveEevee Date: Sun, 14 Oct 2018 11:04:31 +0300 Subject: [PATCH 1/5] SongSelect: Add About screen --- .github/ISSUE_TEMPLATE.md | 2 + public/src/css/main.css | 96 +++++++++++++++++++--------- public/src/js/about.js | 122 ++++++++++++++++++++++++++++++++++++ public/src/js/assets.js | 3 +- public/src/js/loader.js | 9 --- public/src/js/main.js | 37 +++++++++++ public/src/js/songselect.js | 37 +++++++++-- public/src/js/tutorial.js | 2 +- public/src/js/view.js | 6 +- public/src/views/about.html | 27 ++++++++ templates/index.html | 2 +- 11 files changed, 296 insertions(+), 47 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 public/src/js/about.js create mode 100644 public/src/views/about.html diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..95fd27a --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,2 @@ +###### Describe the problem you are having below. Please include a screenshot and the diagnostic information. + diff --git a/public/src/css/main.css b/public/src/css/main.css index b91867a..b814f6a 100644 --- a/public/src/css/main.css +++ b/public/src/css/main.css @@ -12,6 +12,7 @@ body{ width: 100%; height: 100%; background: #fe7839; + position: relative; user-select: none; touch-action: none; } @@ -135,30 +136,34 @@ body{ #tutorial{ background: rgb(246, 234, 212); color: black; - border: 5px black solid; - border-radius: 10px; - height: 65%; - max-width: 800px; - padding: 20px; - margin: 8px; - font-size: 16pt; + border: 0.25em black solid; + border-radius: 0.5em; + width: 800px; + padding: 1em; + margin: 1em; + font-size: 21px; position: relative; } +.touch-enabled #tutorial{ + font-size: 3vmin; +} #tutorial-title{ z-index: 1; position: absolute; color: white; - top: -25px; - font-size: 26pt; + top: -0.7em; + font-size: 1.65em; } #tutorial-content{ - padding: 15px 30px; + margin: 0.7em 0; + overflow-y: auto; + max-height: calc(100vh - 14em); } kbd{ font-family: inherit; padding: 0.1em 0.6em; border: 1px solid #ccc; - font-size: 13px; + font-size: 0.6em; background-color: #f7f7f7; color: #333; box-shadow: 0 1px 0px rgba(0, 0, 0, 0.2), 0 0 0 2px #ffffff inset; @@ -169,26 +174,61 @@ kbd{ white-space: nowrap; } .taibtn{ - bottom: 15px; - margin: 0 auto; - position: absolute; - right: 15px; - padding: 10px 40px; - border-radius: 15px; - border: 3px rgba(218, 205, 178, 1) solid; + display: inline-block; + padding: 0.4em 0.4em; + border-radius: 0.5em; + border: 0.1em rgba(218, 205, 178, 1) solid; cursor: pointer; -} -.taibtn:hover{ - z-index: 1; - color: white; - background: rgb(255, 181, 71); - border-color: white; -} -.taibtn::before{ - padding: 0 40px; + font-size: 1.4em; + box-sizing: border-box; + color: #555; + text-align: center; } #tutorial-end-button{ - font-size: 22pt; + float: right; + padding: 0.4em 1.5em; + font-weight: bold; + border-color: #000; + color: #000; +} +.taibtn:hover, +#tutorial-end-button:hover{ + position: relative; + z-index: 1; + color: #fff; + background: #ffb547; + border-color: #fff; +} +.taibtn::before{ + padding-left: inherit; +} +#about-link-btns{ + float: left; + display: flex; +} +#about-link-btns .taibtn{ + margin-right: 0.4em; +} +#diag-txt{ + width: 100%; + height: 5em; + font-size: inherit; + resize: none; + word-break: break-all; + margin-bottom: 1em; + background: #fff; + border: 1px solid #a9a9a9; +} +.text-warn{ + color: #d00; +} +.link-btn a{ + color: inherit; + text-decoration: none; + pointer-events: none; +} +.nowrap{ + white-space: nowrap; } @keyframes bgscroll{ from{ diff --git a/public/src/js/about.js b/public/src/js/about.js new file mode 100644 index 0000000..29eeb1b --- /dev/null +++ b/public/src/js/about.js @@ -0,0 +1,122 @@ +class About{ + constructor(touchEnabled){ + this.touchEnabled = touchEnabled + loader.changePage("about") + cancelTouch = false + + this.endButton = document.getElementById("tutorial-end-button") + this.diagTxt = document.getElementById("diag-txt") + this.version = document.getElementById("version-link").href + this.tutorialOuter = document.getElementById("tutorial-outer") + if(touchEnabled){ + this.tutorialOuter.classList.add("touch-enabled") + } + this.linkGithub = document.getElementById("link-github") + this.linkEmail = document.getElementById("link-email") + + pageEvents.add(this.linkGithub, ["click", "touchend"], this.linkButton) + pageEvents.add(this.linkEmail, ["click", "touchend"], this.linkButton) + pageEvents.once(this.endButton, ["mousedown", "touchstart"]).then(this.onEnd.bind(this)) + pageEvents.keyOnce(this, 13, "down").then(this.onEnd.bind(this)) + + this.gamepad = new Gamepad({ + "confirm": ["start", "b", "ls", "rs"] + }, this.onEnd.bind(this)) + + this.addDiag() + } + onEnd(event){ + var touched = false + if(event && event.type === "touchstart"){ + event.preventDefault() + touched = true + } + this.clean() + assets.sounds["don"].play() + localStorage.setItem("tutorial", "true") + setTimeout(() => { + new SongSelect("about", false, touched) + }, 500) + } + addDiag(){ + var diag = [] + + diag.push("```") + diag.push("Taiko-Web version: " + this.version) + diag.push("User agent: " + navigator.userAgent) + diag.push("Screen size: " + innerWidth + "x" + innerHeight + ", outer: " + outerWidth + "x" + outerHeight + ", ratio: " + (window.devicePixelRatio || 1).toFixed(2)) + if(this.touchEnabled){ + diag.push("Touch enabled: true") + } + if(!fullScreenSupported){ + diag.push("Full screen supported: false") + } + if("getGamepads" in navigator){ + var gamepads = navigator.getGamepads() + for(var i = 0; i < gamepads.length; i++){ + if(gamepads[i]){ + var gamepadDiag = [] + gamepadDiag.push(gamepads[i].id) + gamepadDiag.push("buttons: " + gamepads[i].buttons.length) + gamepadDiag.push("axes: " + gamepads[i].axes.length) + diag.push("Gamepad #" + (i + 1) + ": " + gamepadDiag.join(", ")) + } + } + } + var errorObj = {} + if(localStorage["lastError"]){ + try{ + errorObj = JSON.parse(localStorage["lastError"]) + }catch(e){} + } + if(errorObj.timestamp && errorObj.stack){ + if(errorObj.timestamp + 1000 * 60 * 60 * 24 > (+new Date)){ + diag.push("Last error: " + errorObj.stack) + diag.push("Error date: " + new Date(errorObj.timestamp).toGMTString()) + }else{ + localStorage.removeItem("lastError") + } + } + diag.push("```") + + var body = this.diagTxt.contentWindow.document.body + body.innerText = diag.join("\n") + + body.setAttribute("style", ` + font-family: monospace; + margin: 2px 0 0 2px; + white-space: pre-wrap; + word-break: break-all; + cursor: text; + `) + body.setAttribute("onblur", ` + getSelection().removeAllRanges() + `) + if(!this.touchEnabled){ + body.setAttribute("onfocus", ` + var selection = getSelection() + selection.removeAllRanges() + var range = document.createRange() + range.selectNodeContents(document.body) + selection.addRange(range) + `) + } + } + linkButton(event){ + event.currentTarget.getElementsByTagName("a")[0].click() + } + clean(){ + cancelTouch = true + this.gamepad.clean() + pageEvents.remove(this.linkGithub, ["click", "touchend"]) + pageEvents.remove(this.linkEmail, ["click", "touchend"]) + pageEvents.remove(this.endButton, ["mousedown", "touchstart"]) + pageEvents.keyRemove(this, 13) + delete this.endButton + delete this.diagTxt + delete this.version + delete this.tutorialOuter + delete this.linkGithub + delete this.linkEmail + } +} diff --git a/public/src/js/assets.js b/public/src/js/assets.js index e289e16..fde1bec 100644 --- a/public/src/js/assets.js +++ b/public/src/js/assets.js @@ -123,7 +123,8 @@ var assets = { "loadsong.html", "songselect.html", "titlescreen.html", - "tutorial.html" + "tutorial.html", + "about.html" ], "songs": [], diff --git a/public/src/js/loader.js b/public/src/js/loader.js index e8bda9d..9d1f188 100644 --- a/public/src/js/loader.js +++ b/public/src/js/loader.js @@ -6,15 +6,6 @@ class Loader{ this.canvasTest = new CanvasTest() p2 = new P2Connection() this.ajax("src/views/loader.html").then(this.run.bind(this)) - - pageEvents.add(root, ["touchstart", "touchmove", "touchend"], event => { - event.preventDefault() - }) - var versionDiv = document.getElementById("version") - var versionLink = document.getElementById("version-link") - pageEvents.add(versionDiv, ["click", "touchend"], () => { - versionLink.click() - }) } run(page){ this.promises = [] diff --git a/public/src/js/main.js b/public/src/js/main.js index 98f6121..a22b310 100644 --- a/public/src/js/main.js +++ b/public/src/js/main.js @@ -1,3 +1,16 @@ +addEventListener("error", err => { + var stack + if("error" in err){ + stack = err.error.stack + }else{ + stack = err.message + "\n at " + err.filename + ":" + err.lineno + ":" + err.colno + } + localStorage["lastError"] = JSON.stringify({ + timestamp: +new Date, + stack: stack + }) +}) + function toggleFullscreen(){ if("requestFullscreen" in root){ if(document.fullscreenElement){ @@ -19,6 +32,14 @@ function toggleFullscreen(){ } } } + +function resizeRoot(){ + if(lastHeight !== innerHeight){ + lastHeight = innerHeight + root.style.height = innerHeight + "px" + } +} + var root = document.documentElement var fullScreenSupported = "requestFullscreen" in root || "webkitRequestFullscreen" in root || "mozRequestFullScreen" in root @@ -26,6 +47,22 @@ var pageEvents = new PageEvents() var snd = {} var p2 var disableBlur = false +var cancelTouch = true +var lastHeight + +pageEvents.add(root, ["touchstart", "touchmove", "touchend"], event => { + if(event.cancelable && cancelTouch){ + event.preventDefault() + } +}) +var versionDiv = document.getElementById("version") +var versionLink = document.getElementById("version-link") +pageEvents.add(versionDiv, ["click", "touchend"], () => { + versionLink.click() +}) +resizeRoot() +pageEvents.add(window, "resize", resizeRoot) + var loader = new Loader(() => { new Titlescreen() }) diff --git a/public/src/js/songselect.js b/public/src/js/songselect.js index 53248e9..aee12cb 100644 --- a/public/src/js/songselect.js +++ b/public/src/js/songselect.js @@ -29,6 +29,12 @@ class SongSelect{ border: ["#d6ffff", "#6bae9c"], outline: "#31ae94" }, + "about": { + sort: 7, + background: "#91cfff", + border: ["#dff0ff", "#6890b2"], + outline: "#217abb" + }, "J-POP": { sort: 0, background: "#219fbb", @@ -114,7 +120,9 @@ class SongSelect{ category: "ランダム" }) if(touchEnabled){ - fromTutorial = false + if(fromTutorial === "tutorial"){ + fromTutorial = false + } }else{ this.songs.push({ title: "あそびかた説明", @@ -123,6 +131,12 @@ class SongSelect{ category: "ランダム" }) } + this.songs.push({ + title: "について", + skin: this.songSkin.about, + action: "about", + category: "ランダム" + }) this.songs.push({ title: "もどる", skin: this.songSkin.back, @@ -155,16 +169,20 @@ class SongSelect{ this.selectedDiff = 0 assets.sounds["bgm_songsel"].playLoop(0.1, false, 0, 1.442, 3.506) - if(touchEnabled || !fromTutorial && "selectedSong" in localStorage){ + if(!touchEnabled && !fromTutorial && !("selectedSong" in localStorage)){ + fromTutorial = "tutorial" + } + + if(fromTutorial){ + this.selectedSong = this.songs.findIndex(song => song.action === fromTutorial) + this.playBgm(true) + }else{ if("selectedSong" in localStorage){ this.selectedSong = Math.min(Math.max(0, localStorage["selectedSong"] |0), this.songs.length) } assets.sounds["song-select"].play() snd.musicGain.fadeOut() this.playBgm(false) - }else{ - this.selectedSong = this.songs.findIndex(song => song.action === "tutorial") - this.playBgm(true) } if("selectedDiff" in localStorage){ this.selectedDiff = Math.min(Math.max(0, localStorage["selectedDiff"] |0), 4) @@ -454,6 +472,8 @@ class SongSelect{ }, 200) }else if(currentSong.action === "tutorial"){ this.toTutorial() + }else if(currentSong.action === "about"){ + this.toAbout() } this.pointer(false) } @@ -505,6 +525,13 @@ class SongSelect{ new Tutorial(true) }, 500) } + toAbout(){ + assets.sounds["don"].play() + this.clean() + setTimeout(() => { + new About(this.touchEnabled) + }, 500) + } redraw(){ if(!this.redrawRunning){ diff --git a/public/src/js/tutorial.js b/public/src/js/tutorial.js index 3f9e1e3..b340d2c 100644 --- a/public/src/js/tutorial.js +++ b/public/src/js/tutorial.js @@ -22,7 +22,7 @@ class Tutorial{ assets.sounds["don"].play() localStorage.setItem("tutorial", "true") setTimeout(() => { - new SongSelect(this.fromSongSel, false, touched) + new SongSelect(this.fromSongSel ? "tutorial" : false, false, touched) }, 500) } clean(){ diff --git a/public/src/js/view.js b/public/src/js/view.js index 99d37ae..a9f5dcf 100644 --- a/public/src/js/view.js +++ b/public/src/js/view.js @@ -949,8 +949,10 @@ class View{ } clean(){ pageEvents.mouseRemove(this) - if(this.controller.multiplayer === 2 && this.canvas){ - this.canvas.canvas.parentNode.removeChild(this.canvas.canvas) + if(this.controller.multiplayer === 2){ + if(this.canvas){ + this.canvas.canvas.parentNode.removeChild(this.canvas.canvas) + } }else{ this.cursor.parentNode.removeChild(this.cursor) } diff --git a/public/src/views/about.html b/public/src/views/about.html new file mode 100644 index 0000000..f2581b2 --- /dev/null +++ b/public/src/views/about.html @@ -0,0 +1,27 @@ +
+
+
について / About
+
+ このシミュレータは現在開発中です。
+ バグが発生した場合は、報告してください。
+ GitHubかメールでバグを報告してください。
+ 以下の診断情報を含めてください!
+
+ This simulator is still in development.
+ Please report any bugs you find.
+ You can report bugs either via GitHub or email.
+ Be sure to include the following diagnostic data! + +
+ + +
OK
+
+
diff --git a/templates/index.html b/templates/index.html index d813baf..d4b8f13 100644 --- a/templates/index.html +++ b/templates/index.html @@ -15,7 +15,6 @@ 太鼓の達人ウェブ - Taiko no Tatsujin Web - @@ -52,6 +51,7 @@ + From a0635812bb3cb1497407d72ea6fb33287db075db Mon Sep 17 00:00:00 2001 From: LoveEevee Date: Sun, 14 Oct 2018 13:37:27 +0300 Subject: [PATCH 2/5] Add body to button links, add performance to diagnostic --- public/src/css/main.css | 3 +- public/src/js/about.js | 70 +++++++++++++++++++++++++------------ public/src/js/canvastest.js | 3 +- public/src/js/loader.js | 7 +++- public/src/js/main.js | 5 +++ public/src/views/about.html | 2 +- 6 files changed, 63 insertions(+), 27 deletions(-) diff --git a/public/src/css/main.css b/public/src/css/main.css index b814f6a..225619d 100644 --- a/public/src/css/main.css +++ b/public/src/css/main.css @@ -209,7 +209,8 @@ kbd{ #about-link-btns .taibtn{ margin-right: 0.4em; } -#diag-txt{ +#diag-txt textarea, +#diag-txt iframe{ width: 100%; height: 5em; font-size: inherit; diff --git a/public/src/js/about.js b/public/src/js/about.js index 29eeb1b..c6cb501 100644 --- a/public/src/js/about.js +++ b/public/src/js/about.js @@ -1,5 +1,7 @@ class About{ constructor(touchEnabled){ + this.issueTemplate = "###### Describe the problem you are having below. Please include a screenshot and the diagnostic information." + this.touchEnabled = touchEnabled loader.changePage("about") cancelTouch = false @@ -14,8 +16,8 @@ class About{ this.linkGithub = document.getElementById("link-github") this.linkEmail = document.getElementById("link-email") - pageEvents.add(this.linkGithub, ["click", "touchend"], this.linkButton) - pageEvents.add(this.linkEmail, ["click", "touchend"], this.linkButton) + pageEvents.add(this.linkGithub, ["click", "touchend"], this.linkButton.bind(this)) + pageEvents.add(this.linkEmail, ["click", "touchend"], this.linkButton.bind(this)) pageEvents.once(this.endButton, ["mousedown", "touchstart"]).then(this.onEnd.bind(this)) pageEvents.keyOnce(this, 13, "down").then(this.onEnd.bind(this)) @@ -51,6 +53,8 @@ class About{ if(!fullScreenSupported){ diag.push("Full screen supported: false") } + diag.push("Blur performance: " + perf.blur + "ms, all images: " + perf.allImg + "ms") + diag.push("Page load: " + (perf.load / 1000).toFixed(1) + "s") if("getGamepads" in navigator){ var gamepads = navigator.getGamepads() for(var i = 0; i < gamepads.length; i++){ @@ -78,32 +82,48 @@ class About{ } } diag.push("```") + var diag = diag.join("\n") - var body = this.diagTxt.contentWindow.document.body - body.innerText = diag.join("\n") - - body.setAttribute("style", ` - font-family: monospace; - margin: 2px 0 0 2px; - white-space: pre-wrap; - word-break: break-all; - cursor: text; - `) - body.setAttribute("onblur", ` - getSelection().removeAllRanges() - `) - if(!this.touchEnabled){ - body.setAttribute("onfocus", ` - var selection = getSelection() - selection.removeAllRanges() - var range = document.createRange() - range.selectNodeContents(document.body) - selection.addRange(range) + if(navigator.userAgent.indexOf("Android") >= 0){ + var iframe = document.createElement("iframe") + this.diagTxt.appendChild(iframe) + var body = iframe.contentWindow.document.body + body.innerText = diag + + body.setAttribute("style", ` + font-family: monospace; + margin: 2px 0 0 2px; + white-space: pre-wrap; + word-break: break-all; + cursor: text; `) + body.setAttribute("onblur", ` + getSelection().removeAllRanges() + `) + }else{ + this.textarea = document.createElement("textarea") + this.textarea.readOnly = true + this.textarea.value = diag + this.diagTxt.appendChild(this.textarea) + if(!this.touchEnabled){ + pageEvents.add(this.textarea, "focus", () => { + this.textarea.select() + }) + pageEvents.add(this.textarea, "blur", () => { + getSelection().removeAllRanges() + }) + } } + + var issueBody = this.issueTemplate + "\n\n\n\n" + diag + this.getLink(this.linkGithub).href += "?body=" + encodeURIComponent(issueBody) + this.getLink(this.linkEmail).href += "?body=" + encodeURIComponent(issueBody.replace(/\n/g, "\r\n")) + } + getLink(target){ + return target.getElementsByTagName("a")[0] } linkButton(event){ - event.currentTarget.getElementsByTagName("a")[0].click() + this.getLink(event.currentTarget).click() } clean(){ cancelTouch = true @@ -111,6 +131,9 @@ class About{ pageEvents.remove(this.linkGithub, ["click", "touchend"]) pageEvents.remove(this.linkEmail, ["click", "touchend"]) pageEvents.remove(this.endButton, ["mousedown", "touchstart"]) + if(this.textarea){ + pageEvents.remove(this.textarea, ["focus", "blur"]) + } pageEvents.keyRemove(this, 13) delete this.endButton delete this.diagTxt @@ -118,5 +141,6 @@ class About{ delete this.tutorialOuter delete this.linkGithub delete this.linkEmail + delete this.textarea } } diff --git a/public/src/js/canvastest.js b/public/src/js/canvastest.js index b952981..dea0bf6 100644 --- a/public/src/js/canvastest.js +++ b/public/src/js/canvastest.js @@ -91,6 +91,7 @@ class CanvasTest{ drawAllImages(){ return new Promise(resolve => { requestAnimationFrame(() => { + var startTime = +new Date var ctx = this.ctx ctx.save() ctx.clearRect(0, 0, this.canvas.width, this.canvas.height) @@ -131,7 +132,7 @@ class CanvasTest{ } ctx.restore() - resolve() + resolve((+new Date) - startTime) }) }) } diff --git a/public/src/js/loader.js b/public/src/js/loader.js index 9d1f188..59954b6 100644 --- a/public/src/js/loader.js +++ b/public/src/js/loader.js @@ -5,6 +5,8 @@ class Loader{ this.assetsDiv = document.getElementById("assets") this.canvasTest = new CanvasTest() p2 = new P2Connection() + this.startTime = +new Date + this.ajax("src/views/loader.html").then(this.run.bind(this)) } run(page){ @@ -85,6 +87,7 @@ class Loader{ }) this.promises.push(this.canvasTest.blurPerformance().then(result => { + perf.blur = result if(result > 1000 / 50){ // Less than 50 fps with blur enabled disableBlur = true @@ -96,7 +99,9 @@ class Loader{ }) Promise.all(this.promises).then(() => { - this.canvasTest.drawAllImages().then(() => { + this.canvasTest.drawAllImages().then(result => { + perf.allImg = result + perf.load = (+new Date) - this.startTime this.canvasTest.clean() this.clean() this.callback() diff --git a/public/src/js/main.js b/public/src/js/main.js index a22b310..9e29573 100644 --- a/public/src/js/main.js +++ b/public/src/js/main.js @@ -49,6 +49,11 @@ var p2 var disableBlur = false var cancelTouch = true var lastHeight +var perf = { + blur: 0, + allImg: 0, + load: 0 +} pageEvents.add(root, ["touchstart", "touchmove", "touchend"], event => { if(event.cancelable && cancelTouch){ diff --git a/public/src/views/about.html b/public/src/views/about.html index f2581b2..5777ea2 100644 --- a/public/src/views/about.html +++ b/public/src/views/about.html @@ -13,7 +13,7 @@ Be sure to include the following diagnostic data! - +