Files
dkala-front/public/the-cube-master/src/js/ThemeEditor.js
T
2026-02-07 15:31:22 +03:30

179 lines
4.6 KiB
JavaScript

import { Tween, Easing } from './Tween.js';
class ThemeEditor {
constructor( game ) {
this.game = game;
this.editColor = 'R';
this.getPieceColor = this.getPieceColor.bind( this );
}
colorFromHSL( h, s, l ) {
h = Math.round( h );
s = Math.round( s );
l = Math.round( l );
return new THREE.Color( `hsl(${h}, ${s}%, ${l}%)` );
}
setHSL( color = null, animate = false ) {
this.editColor = ( color === null) ? 'R' : color;
const hsl = new THREE.Color( this.game.themes.getColors()[ this.editColor ] );
const { h, s, l } = hsl.getHSL( hsl );
const { hue, saturation, lightness } = this.game.preferences.ranges;
if ( animate ) {
const ho = hue.value / 360;
const so = saturation.value / 100;
const lo = lightness.value / 100;
const colorOld = this.colorFromHSL( hue.value, saturation.value, lightness.value );
if ( this.tweenHSL ) this.tweenHSL.stop()
this.tweenHSL = new Tween( {
duration: 200,
easing: Easing.Sine.Out(),
onUpdate: tween => {
hue.setValue( ( ho + ( h - ho ) * tween.value ) * 360 );
saturation.setValue( ( so + ( s - so ) * tween.value ) * 100 );
lightness.setValue( ( lo + ( l - lo ) * tween.value ) * 100 );
const colorTween = colorOld.clone().lerp( hsl, tween.value );
const colorTweenStyle = colorTween.getStyle();
const colorTweenHex = colorTween.getHSL( colorTween );
hue.handle.style.color = colorTweenStyle;
saturation.handle.style.color = colorTweenStyle;
lightness.handle.style.color = colorTweenStyle;
saturation.track.style.color =
this.colorFromHSL( colorTweenHex.h * 360, 100, 50 ).getStyle();
lightness.track.style.color =
this.colorFromHSL( colorTweenHex.h * 360, colorTweenHex.s * 100, 50 ).getStyle();
this.game.dom.theme.style.display = 'none';
this.game.dom.theme.offsetHeight;
this.game.dom.theme.style.display = '';
},
onComplete: () => {
this.updateHSL();
this.game.storage.savePreferences();
},
} );
} else {
hue.setValue( h * 360 );
saturation.setValue( s * 100 );
lightness.setValue( l * 100 );
this.updateHSL();
this.game.storage.savePreferences();
}
}
updateHSL() {
const { hue, saturation, lightness } = this.game.preferences.ranges;
const h = hue.value;
const s = saturation.value;
const l = lightness.value;
const color = this.colorFromHSL( h, s, l ).getStyle();
hue.handle.style.color = color;
saturation.handle.style.color = color;
lightness.handle.style.color = color;
saturation.track.style.color = this.colorFromHSL( h, 100, 50 ).getStyle();
lightness.track.style.color = this.colorFromHSL( h, s, 50 ).getStyle();
this.game.dom.theme.style.display = 'none';
this.game.dom.theme.offsetHeight;
this.game.dom.theme.style.display = '';
const theme = this.game.themes.theme;
this.game.themes.colors[ theme ][ this.editColor ] = this.colorFromHSL( h, s, l ).getHex();
this.game.themes.setTheme();
}
colorPicker( enable ) {
if ( enable ) {
this.game.dom.game.addEventListener( 'click', this.getPieceColor, false );
} else {
this.game.dom.game.removeEventListener( 'click', this.getPieceColor, false );
}
}
getPieceColor( event ) {
const clickEvent = event.touches
? ( event.touches[ 0 ] || event.changedTouches[ 0 ] )
: event;
const clickPosition = new THREE.Vector2( clickEvent.pageX, clickEvent.pageY );
let edgeIntersect = this.game.controls.getIntersect( clickPosition, this.game.cube.edges, true );
let pieceIntersect = this.game.controls.getIntersect( clickPosition, this.game.cube.cubes, true );
if ( edgeIntersect !== false ) {
const edge = edgeIntersect.object;
const position = edge.parent
.localToWorld( edge.position.clone() )
.sub( this.game.cube.object.position )
.sub( this.game.cube.animator.position );
const mainAxis = this.game.controls.getMainAxis( position );
if ( position.multiplyScalar( 2 ).round()[ mainAxis ] < 1 ) edgeIntersect = false;
}
const name = edgeIntersect ? edgeIntersect.object.name : pieceIntersect ? 'P' : 'G';
this.setHSL( name, true );
}
resetTheme() {
this.game.themes.colors[ this.game.themes.theme ] =
JSON.parse( JSON.stringify( this.game.themes.defaults[ this.game.themes.theme ] ) );
this.game.themes.setTheme();
this.setHSL( this.editColor, true );
}
}
export { ThemeEditor };