Merge pull request #8 from LoveEevee/scalablecanvas

Support high DPI screens
This commit is contained in:
Bui 2018-09-09 15:11:37 +01:00 committed by GitHub
commit 66b0924252
7 changed files with 203 additions and 68 deletions

View File

@ -48,6 +48,8 @@
<script type='application/javascript' src='/src/js/mekadon.js'></script> <script type='application/javascript' src='/src/js/mekadon.js'></script>
<script type='application/javascript' src='/src/js/gamepad.js'></script> <script type='application/javascript' src='/src/js/gamepad.js'></script>
<script type='application/javascript' src='/src/js/tutorial.js'></script> <script type='application/javascript' src='/src/js/tutorial.js'></script>
<script type='application/javascript' src='/src/js/scalablecanvas.js'></script>
<script type='application/javascript' src='/src/js/element.js'></script>
</head> </head>
<body> <body>

View File

@ -28,14 +28,14 @@
width: 90%; width: 90%;
height: 25%; height: 25%;
display: block; display: block;
margin: auto auto 30px; margin: 0 auto;
cursor: pointer; cursor: pointer;
border:5px solid #ae7a26; border:.5vmin solid #ae7a26;
background: rgb(255, 255, 255); background: rgb(255, 255, 255);
color: black; color: black;
font-family: TnT; font-family: TnT;
font-size: 5vmin; font-size: 3.5vmin;
border-radius: 10px; border-radius: 1.5vmin;
} }
#pause-menu button:hover{ #pause-menu button:hover{

View File

