Skip to content

Commit

Permalink
Merge pull request #14 from CaptSiro/featureHitJudgements
Browse files Browse the repository at this point in the history
Feature hit judgements
  • Loading branch information
happpy24 authored Oct 9, 2024
2 parents 62716ad + 5f9d018 commit cea1917
Show file tree
Hide file tree
Showing 6 changed files with 328 additions and 39 deletions.
10 changes: 8 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
rel="stylesheet"
href="styles/difficulty-graph.css"
/>
<link
rel="stylesheet"
href="styles/hit-judgements.css"
/>
</head>

<body>
Expand Down Expand Up @@ -57,7 +61,7 @@
<span>CS</span>
<span id="cs">4</span>
</div>

<div class="ar">
<span>AR</span>
<span id="ar">8</span>
Expand All @@ -78,7 +82,7 @@
<div class="bg-underlay"></div>
<img id="bg" class="bg" src="./assets/noimage.png">
<div class="bg-overlay"></div>

</div>
<div class="right">
<div class="hit-errors">
Expand Down Expand Up @@ -116,7 +120,9 @@
height="64"
></canvas>
</div>
<div id="hit-judgements"></div>
</div>

<!-- OTHER SCRIPTS -->
<script src="js/odometr.js"></script>
<script src="js/countUp.js"></script>
Expand Down
90 changes: 59 additions & 31 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import {
fastSmooth,
max
} from "./js/fast-smooth.js";
const socket = new WebSocketManager(window.location.host);
import { hitJudgementsAdd, hitJudgementsClear } from "./js/hit-judgements.js";
import GraphFill, { Color } from "./js/GraphFill.js";
const socket = new WebSocketManager('127.0.0.1:24050');

