Merge branch 'CHN' of https://github.com/asesidaa/TaikoLocalServer into CHN
@ -3,9 +3,11 @@
|
||||
@inject IGameDataService GameDataService
|
||||
@inject IDialogService DialogService
|
||||
@inject LoginService LoginService
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<MudBreadcrumbs Items="breadcrumbs" Class="px-0"></MudBreadcrumbs>
|
||||
|
||||
|
||||
<h1>Profile</h1>
|
||||
@if (LoginService.LoginRequired)
|
||||
{
|
||||
@ -35,10 +37,9 @@ else
|
||||
<MudTabPanel Text="Profile">
|
||||
<MudStack Spacing="4">
|
||||
<h2>Profile Options</h2>
|
||||
|
||||
<MudGrid>
|
||||
<MudItem xs="12" md="8">
|
||||
<MudTextField @bind-Value="@response.MyDonName" Label="Name"></MudTextField>
|
||||
<MudTextField TextChanged="UpdateMyDonName" @bind-Value="@response.MyDonName" Label="Name"></MudTextField>
|
||||
</MudItem>
|
||||
<MudItem xs="12" md="4">
|
||||
<MudSelect @bind-Value="@response.MyDonNameLanguage" Label="Language">
|
||||
@ -53,7 +54,7 @@ else
|
||||
|
||||
<MudGrid>
|
||||
<MudItem xs="12" md="8">
|
||||
<MudTextField @bind-Value="@response.Title" Label="Title" />
|
||||
<MudTextField TextChanged="UpdateTitle" @bind-Value="@response.Title" Label="Title" />
|
||||
<MudButton Color="Color.Primary" Class="mt-1" Size="Size.Small" OnClick="@((_)=>OpenChooseTitleDialog())">
|
||||
Select a Title
|
||||
</MudButton>
|
||||
@ -254,39 +255,59 @@ else
|
||||
</MudPaper>
|
||||
</MudItem>
|
||||
|
||||
<MudItem md="4" xs="12" Class="py-4 px-8">
|
||||
<MudItem md="4" xs="12" Class="py-3 px-3">
|
||||
<MudStack Spacing="4" Class="sticky" Style="top:100px">
|
||||
<MudCard style="height: 400px;">
|
||||
<MudCard style="height: auto" Outlined="true">
|
||||
<MudCardContent>
|
||||
<div style="position:relative">
|
||||
@* Player Visualizer *@
|
||||
<MudItem style="text-align: center;">
|
||||
<MudItem style="position:relative">
|
||||
@if (response.Kigurumi == 0)
|
||||
{
|
||||
<MudImage Fluid="true" style=@($"position:absolute; filter: {CostumeColorFilters[response.BodyColor]}") Src=@ImageOrDefault("masks/body-bodymask", response.Body, "masks/body-bodymask-0000") />
|
||||
<MudImage Fluid="true" style=@($"position:absolute; filter: {CostumeColorFilters[response.FaceColor]}") Src=@ImageOrDefault("masks/body-facemask", response.Body, "masks/body-facemask-0000") />
|
||||
<MudImage Fluid="true" style="position:absolute;" onerror="this.src='images/Costumes/body/body-0000.png'" Src=@($"images/Costumes/body/body-{response.Body.ToString().PadLeft(4, '0')}.png") />
|
||||
|
||||
<MudImage Fluid="true" style="position:absolute;" onerror="this.src='images/Costumes/face/face-0000.png'" Src=@($"images/Costumes/face/face-{response.Face.ToString().PadLeft(4, '0')}.png") />
|
||||
|
||||
<MudImage Fluid="true" style=@($"position:absolute; filter: {CostumeColorFilters[response.BodyColor]}") Src=@ImageOrDefault("masks/head-bodymask", response.Head, "head/head-0000") />
|
||||
<MudImage Fluid="true" style=@($"position:absolute; filter: {CostumeColorFilters[response.FaceColor]}") Src=@ImageOrDefault("masks/head-facemask", response.Head, "head/head-0000") />
|
||||
<MudImage Fluid="true" style="position:absolute;" onerror="this.src='images/Costumes/head/head-0000.png'" Src=@($"images/Costumes/head/head-{response.Head.ToString().PadLeft(4, '0')}.png") />
|
||||
<MudImage Fluid="true" style=@($"position: relative; top: 0; left: 0; filter: {CostumeColorFilters[response.BodyColor]}") Src=@ImageOrDefault("masks/body-bodymask", response.Body, "masks/body-bodymask-0000") />
|
||||
<MudImage Fluid="true" style=@($"position:absolute; top: 0; left: 0; right: 0; margin: 0 auto; filter: {CostumeColorFilters[response.FaceColor]}") Src=@ImageOrDefault("masks/body-facemask", response.Body, "masks/body-facemask-0000") />
|
||||
<MudImage Fluid="true" style="position:absolute; top: 0; left: 0; right: 0; margin: 0 auto;" onerror="this.src='images/Costumes/body/body-0000.png'" Src=@($"images/Costumes/body/body-{response.Body.ToString().PadLeft(4, '0')}.png") />
|
||||
<MudImage Fluid="true" style="position:absolute; top: 0; left: 0; right: 0; margin: 0 auto;" onerror="this.src='images/Costumes/face/face-0000.png'" Src=@($"images/Costumes/face/face-{response.Face.ToString().PadLeft(4, '0')}.png") />
|
||||
<MudImage Fluid="true" style=@($"position:absolute; top: 0; left: 0; right: 0; margin: 0 auto; filter: {CostumeColorFilters[response.BodyColor]}") Src=@ImageOrDefault("masks/head-bodymask", response.Head, "head/head-0000") />
|
||||
<MudImage Fluid="true" style=@($"position:absolute; top: 0; left: 0; right: 0; margin: 0 auto; filter: {CostumeColorFilters[response.FaceColor]}") Src=@ImageOrDefault("masks/head-facemask", response.Head, "head/head-0000") />
|
||||
<MudImage Fluid="true" style="position:absolute; top: 0; left: 0; right: 0; margin: 0 auto;" onerror="this.src='images/Costumes/head/head-0000.png'" Src=@($"images/Costumes/head/head-{response.Head.ToString().PadLeft(4, '0')}.png") />
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudImage Fluid="true" style=@($"position:absolute; filter: {CostumeColorFilters[response.BodyColor]}") Src=@ImageOrDefault("masks/kigurumi-bodymask", response.Kigurumi, "masks/body-bodymask-0000") />
|
||||
<MudImage Fluid="true" style=@($"position:absolute; filter: {CostumeColorFilters[response.FaceColor]}") Src=@ImageOrDefault("masks/kigurumi-facemask", response.Kigurumi, "masks/body-facemask-0000") />
|
||||
<MudImage Fluid="true" style="position:absolute;" onerror="this.src='images/Costumes/kigurumi/kigurumi-0000.png'" Src=@($"images/Costumes/kigurumi/kigurumi-{response.Kigurumi.ToString().PadLeft(4, '0')}.png") />
|
||||
<MudImage Fluid="true" style=@($"position: relative; top: 0; left: 0; filter: {CostumeColorFilters[response.BodyColor]}") Src=@ImageOrDefault("masks/kigurumi-bodymask", response.Kigurumi, "masks/body-bodymask-0000") />
|
||||
<MudImage Fluid="true" style=@($"position:absolute; top: 0; left: 0; right: 0; margin: 0 auto; filter: {CostumeColorFilters[response.FaceColor]}") Src=@ImageOrDefault("masks/kigurumi-facemask", response.Kigurumi, "masks/body-facemask-0000") />
|
||||
<MudImage Fluid="true" style="position:absolute; top: 0; left: 0; right: 0; margin: 0 auto;" onerror="this.src='images/Costumes/kigurumi/kigurumi-0000.png'" Src=@($"images/Costumes/kigurumi/kigurumi-{response.Kigurumi.ToString().PadLeft(4, '0')}.png") />
|
||||
}
|
||||
<MudImage Fluid="true" style="position:absolute;" onerror="this.src='images/Costumes/puchi/puchi-0000.png'" Src=@($"images/Costumes/puchi/puchi-{response.Puchi.ToString().PadLeft(4, '0')}.png") />
|
||||
<MudImage Fluid="true" style="position:absolute; top: 0; left: 0; right: 0; margin: 0 auto;" onerror="this.src='images/Costumes/puchi/puchi-0000.png'" Src=@($"images/Costumes/puchi/puchi-{response.Puchi.ToString().PadLeft(4, '0')}.png") />
|
||||
</MudItem>
|
||||
</MudItem>
|
||||
|
||||
</div>
|
||||
|
||||
@* Player Nameplate *@
|
||||
<MudItem style="text-align: center; position:relative;">
|
||||
@* Title text *@
|
||||
<MudItem style="position:absolute; top: 7%; left:0; right:1.1%; height:38%; width:min(96%, 320px); margin: 0 auto; z-index:2; vertical-align: middle;">
|
||||
<MudItem Style="position:absolute; height:100%; width:80%; right: 10%;">
|
||||
<MudText Id="nameplate-title" Style="position:absolute; height:100%; top: 0; left: 0; right: 0; margin: auto auto; font-family: 'Nijiiro', sans-serif; color:black">@response.Title</MudText>
|
||||
</MudItem>
|
||||
</MudItem>
|
||||
@* Name text *@
|
||||
<MudItem Style="position:absolute; top: 47%; left:0; right:1.1%; height:41%; width:min(96%, 320px); margin: 0 auto; z-index:2">
|
||||
@* Name textoffset to the right for Dan Rank *@
|
||||
<MudItem Style=@($"position:absolute; height:100%; right: 10%; {(response.IsDisplayDanOnNamePlate ? "width:46%;" : "width:80%;")}")>
|
||||
<MudText Id="nameplate-name-outline" Style="position:absolute; height:100%; top: 0; left: 0; right: 0; margin: auto auto; font-family: 'Nijiiro', sans-serif; -webkit-text-stroke: 5px; -webkit-text-stroke-color: black">@response.MyDonName</MudText>
|
||||
<MudText Id="nameplate-name" Style="position:absolute; height:100%; top: 0; left: 0; right: 0; margin: auto auto; font-family: 'Nijiiro', sans-serif; color:white">@response.MyDonName</MudText>
|
||||
</MudItem>
|
||||
</MudItem>
|
||||
<MudImage onload="nameplateLoaded()" Id="nameplate" Fluid="true" Style="position: relative; top: 0; left: 0;" Src="images/Nameplates/nameplate.png" />
|
||||
<MudImage Fluid="true" Style="position:absolute; top: 0; left: 0; right: 0; margin: 0 auto;" Src=@($"images/Nameplates/nameplate_{TitlePlateStrings[response.TitlePlateId].Replace(' ', '_')}.png") />
|
||||
@if (response.IsDisplayDanOnNamePlate)
|
||||
{
|
||||
<MudImage Fluid="true" Style="position:absolute; top: 0; left: 0; right: 0; margin: 0 auto;" Src="images/Nameplates/nameplate_dan.png" />
|
||||
}
|
||||
</MudItem>
|
||||
</MudCardContent>
|
||||
@* <MudCardActions>
|
||||
<MudButton Variant="Variant.Text" Color="Color.Primary">Share</MudButton>
|
||||
<MudButton Variant="Variant.Text" Color="Color.Primary">Learn More</MudButton>
|
||||
</MudCardActions> *@
|
||||
</MudCard>
|
||||
|
||||
<MudButton Disabled="@isSavingOptions"
|
||||
OnClick="SaveOptions"
|
||||
Variant="Variant.Filled"
|
||||
@ -303,7 +324,20 @@ else
|
||||
}
|
||||
</MudButton>
|
||||
</MudStack>
|
||||
|
||||
</MudItem>
|
||||
</MudGrid>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
private async Task UpdateMyDonName()
|
||||
{
|
||||
@if (response is not null) await JS.InvokeVoidAsync("updateMyDonName", response.MyDonName);
|
||||
}
|
||||
|
||||
private async Task UpdateTitle()
|
||||
{
|
||||
@if (response is not null) await JS.InvokeVoidAsync("updateTitle", response.Title);
|
||||
}
|
||||
}
|
@ -35,20 +35,15 @@ public partial class Profile
|
||||
"masks/body-bodymask-0070", "masks/body-bodymask-0092", "masks/body-bodymask-0121",
|
||||
"masks/body-bodymask-0123", "masks/body-bodymask-0127", "masks/body-bodymask-0136",
|
||||
"masks/body-bodymask-0153",
|
||||
|
||||
"masks/body-facemask-0005", "masks/body-facemask-0015", "masks/body-facemask-0030",
|
||||
"masks/body-facemask-0064", "masks/body-facemask-0065", "masks/body-facemask-0069",
|
||||
"masks/body-facemask-0090", "masks/body-facemask-0092", "masks/body-facemask-0136",
|
||||
"masks/body-facemask-0151", "masks/body-facemask-0152", "masks/body-facemask-0153",
|
||||
|
||||
"masks/head-bodymask-0113", "masks/head-bodymask-0138",
|
||||
|
||||
"masks/head-facemask-0003", "masks/head-facemask-0113", "masks/head-facemask-0137",
|
||||
"masks/head-facemask-0138",
|
||||
|
||||
"masks/kigurumi-bodymask-0052", "masks/kigurumi-bodymask-0109", "masks/kigurumi-bodymask-0110",
|
||||
"masks/kigurumi-bodymask-0115", "masks/kigurumi-bodymask-0123",
|
||||
|
||||
"masks/kigurumi-facemask-0052", "masks/kigurumi-facemask-0109", "masks/kigurumi-facemask-0110",
|
||||
"masks/kigurumi-facemask-0115", "masks/kigurumi-facemask-0123",
|
||||
};
|
||||
|
BIN
TaikoWebUI/wwwroot/css/Nijiiro.woff2
Normal file
@ -1,5 +1,10 @@
|
||||
@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
|
||||
|
||||
@font-face {
|
||||
font-family: 'Nijiiro';
|
||||
src: url('Nijiiro.woff2') format('woff2')
|
||||
}
|
||||
|
||||
html, body {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate_AI_1.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate_AI_2.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate_AI_3.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate_AI_4.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate_dan.png
Normal file
After Width: | Height: | Size: 750 B |
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate_gold.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate_purple.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate_rainbow.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
TaikoWebUI/wwwroot/images/Nameplates/nameplate_wood.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
@ -29,6 +29,8 @@
|
||||
</div>
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
|
||||
<script src="js/textFit.min.js"></script>
|
||||
<script src="js/updateTextFit.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
1
TaikoWebUI/wwwroot/js/textFit.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(root,factory){"use strict";if(typeof define==="function"&&define.amd){define([],factory)}else if(typeof exports==="object"){module.exports=factory()}else{root.textFit=factory()}})(typeof global==="object"?global:this,function(){"use strict";var defaultSettings={alignVert:false,alignHoriz:false,multiLine:false,detectMultiLine:true,minFontSize:6,maxFontSize:80,reProcess:true,widthOnly:false,alignVertWithFlexbox:false};return function textFit(els,options){if(!options)options={};var settings={};for(var key in defaultSettings){if(options.hasOwnProperty(key)){settings[key]=options[key]}else{settings[key]=defaultSettings[key]}}if(typeof els.toArray==="function"){els=els.toArray()}var elType=Object.prototype.toString.call(els);if(elType!=="[object Array]"&&elType!=="[object NodeList]"&&elType!=="[object HTMLCollection]"){els=[els]}for(var i=0;i<els.length;i++){processItem(els[i],settings)}};function processItem(el,settings){if(!isElement(el)||!settings.reProcess&&el.getAttribute("textFitted")){return false}if(!settings.reProcess){el.setAttribute("textFitted",1)}var innerSpan,originalHeight,originalHTML,originalWidth;var low,mid,high;originalHTML=el.innerHTML;originalWidth=innerWidth(el);originalHeight=innerHeight(el);if(!originalWidth||!settings.widthOnly&&!originalHeight){if(!settings.widthOnly)throw new Error("Set a static height and width on the target element "+el.outerHTML+" before using textFit!");else throw new Error("Set a static width on the target element "+el.outerHTML+" before using textFit!")}if(originalHTML.indexOf("textFitted")===-1){innerSpan=document.createElement("span");innerSpan.className="textFitted";innerSpan.style["display"]="inline-block";innerSpan.innerHTML=originalHTML;el.innerHTML="";el.appendChild(innerSpan)}else{innerSpan=el.querySelector("span.textFitted");if(hasClass(innerSpan,"textFitAlignVert")){innerSpan.className=innerSpan.className.replace("textFitAlignVert","");innerSpan.style["height"]="";el.className.replace("textFitAlignVertFlex","")}}if(settings.alignHoriz){el.style["text-align"]="center";innerSpan.style["text-align"]="center"}var multiLine=settings.multiLine;if(settings.detectMultiLine&&!multiLine&&innerSpan.scrollHeight>=parseInt(window.getComputedStyle(innerSpan)["font-size"],10)*2){multiLine=true}if(!multiLine){el.style["white-space"]="nowrap"}low=settings.minFontSize;high=settings.maxFontSize;var size=low;while(low<=high){mid=high+low>>1;innerSpan.style.fontSize=mid+"px";if(innerSpan.scrollWidth<=originalWidth&&(settings.widthOnly||innerSpan.scrollHeight<=originalHeight)){size=mid;low=mid+1}else{high=mid-1}}if(innerSpan.style.fontSize!=size+"px")innerSpan.style.fontSize=size+"px";if(settings.alignVert){addStyleSheet();var height=innerSpan.scrollHeight;if(window.getComputedStyle(el)["position"]==="static"){el.style["position"]="relative"}if(!hasClass(innerSpan,"textFitAlignVert")){innerSpan.className=innerSpan.className+" textFitAlignVert"}innerSpan.style["height"]=height+"px";if(settings.alignVertWithFlexbox&&!hasClass(el,"textFitAlignVertFlex")){el.className=el.className+" textFitAlignVertFlex"}}}function innerHeight(el){var style=window.getComputedStyle(el,null);return el.clientHeight-parseInt(style.getPropertyValue("padding-top"),10)-parseInt(style.getPropertyValue("padding-bottom"),10)}function innerWidth(el){var style=window.getComputedStyle(el,null);return el.clientWidth-parseInt(style.getPropertyValue("padding-left"),10)-parseInt(style.getPropertyValue("padding-right"),10)}function isElement(o){return typeof HTMLElement==="object"?o instanceof HTMLElement:o&&typeof o==="object"&&o!==null&&o.nodeType===1&&typeof o.nodeName==="string"}function hasClass(element,cls){return(" "+element.className+" ").indexOf(" "+cls+" ")>-1}function addStyleSheet(){if(document.getElementById("textFitStyleSheet"))return;var style=[".textFitAlignVert{","position: absolute;","top: 0; right: 0; bottom: 0; left: 0;","margin: auto;","display: flex;","justify-content: center;","flex-direction: column;","}",".textFitAlignVertFlex{","display: flex;","}",".textFitAlignVertFlex .textFitAlignVert{","position: static;","}"].join("");var css=document.createElement("style");css.type="text/css";css.id="textFitStyleSheet";css.innerHTML=style;document.body.appendChild(css)}});
|
81
TaikoWebUI/wwwroot/js/updateTextFit.js
Normal file
@ -0,0 +1,81 @@
|
||||
// Function to be called when the viewfinder size changes
|
||||
var title;
|
||||
var myDonName;
|
||||
var myDonNameOutline;
|
||||
var init = false
|
||||
const observer = new ResizeObserver(handleResize);
|
||||
function handleResize() {
|
||||
updateFit()
|
||||
}
|
||||
|
||||
function waitForElm(selector) {
|
||||
return new Promise(resolve => {
|
||||
if (document.querySelector(selector)) {
|
||||
return resolve(document.querySelector(selector));
|
||||
}
|
||||
|
||||
const observer = new MutationObserver(mutations => {
|
||||
if (document.querySelector(selector)) {
|
||||
observer.disconnect();
|
||||
resolve(document.querySelector(selector));
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// This is a monkey hack to detect when the page has changed (to stop the observer events)
|
||||
var pushState = history.pushState;
|
||||
history.pushState = function () {
|
||||
pushState.apply(history, arguments);
|
||||
init = false;
|
||||
observer.disconnect();
|
||||
};
|
||||
|
||||
// Fetches all the relevant objects on the page so updateFit can reference them later
|
||||
function initNameplate() {
|
||||
if (window.location.href.indexOf("Profile") > -1) {
|
||||
waitForElm('#nameplate-title').then((elm) => {
|
||||
title = elm
|
||||
waitForElm('#nameplate-name').then((elm) => {
|
||||
myDonName = elm
|
||||
waitForElm('#nameplate-name-outline').then((elm) => {
|
||||
myDonNameOutline = elm
|
||||
observer.observe(document.getElementById('nameplate'));
|
||||
init = true
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateFit() {
|
||||
textFit(title, { alignHoriz: true, alignVert: true });
|
||||
textFit(myDonName, { alignHoriz: true, alignVert: true });
|
||||
textFit(myDonNameOutline, { alignHoriz: true, alignVert: true });
|
||||
}
|
||||
|
||||
|
||||
// Used to individually update texts on the nameplate
|
||||
function updateMyDonName(elm) {
|
||||
if (init) {
|
||||
myDonName.textContent = elm
|
||||
myDonNameOutline.textContent = elm
|
||||
updateFit()
|
||||
}
|
||||
}
|
||||
function updateTitle(elm) {
|
||||
if (init) {
|
||||
title.textContent = elm
|
||||
updateFit()
|
||||
}
|
||||
}
|
||||
|
||||
// Called by html onload when the image of the nameplate is loaded (this ensures the first fit is properly done)
|
||||
function nameplateLoaded() {
|
||||
initNameplate()
|
||||
}
|