@ -31,17 +31,22 @@ html, body{
} }
.window{ .window{
font-size: 14pt; width: 60vmin;
width: 30%; height: 23vmin;
height: 30%; padding: 3vmin;
padding: 30px;
color: black; color: black;
background: rgba(255, 220, 47, 0.95); background: rgba(255, 220, 47, 0.95);
border: 7px outset #f4ae00; border: .5vmin outset #f4ae00;
position:relative;
box-shadow: 2px 2px 10px black; box-shadow: 2px 2px 10px black;
top: 35%; margin: auto;
left: 35%; position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
} }
@ -59,7 +64,7 @@ html, body{
position: absolute; position: absolute;
right: 0; right: 0;
font-size: 5vmin; font-size: 5vmin;
margin: 30px 30px 0px 0px; margin: 3vmin 3vmin 0px 0px;
color: white; color: white;
float: right; float: right;
z-index: 1; z-index: 1;

49
public/src/js/element.js Normal file
View File

@ -0,0 +1,49 @@
function element(){
var parent
var lasttag
var createdtag
var toreturn={}
for(var i=0;i<arguments.length;i++){
var current=arguments[i]
if(current){
if(current.nodeType){
parent=lasttag=current
}else if(Array.isArray(current)){
lasttag=parent
for(var j=0;j<current.length;j++){
if(current[j]){
if(j==0&&typeof current[j]=="string"){
var tagname=current[0].split("#")
lasttag=createdtag=document.createElement(tagname[0])
if(tagname[1]){
toreturn[tagname[1]]=createdtag
}
}else if(current[j].constructor==Object){
if(lasttag){
for(var value in current[j]){
if(value!="style"&&value in lasttag){
lasttag[value]=current[j][value]
}else{
lasttag.setAttribute(value,current[j][value])
}
}
}
}else{
var returned=element(lasttag,current[j])
for(var k in returned){
toreturn[k]=returned[k]
}
}
}
}
}else if(current){
createdtag=document.createTextNode(current)
}
if(parent&&createdtag){
parent.appendChild(createdtag)
}
createdtag=0
}
}
return toreturn
}

View File

@ -0,0 +1,42 @@
class ScalableCanvas{
constructor(id, width, height, noStyle){
var oldCanvas = document.getElementById(id)
if(oldCanvas){
this.canvas = oldCanvas
}else{
this.canvas = document.createElement("canvas")
this.canvas.id = id
}
this.ctx = this.canvas.getContext("2d")
this.rescale()
this.resize(width, height, noStyle)
}
resize(width, height, noStyle){
if(width != this.width || height != this.height){
this.width = width
this.height = height
this.scaledWidth = width * this.scale
this.canvas.width = this.scaledWidth
this.scaledHeight = height * this.scale
this.canvas.height = this.scaledHeight
if(noStyle || this.scale == 1){
if(this.canvas.style.width){
this.canvas.style.width = ""
}
if(this.canvas.style.height){
this.canvas.style.height = ""
}
}else{
this.canvas.style.width = width + "px"
this.canvas.style.height = height + "px"
}
}
}
rescale(){
var scale = window.devicePixelRatio || 1
if(scale != this.scale){
this.ctx.scale(scale, scale)
this.scale = scale
}
}
}

View File

@ -3,7 +3,6 @@ function SongSelect(){
var _this=this; var _this=this;
var _songs; var _songs;
var _selectedSong = {title:'', folder:'', difficulty:''}; var _selectedSong = {title:'', folder:'', difficulty:''};
var _code="";
var _preview; var _preview;
var _preview_to; var _preview_to;
var _diffNames={ var _diffNames={
@ -154,66 +153,94 @@ function SongSelect(){
setTimeout(function(){ setTimeout(function(){
assets.sounds["song-select"].playAsset(); assets.sounds["song-select"].playAsset();
}, 200); }, 200);
var songElements = [0]
for(var i=0; i<assets.songs.length; i++){ for(var i=0; i<assets.songs.length; i++){
var song = assets.songs[i]; var song = assets.songs[i];
var songDir = '/songs/' + song.id;
var songDifficulties = song.stars;
var songID = song.id;
var songTitle = song.title; var songTitle = song.title;
var songTitleSpace = songTitle.replace(/ /g, '&nbsp;');
var songPreview = song.preview;
var skipChars = []; var skipChars = [];
var charElements = [0]
var diffElements = [0]
var cl = /^[\x00-\xFF]*$/.test(songTitle) ? 'song-title alpha-title' : 'song-title';
_code += "<div id='song-"+songID+"' class='song' data-title='"+songTitle+"' data-song-id='"+songID+"' data-preview='"+songPreview+"'><div class='"+cl+"'>";
for (var c=0; c<songTitle.length; c++) { for (var c=0; c<songTitle.length; c++) {
if (skipChars.indexOf(c) > -1) { if (skipChars.indexOf(c) > -1) {
continue; continue;
}; };
var ch = songTitle.charAt(c) == ' ' ? '&nbsp;' : songTitle.charAt(c); var ch = songTitle.charAt(c) == " " ? "\xa0" : songTitle.charAt(c);
var isApos = false; var isApos = false;
if (songTitle.charAt(c+1) == '\'') { if (songTitle.charAt(c+1) == "'") {
ch = ch + '\''; ch = ch + "'";
skipChars.push(c+1); skipChars.push(c+1);
isApos = true; isApos = true;
}; };
var cl = ch == '&nbsp;' ? 'song-title-char song-title-space' : 'song-title-char'; var cl = ch == "\xa0" ? "song-title-char song-title-space" : "song-title-char";
cl = isApos ? cl + ' song-title-apos' : cl; cl = isApos ? cl + " song-title-apos" : cl;
_code += '<span class="' + cl + '" alt="' + ch + '">' + ch + '</span>'; charElements.push(
["span", {
class: cl,
alt: ch
}, ch]
)
}; };
_code += "</div><ul class='difficulties'>";
for(var diff in _diffNames){ for(var diff in _diffNames){
var diffName = diff; var diffName = diff;
var diffLevel = songDifficulties[diff]; var diffLevel = song.stars[diff];
if (!diffLevel) { if (!diffLevel) {
continue; continue;
} }
var starsDisplay=""; var starsDisplay = [0]
for(var x=1; x<=diffLevel; x++){ for(var x=1; x<=diffLevel; x++){
starsDisplay+="&#9733;<br>"; starsDisplay.push("\u2605")
starsDisplay.push(["br"])
} }
var diffTxt=_diffNames[diffName] var diffTxt=_diffNames[diffName]
_code += "<li class='difficulty "+diffName+"'>"; diffElements.push(
_code+= "<span class='diffname'>"+diffTxt+"</span>"; ["li", {
_code+= "<span class='stars'>"+starsDisplay+"</span>"; class: "difficulty " + diffName
_code += "</li>"; },
["span", {
class: "diffname"
}, diffTxt],
["span", {
class: "stars"
}, starsDisplay]
]
)
} }
_code += "</ul></div>"; songElements.push(
["div", {
id: "song-" + song.id,
class: "song",
"data-title": songTitle,
"data-song-id": song.id,
"data-preview": song.preview
},
["div", {
class: /^[\x00-\xFF]*$/.test(songTitle) ? "song-title alpha-title" : "song-title"
}, charElements],
["ul", {
class: "difficulties"
}, diffElements]
]
)
} }
$("#song-container").html(_code); element(
document.getElementById("song-container"),
songElements
)
$('.difficulty').hide(); $('.difficulty').hide();
} }

View File

@ -3,12 +3,13 @@ class View{
this.controller = controller this.controller = controller
this.bg = bg this.bg = bg
this.diff = diff this.diff = diff
this.canvas = document.getElementById("canvas")
this.ctx = this.canvas.getContext("2d")
this.winW = $(window).width() this.winW = $(window).width()
this.winH = $(window).height() this.winH = $(window).height()
this.canvas = new ScalableCanvas("canvas", this.winW, this.winH)
this.ctx = this.canvas.ctx
this.taikoSquareW = this.winW / 4 this.taikoSquareW = this.winW / 4
this.slotX = this.taikoSquareW + 100 this.slotX = this.taikoSquareW + 100
@ -27,7 +28,7 @@ class View{
this.currentBigDonFace = 1 this.currentBigDonFace = 1
this.nextBeat = 0 this.nextBeat = 0
this.songTitle = this.title this.songTitle = title
this.songDifficulty = this.diff.split(".").slice(0, -1).join(".") this.songDifficulty = this.diff.split(".").slice(0, -1).join(".")
} }
@ -49,10 +50,11 @@ class View{
} }
positionning(){ positionning(){
this.winW = $(window).width() this.canvas.rescale()
this.winH = $(window).height() this.canvas.resize($(window).width(), $(window).height())
this.canvas.width = this.winW this.winW = this.canvas.scaledWidth
this.canvas.height = this.winH this.winH = this.canvas.scaledHeight
this.barY = 0.25 * this.winH this.barY = 0.25 * this.winH
this.barH = 0.23 * this.winH this.barH = 0.23 * this.winH
this.lyricsBarH = 0.2 * this.barH this.lyricsBarH = 0.2 * this.barH
@ -61,7 +63,7 @@ class View{
this.taikoX = this.taikoSquareW * 0.76 - this.taikoW / 2 this.taikoX = this.taikoSquareW * 0.76 - this.taikoW / 2
this.taikoY = this.barY + 5 this.taikoY = this.barY + 5
this.taikoSquareW = this.winW / 4 this.taikoSquareW = this.winW / 4
this.slotX = this.taikoSquareW + 100 this.slotX = this.taikoSquareW + this.barH * 0.45
this.scoreSquareW = this.taikoSquareW * 0.55 this.scoreSquareW = this.taikoSquareW * 0.55
this.scoreSquareH = this.barH * 0.25 this.scoreSquareH = this.barH * 0.25
this.circleSize = this.barH * 0.15 this.circleSize = this.barH * 0.15
@ -84,7 +86,7 @@ class View{
this.HPBarColH = this.HPBarH * 0.8 this.HPBarColH = this.HPBarH * 0.8
var diffRatio = 176 / 120 var diffRatio = 176 / 120
this.diffH = this.winH * 0.16 this.diffH = this.winH * 0.16
this.diffW = this.diffH*diffRatio this.diffW = this.diffH * diffRatio
this.diffX = this.taikoX * 0.10 this.diffX = this.taikoX * 0.10
this.diffY = this.taikoY * 1.05 + this.taikoH * 0.19 this.diffY = this.taikoY * 1.05 + this.taikoH * 0.19
} }
@ -93,6 +95,8 @@ class View{
this.positionning() this.positionning()
this.distanceForCircle = this.winW - this.slotX this.distanceForCircle = this.winW - this.slotX
this.ctx.clearRect(0, 0, this.canvas.scaledWidth, this.canvas.scaledHeight)
// Draw // Draw
this.drawBar() this.drawBar()
this.drawSlot() this.drawSlot()
@ -124,6 +128,8 @@ class View{
} }
drawHPBar(){ drawHPBar(){
var z = this.canvas.scale
var bottomSquareX = this.taikoSquareW var bottomSquareX = this.taikoSquareW
var borderSize = this.HPBarH * 0.2 var borderSize = this.HPBarH * 0.2
this.ctx.fillStyle = "#000" this.ctx.fillStyle = "#000"
@ -139,13 +145,13 @@ class View{
bottomSquareX + borderSize, bottomSquareX + borderSize,
this.HPBarY + 0.435 * this.HPBarH, this.HPBarY + 0.435 * this.HPBarH,
this.winW - bottomSquareX - borderSize, this.winW - bottomSquareX - borderSize,
this.HPBarH / 2 + 1 this.HPBarH / 2 + 2 * z
) )
this.ctx.fillRect( this.ctx.fillRect(
bottomSquareX, bottomSquareX,
this.HPBarY + 0.68 * this.HPBarH, this.HPBarY + 0.68 * this.HPBarH,
this.HPBarW * 0.8, this.HPBarW * 0.8,
this.HPBarH / 4 + 1 this.HPBarH / 4 + 2 * z
) )
this.ctx.arc( this.ctx.arc(
bottomSquareX+borderSize, bottomSquareX+borderSize,
@ -200,13 +206,14 @@ class View{
} }
drawMeasure(measure){ drawMeasure(measure){
var z = this.canvas.scale
var currentTime = this.controller.getEllapsedTime().ms var currentTime = this.controller.getEllapsedTime().ms
var measureX = this.slotX + measure.speed / (70 / this.circleSize) * (measure.ms - currentTime) var measureX = this.slotX + measure.speed / (70 / this.circleSize) * (measure.ms - currentTime)
this.ctx.strokeStyle = "#bab8b8" this.ctx.strokeStyle = "#bab8b8"
this.ctx.lineWidth = 2 this.ctx.lineWidth = 2
this.ctx.beginPath() this.ctx.beginPath()
this.ctx.moveTo(measureX, this.barY + 5) this.ctx.moveTo(measureX, this.barY + 5 * z)
this.ctx.lineTo(measureX, this.barY + this.barH - this.lyricsBarH - 5) this.ctx.lineTo(measureX, this.barY + this.barH - this.lyricsBarH - 5 * z)
this.ctx.closePath() this.ctx.closePath()
this.ctx.stroke() this.ctx.stroke()
} }
@ -294,7 +301,7 @@ class View{
var pointsText = this.controller.getGlobalScore().points.toString().split("") var pointsText = this.controller.getGlobalScore().points.toString().split("")
for(var i in pointsText){ for(var i in pointsText){
this.ctx.fillText(pointsText[i], this.ctx.fillText(pointsText[i],
this.scoreSquareW - 20 + glyph * (i - pointsText.length + 1), this.scoreSquareW - 30 + glyph * (i - pointsText.length + 1),
this.barY + this.scoreSquareH * 0.7 this.barY + this.scoreSquareH * 0.7
) )
} }
@ -449,6 +456,8 @@ class View{
} }
drawCircle(circle, circlePos){ drawCircle(circle, circlePos){
var z = this.canvas.scale
var fill, size, faceID var fill, size, faceID
if(!circlePos){ if(!circlePos){
var currentTime = this.controller.getEllapsedTime().ms var currentTime = this.controller.getEllapsedTime().ms
@ -540,11 +549,12 @@ class View{
} }
drawTime(){ drawTime(){
var z = this.canvas.scale
var time = this.controller.getEllapsedTime() var time = this.controller.getEllapsedTime()
this.ctx.globalAlpha = 0.7 this.ctx.globalAlpha = 0.7
this.ctx.fillStyle = "#000" this.ctx.fillStyle = "#000"
this.ctx.fillRect(this.winW - 110, this.winH - 60, this.winW, this.winH) this.ctx.fillRect(this.winW - 110 * z, this.winH - 60 * z, this.winW, this.winH)
this.ctx.globalAlpha = 1 this.ctx.globalAlpha = 1
this.ctx.fillStyle = "#fff" this.ctx.fillStyle = "#fff"
@ -556,9 +566,9 @@ class View{
this.ctx.font = "normal " + (this.barH / 12) + "px Kozuka" this.ctx.font = "normal " + (this.barH / 12) + "px Kozuka"
this.ctx.textAlign = "right" this.ctx.textAlign = "right"
this.ctx.fillText(formatedH + ":" + formatedM + ":" + formatedS, this.ctx.fillText(formatedH + ":" + formatedM + ":" + formatedS,
this.winW - 10, this.winH - 30 this.winW - 10 * z, this.winH - 30 * z
) )
this.ctx.fillText(time.ms, this.winW - 10, this.winH - 10) this.ctx.fillText(time.ms, this.winW - 10 * z, this.winH - 10 * z)
} }
drawBar(){ drawBar(){