Add support for darkmode
This commit is contained in:
parent
5284d498f3
commit
9abd570b87
|
|
@ -1,46 +1,48 @@
|
|||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>Frames</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div class="frames-container">
|
||||
<mat-tab-group [selectedIndex]="frames.indexOf(currentFrame)"
|
||||
(selectedIndexChange)="switchFrame(frames[$event])">
|
||||
<mat-tab *ngFor="let frameId of frames" [label]="frameId">
|
||||
<div class="frame-content">
|
||||
<h3>Particles in {{ frameId }}</h3>
|
||||
<div class="particles-list">
|
||||
<div *ngFor="let particle of particleData.frames[frameId]; let i = index" class="particle-item">
|
||||
<div class="card-div">
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>Frames</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div class="frames-container">
|
||||
<mat-tab-group [selectedIndex]="frames.indexOf(currentFrame)"
|
||||
(selectedIndexChange)="switchFrame(frames[$event])">
|
||||
<mat-tab *ngFor="let frameId of frames" [label]="frameId">
|
||||
<div class="frame-content">
|
||||
<h3>Particles in {{ frameId }}</h3>
|
||||
<div class="particles-list">
|
||||
<div *ngFor="let particle of particleData.frames[frameId]; let i = index" class="particle-item">
|
||||
<span class="particle-item-text">
|
||||
Particle {{ i + 1 }}: ({{ particle.x.toFixed(2) }}, {{ particle.y.toFixed(2) }}
|
||||
, {{ particle.z.toFixed(2) }})
|
||||
</span>
|
||||
<button mat-icon-button (click)="removeParticle(frameId, i)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="highlightParticle(frameId, i)">
|
||||
<mat-icon>lightbulb</mat-icon>
|
||||
<button mat-icon-button (click)="removeParticle(frameId, i)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="highlightParticle(frameId, i)">
|
||||
<mat-icon>lightbulb</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="!particleData.frames[frameId] || particleData.frames[frameId].length === 0"
|
||||
class="no-particles">
|
||||
No particles in this frame. Click on the plane to add particles.
|
||||
</div>
|
||||
</div>
|
||||
<div class="frame-actions">
|
||||
<button mat-raised-button color="warn" (click)="removeFrame(frameId)"
|
||||
[disabled]="frames.length <= 1">
|
||||
Remove Frame
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="!particleData.frames[frameId] || particleData.frames[frameId].length === 0"
|
||||
class="no-particles">
|
||||
No particles in this frame. Click on the plane to add particles.
|
||||
</div>
|
||||
</div>
|
||||
<div class="frame-actions">
|
||||
<button mat-raised-button color="warn" (click)="removeFrame(frameId)"
|
||||
[disabled]="frames.length <= 1">
|
||||
Remove Frame
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
<div class="add-frame">
|
||||
<button mat-raised-button color="primary" (click)="addFrame()">
|
||||
Add New Frame
|
||||
</button>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
<div class="add-frame">
|
||||
<button mat-raised-button color="primary" (click)="addFrame()">
|
||||
Add New Frame
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
.no-particles {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: #888;
|
||||
color: var(--color-primairy);
|
||||
}
|
||||
|
||||
.frame-actions {
|
||||
|
|
@ -48,3 +48,14 @@
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card-div {
|
||||
mat-card {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--font-color);
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<mat-card class="color-picker-card">
|
||||
<mat-card-header>
|
||||
<mat-card-title>Particle Color</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div class="color-picker">
|
||||
<input type="color" [(ngModel)]="selectedColor">
|
||||
<span>Selected Color: {{ selectedColor }}</span>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<div class="card-div">
|
||||
<mat-card class="color-picker-card">
|
||||
<mat-card-header>
|
||||
<mat-card-title>Particle Color</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div class="color-picker">
|
||||
<input type="color" [(ngModel)]="selectedColor">
|
||||
<span>Selected Color: {{ selectedColor }}</span>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -15,3 +15,14 @@
|
|||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.card-div {
|
||||
mat-card {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--font-color);
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,91 +1,93 @@
|
|||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>Particle Properties</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Particle Name</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.particle_name" placeholder="Enter particle name">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="card-div">
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>Particle Properties</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Particle Name</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.particle_name" placeholder="Enter particle name">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Display Name</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.display_name" placeholder="Enter display name">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Display Name</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.display_name" placeholder="Enter display name">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Particle Type</mat-label>
|
||||
<mat-select [(ngModel)]="particleData.particle_type">
|
||||
<mat-option *ngFor="let type of particleTypes" [value]="type">{{ type }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Particle Type</mat-label>
|
||||
<mat-select [(ngModel)]="particleData.particle_type">
|
||||
<mat-option *ngFor="let type of particleTypes" [value]="type">{{ type }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Lore</mat-label>
|
||||
<textarea matInput [(ngModel)]="particleData.lore" placeholder="Enter lore"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Lore</mat-label>
|
||||
<textarea matInput [(ngModel)]="particleData.lore" placeholder="Enter lore"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Display Item</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.display_item" placeholder="Enter display item">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Display Item</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.display_item" placeholder="Enter display item">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Permission</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.permission" placeholder="Enter permission">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Permission</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.permission" placeholder="Enter permission">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Package Permission</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.package_permission" placeholder="Enter package permission">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Package Permission</mat-label>
|
||||
<input matInput [(ngModel)]="particleData.package_permission" placeholder="Enter package permission">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Frame Delay</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="particleData.frame_delay" placeholder="Enter frame delay">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Frame Delay</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="particleData.frame_delay" placeholder="Enter frame delay">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Repeat</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="particleData.repeat" placeholder="Enter repeat count">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Repeat</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="particleData.repeat" placeholder="Enter repeat count">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Repeat Delay</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="particleData.repeat_delay"
|
||||
placeholder="Enter repeat delay">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Repeat Delay</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="particleData.repeat_delay"
|
||||
placeholder="Enter repeat delay">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Random Offset</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="particleData.random_offset"
|
||||
placeholder="Enter random offset">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Random Offset</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="particleData.random_offset"
|
||||
placeholder="Enter random offset">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<mat-checkbox [(ngModel)]="particleData.stationary">Stationary</mat-checkbox>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<div class="form-row">
|
||||
<mat-checkbox [(ngModel)]="particleData.stationary"><span>Stationary</span></mat-checkbox>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
.form-row {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.card-div {
|
||||
mat-card {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--font-color);
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
<div #rendererContainer class="renderer-container">
|
||||
<div class="plane-controls-overlay">
|
||||
<button mat-mini-fab color="primary" (click)="resetCamera()"
|
||||
matTooltip="Reset camera">
|
||||
<mat-icon>location_searching</mat-icon>
|
||||
</button>
|
||||
<div class="button-row">
|
||||
<button mat-mini-fab color="primary" (click)="resetCamera()"
|
||||
matTooltip="Reset camera">
|
||||
<mat-icon>location_searching</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-mini-fab color="primary" (click)="togglePlaneLock()"
|
||||
[matTooltip]="isPlaneLocked ? 'Unlock Plane' : 'Lock Plane'">
|
||||
<mat-icon>{{ isPlaneLocked ? 'lock' : 'lock_open' }}</mat-icon>
|
||||
</button>
|
||||
<button mat-mini-fab color="primary" (click)="togglePlaneLock()"
|
||||
[matTooltip]="isPlaneLocked ? 'Unlock Plane' : 'Lock Plane'">
|
||||
<mat-icon>{{ isPlaneLocked ? 'lock' : 'lock_open' }}</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="isPlaneLocked" class="plane-orientation-buttons">
|
||||
<button mat-mini-fab color="warn" (click)="setPlaneOrientation(planeOrientations.VERTICAL_ABOVE)"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
background-color: #f0f0f0;
|
||||
background-color: var(--color-primairy);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
|
@ -21,6 +21,13 @@
|
|||
z-index: 10;
|
||||
}
|
||||
|
||||
.button-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.plane-orientation-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
|
|
@ -42,5 +49,5 @@
|
|||
.plane-orientation-buttons button.active {
|
||||
opacity: 1;
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
|
||||
box-shadow: 0 0 10px var(--color-tertiary);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,14 @@
|
|||
gap: 20px;
|
||||
}
|
||||
|
||||
label, span {
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
||||
.plane-controls {
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
background-color: #f5f5f5;
|
||||
background-color: var(--color-primairy);
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -30,10 +34,92 @@
|
|||
flex: 1;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
margin-bottom: 15px;
|
||||
:host ::ng-deep {
|
||||
.mdc-text-field--outlined {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.mdc-text-field--outlined .mdc-floating-label,
|
||||
.mdc-text-field--outlined .mdc-text-field__input,
|
||||
.mat-mdc-form-field-label,
|
||||
.mat-mdc-select-value-text,
|
||||
.mat-mdc-select-arrow,
|
||||
.mat-mdc-checkbox-label,
|
||||
.mat-mdc-card-header,
|
||||
.mat-mdc-card-title,
|
||||
.mat-mdc-card-content {
|
||||
color: var(--font-color) !important;
|
||||
}
|
||||
|
||||
.mdc-text-field--outlined .mdc-notched-outline .mdc-notched-outline__leading,
|
||||
.mdc-text-field--outlined .mdc-notched-outline .mdc-notched-outline__notch,
|
||||
.mdc-text-field--outlined .mdc-notched-outline .mdc-notched-outline__trailing {
|
||||
border-color: var(--font-color) !important;
|
||||
}
|
||||
|
||||
// Fix for dropdown menu
|
||||
.mat-mdc-select-panel {
|
||||
background-color: var(--color-primary) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-option {
|
||||
color: var(--font-color) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-option:hover:not(.mdc-list-item--disabled) {
|
||||
background-color: rgba(255, 255, 255, 0.1) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-option.mat-mdc-option-active {
|
||||
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-select-panel {
|
||||
background-color: var(--color-primary) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-option {
|
||||
color: var(--font-color) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-option:hover:not(.mdc-list-item--disabled) {
|
||||
background-color: rgba(255, 255, 255, 0.1) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-option.mat-mdc-option-active {
|
||||
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-tab {
|
||||
color: var(--font-color) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-tab-header {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.mat-mdc-tab-label-container {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.mdc-tab__content .mdc-tab__text-label {
|
||||
color: var(--font-color) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-tab-label, .mat-mdc-tab-link {
|
||||
color: var(--font-color) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-tab-group.mat-primary .mat-mdc-tab:not(.mat-mdc-tab-disabled) .mdc-tab-indicator__content--underline {
|
||||
border-color: var(--font-color) !important;
|
||||
}
|
||||
|
||||
.mat-mdc-tab-body-content {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.mat-icon {
|
||||
color: var(--font-color);
|
||||
}
|
||||
}
|
||||
|
||||
mat-form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import {ElementRef, Injectable} from '@angular/core';
|
||||
import * as THREE from 'three';
|
||||
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
|
||||
import {ThemeService} from '../../theme/theme.service';
|
||||
import {THEME_MODE} from '../../constant';
|
||||
|
||||
/**
|
||||
* Service responsible for managing the Three.js rendering environment
|
||||
|
|
@ -13,6 +15,16 @@ export class RendererService {
|
|||
camera!: THREE.PerspectiveCamera;
|
||||
renderer!: THREE.WebGLRenderer;
|
||||
controls!: OrbitControls;
|
||||
private currentTheme: THEME_MODE = THEME_MODE.LIGHT;
|
||||
|
||||
constructor(private themeService: ThemeService) {
|
||||
this.themeService.theme$.subscribe(theme => {
|
||||
this.currentTheme = theme;
|
||||
if (this.scene) {
|
||||
this.setBackgroundColor(theme);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Three.js scene, camera, renderer, and controls
|
||||
|
|
@ -20,7 +32,7 @@ export class RendererService {
|
|||
initializeRenderer(container: ElementRef): void {
|
||||
// Create scene
|
||||
this.scene = new THREE.Scene();
|
||||
this.scene.background = new THREE.Color(0xf0f0f0);
|
||||
this.setBackgroundColor(this.currentTheme);
|
||||
|
||||
// Get container dimensions
|
||||
const containerWidth = container.nativeElement.clientWidth;
|
||||
|
|
@ -54,6 +66,10 @@ export class RendererService {
|
|||
this.addLights();
|
||||
}
|
||||
|
||||
private setBackgroundColor(theme: THEME_MODE) {
|
||||
this.scene.background = new THREE.Color(this.currentTheme === THEME_MODE.DARK ? 0x242526 : 0xFBFBFE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the camera to its default position and orientation.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user