new Odometer({
el: document.getElementById('bpm'),
Expand All @@ -27,30 +29,35 @@ new Odometer({
});

const cache = {
h100: -1,
h50: -1,
h0: -1,
accuracy: -1,
title: "",
artist: "",
difficulty: "",
bpm: -1,
cs: -1,
ar: -1,
od: -1,
hp: -1,
maxSR: -1,
ppFC: -1,
background: "",
difficultyGraph: ''
h100: -1,
h50: -1,
h0: -1,
sliderBreaks: -1,
accuracy: -1,
title: "",
artist: "",
difficulty: "",
bpm: -1,
cs: -1,
ar: -1,
od: -1,
hp: -1,
maxSR: -1,
ppFC: -1,
background: "",
difficultyGraph: ''
};

let graphSmoothing = 2; // from 0 (no smoothing) to 5 (max smoothing)
let configDarker = createChartConfig('rgba(185, 234, 255, 0.4)');
let configLighter = createChartConfig('rgba(185, 234, 255, 0.7)');
/** @type {0 | 1 | 2 | 3 | 4 | 5} from 0 (no smoothing) to 5 (max smoothing) */
let graphSmoothing = 2;
const gradientDarker = new GraphFill(new Color(185, 234, 255, 0.4), Color.TRANSPARENT);
const gradientLighter = new GraphFill(new Color(185, 234, 255, 0.7));
let configDarker = createChartConfig(gradientDarker);
let configLighter = createChartConfig(gradientLighter);
let chartDarker;
let chartLighter;
let chartProgress;
let hitJudgementsElement;

function renderGraph(graphData) {
// Better be sure. In case someone forgets
Expand Down Expand Up @@ -144,11 +151,15 @@ socket.commands((data) => {
}

if (message['GraphColor'] != null) {
(chartDarker || configDarker).data.datasets[0].backgroundColor = hexToRgbA(message['GraphColor'], 0.4);
(configLighter || configLighter).data.datasets[0].backgroundColor = hexToRgbA(message['GraphColor'], 0.7);
gradientDarker.setFill(Color.fromHex(message['GraphColor']).setAlpha(0.5));
gradientDarker.setBorder(Color.TRANSPARENT.clone());

chartDarker && chartDarker.update();
chartLighter && chartLighter.update();
const fill = Color.fromHex(message['GraphColor']);
gradientLighter.setFill(fill.setAlpha(0.5));
gradientLighter.setBorder(fill.clone().setAlpha(1));

chartDarker?.update();
chartLighter?.update();
}

if (message['GraphSmoothing'] != null) {
Expand Down Expand Up @@ -246,6 +257,7 @@ const ppCache = {

socket.api_v2(({ play, beatmap, directPath, folders, performance, state, resultsScreen }) => {
try {
const percentage = Math.max(0, Math.min(beatmap.time.live / beatmap.time.mp3Length * 100, 100));
if (chartDarker !== undefined && chartLighter !== undefined && chartProgress !== undefined) {
const dataString = JSON.stringify(performance.graph);
if (cache.difficultyGraph !== dataString) {
Expand All @@ -254,26 +266,42 @@ socket.api_v2(({ play, beatmap, directPath, folders, performance, state, results
renderGraph(performance.graph);
}

const percentage = Math.max(0, Math.min(beatmap.time.live / beatmap.time.mp3Length * 100, 100));
chartProgress.style.width = String(percentage) + "%";
}

let pp = state.name === 'ResultScreen' ? resultsScreen.pp : play.pp;
let hits = state.name === 'ResultScreen' ? resultsScreen.hits : play.hits;

const isSliderBreak = cache.sliderBreaks !== hits['sliderBreaks'];

if (cache.h100 !== hits['100']) {
cache.h100 = hits['100'];
h100.update(hits['100']);

if (hits['100'] > 0 && state.name === "Play") {
cache.sliderBreaks = hits['sliderBreaks'];
hitJudgementsAdd(hitJudgementsElement, "100", percentage, isSliderBreak);
}
}

if (cache.h50 !== hits['50']) {
cache.h50 = hits['50'];
h50.update(hits['50']);

if (hits['50'] > 0 && state.name === "Play") {
cache.sliderBreaks = hits['sliderBreaks'];
hitJudgementsAdd(hitJudgementsElement, "50", percentage, isSliderBreak);
}
}

if (cache.h0 !== hits['0']) {
cache.h0 = hits['0'];
h0.update(hits['0']);

if (hits['0'] > 0 && state.name === "Play") {
cache.sliderBreaks = hits['sliderBreaks'];
hitJudgementsAdd(hitJudgementsElement, "x", percentage, isSliderBreak);
}
}

if (cache.pp !== Math.round(pp.current)) {
Expand Down Expand Up @@ -420,7 +448,7 @@ socket.api_v2(({ play, beatmap, directPath, folders, performance, state, results

if (state.name !== 'Play' && state.name !== 'ResultScreen') {
const pp = document.getElementById('ppFC');

const hitErrors = document.getElementById('ppFC');

if (pp.innerHTML !== cache.ppSS) {
Expand All @@ -431,7 +459,7 @@ socket.api_v2(({ play, beatmap, directPath, folders, performance, state, results
hitErrorsContainer.style.opacity = 0;
ppContainer.style.height = '100%';

ppValueContainer.style.transform =
ppValueContainer.style.transform =
`translateX(-50%) scale(1.8)`
ppValueContainer.style.left = '50%'

Expand All @@ -450,7 +478,7 @@ socket.api_v2(({ play, beatmap, directPath, folders, performance, state, results
ppValueContainer.style.transform =
`translateX(-50%) scale(1)`
ppValueContainer.style.left = '75%'

ppCurrent.style.opacity = 1;
slash.style.opacity = 1;

Expand Down Expand Up @@ -514,16 +542,16 @@ function reset(item) {

/**
* No comments, just shitcode
* @param {HTMLElement} parent
* @param {HTMLElement} child
* @param {HTMLElement} parent
* @param {HTMLElement} child
*/
async function checkAndAnimateScroll(parent, child) {
if (child.getBoundingClientRect().width >= parent.getBoundingClientRect().width) {
parent.classList.add('marquee')
const titles = parent.querySelectorAll('span')

if (titles.length < 2) parent.append(child.cloneNode(true));

} else {
parent.classList.remove('marquee')
const titles = parent.querySelectorAll('span')
Expand Down
141 changes: 141 additions & 0 deletions js/GraphFill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
export class Color {
static TRANSPARENT = new Color(0, 0, 0, 0);

static fromHex(literal) {
let c;

if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(literal)) {
c = literal.substring(1).split('');

if (c.length === 3) {
c = [c[0], c[0], c[1], c[1], c[2], c[2]];
}

c = '0x' + c.join('');
return new Color((c >> 16) & 255, (c >> 8) & 255, c & 255);
}

throw new Error('Bad Hex');
}



#red;
#green;
#blue;
#alpha;

constructor(red, green, blue, alpha = 1) {
this.#red = red;
this.#green = green;
this.#blue = blue;
this.#alpha = alpha;
}



setAlpha(alpha) {
this.#alpha = alpha;
return this;
}

getAlpha() {
return this.#alpha;
}

clone() {
return new Color(
this.#red,
this.#green,
this.#blue,
this.#alpha
);
}

toString() {
return `rgba(${this.#red}, ${this.#green}, ${this.#blue}, ${this.#alpha})`;
}
}



export default class GraphFill {
#gradient;
#width;
#height;
/** @type {Color} */
#fill;
/** @type {Color} */
#border;
#colorUsed;



/**
* @param {Color} fill
* @param border
*/
constructor(fill, border = undefined) {
this.#fill = fill;
this.#border = border !== undefined ? border : fill.clone().setAlpha(1);
}



/**
* @param {Color} color
*/
setFill(color) {
this.#fill = color;
return this;
}

/**
* @param {Color} color
*/
setBorder(color) {
this.#border = color;
return this;
}

create(context, chartArea) {
const chartWidth = chartArea.right - chartArea.left;
const chartHeight = chartArea.bottom - chartArea.top;

if (this.#gradient === undefined
|| this.#width !== chartWidth
|| this.#height !== chartHeight
|| this.#colorUsed !== this.#fill.toString()) {
// Create the gradient because this is either the first render or the size of the chart has changed

this.#width = chartWidth;
this.#height = chartHeight;
this.#gradient = context.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);

this.#gradient.addColorStop(0, this.#fill.clone().setAlpha(0.1).toString());
this.#gradient.addColorStop(0.4, this.#fill.toString());
}

return this.#gradient;
}

border() {
return () => this.#border.toString();
}

/**
* Creates a function for Chart config. This function can be assigned to borderColor or backgroundColor property
* @returns {function(*): CanvasGradient}
*/
background() {
return (context) => {
const chart = context.chart;
if (!chart.chartArea) {
// This case happens on initial chart load
return;
}

return this.create(chart.ctx, chart.chartArea);
};
}
}
Loading

0 comments on commit cea1917

Please sign in to comment.