Skip to content

Commit 98e6452

Browse files
deltakoshDavid Catuhe
andauthored
Add inspector tools to debug particle attractors (#16613)
Fix #16611 Fix #16605 Co-authored-by: David Catuhe <[email protected]>
1 parent 6d2c211 commit 98e6452

File tree

4 files changed

+489
-0
lines changed

4 files changed

+489
-0
lines changed

packages/dev/inspector/src/components/actionTabs/actionTabs.scss

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,134 @@ $line-padding-left: 2px;
135135
margin: 15px 5px 0px 5px;
136136
}
137137

138+
.attractor-step {
139+
display: grid;
140+
grid-template-rows: 100%;
141+
grid-template-columns: 20px 40px auto 20px 20px 30px;
142+
padding-top: 5px;
143+
padding-left: 5px;
144+
padding-bottom: 5px;
145+
align-items: center;
146+
147+
.index {
148+
grid-row: 1;
149+
grid-column: 1;
150+
}
151+
152+
.icon {
153+
cursor: pointer;
154+
}
155+
156+
.strength-value {
157+
margin-left: 5px;
158+
grid-row: 1;
159+
grid-column: 2;
160+
text-align: right;
161+
margin-right: 5px;
162+
}
163+
164+
.strength-slider {
165+
grid-row: 1;
166+
grid-column: 3;
167+
display: grid;
168+
justify-content: stretch;
169+
align-content: center;
170+
margin-right: 12px;
171+
172+
input {
173+
width: 100%;
174+
}
175+
.range:hover {
176+
opacity: 1;
177+
}
178+
179+
.range {
180+
-webkit-appearance: none;
181+
height: 6px;
182+
background: #d3d3d3;
183+
border-radius: 5px;
184+
outline: none;
185+
opacity: 0.7;
186+
transition: opacity 0.2s;
187+
}
188+
189+
.range::-webkit-slider-thumb {
190+
-webkit-appearance: none;
191+
appearance: none;
192+
width: 14px;
193+
height: 14px;
194+
border-radius: 50%;
195+
background: rgb(51, 122, 183);
196+
cursor: pointer;
197+
}
198+
199+
.range::-moz-range-thumb {
200+
width: 14px;
201+
height: 14px;
202+
border-radius: 50%;
203+
background: rgb(51, 122, 183);
204+
cursor: pointer;
205+
}
206+
}
207+
208+
.attractor-control {
209+
grid-row: 1;
210+
grid-column: 4;
211+
display: grid;
212+
align-content: center;
213+
justify-content: center;
214+
opacity: 0.5;
215+
216+
.img {
217+
height: 20px;
218+
width: 20px;
219+
}
220+
.img:hover {
221+
cursor: pointer;
222+
}
223+
224+
&.active {
225+
opacity: 1;
226+
}
227+
}
228+
229+
.attractor-view {
230+
grid-row: 1;
231+
grid-column: 5;
232+
display: grid;
233+
align-content: center;
234+
justify-content: center;
235+
opacity: 0.5;
236+
237+
.img {
238+
height: 20px;
239+
width: 20px;
240+
}
241+
.img:hover {
242+
cursor: pointer;
243+
}
244+
245+
&.active {
246+
opacity: 1;
247+
}
248+
}
249+
250+
.attractor-delete {
251+
grid-row: 1;
252+
grid-column: 6;
253+
display: grid;
254+
align-content: center;
255+
justify-content: center;
256+
.img {
257+
height: 20px;
258+
width: 20px;
259+
}
260+
.img:hover {
261+
cursor: pointer;
262+
}
263+
}
264+
}
265+
138266
.gradient-step {
139267
display: grid;
140268
grid-template-rows: 100%;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import * as React from "react";
2+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
3+
import { faArrowsAlt, faEye, faTrash } from "@fortawesome/free-solid-svg-icons";
4+
import type { GlobalState } from "../../../../globalState";
5+
import type { LockObject } from "shared-ui-components/tabs/propertyGrids/lockObject";
6+
import type { IParticleSystem } from "core/Particles/IParticleSystem";
7+
import type { Attractor } from "core/Particles/attractor";
8+
9+
interface IAttractorGridComponent {
10+
globalState: GlobalState;
11+
attractor: Attractor;
12+
lockObject: LockObject;
13+
lineIndex: number;
14+
host: IParticleSystem;
15+
codeRecorderPropertyName: string;
16+
onDelete: (attractor: Attractor) => void;
17+
removeImpostor: (attractor: Attractor) => void;
18+
addImpostor: (attractor: Attractor, index: number) => void;
19+
onControl: (attractor: Attractor) => void;
20+
isControlled: (attractor: Attractor) => void;
21+
}
22+
23+
export class AttractorGridComponent extends React.Component<IAttractorGridComponent, { strength: number; viewing: boolean }> {
24+
constructor(props: IAttractorGridComponent) {
25+
super(props);
26+
27+
this.state = { strength: props.attractor.strength, viewing: false };
28+
}
29+
30+
lock() {
31+
if (this.props.lockObject) {
32+
this.props.lockObject.lock = true;
33+
}
34+
}
35+
36+
unlock() {
37+
if (this.props.lockObject) {
38+
this.props.lockObject.lock = false;
39+
}
40+
}
41+
42+
updateStrength(strength: number) {
43+
this.props.attractor.strength = strength;
44+
45+
this.setState({ strength: strength });
46+
}
47+
48+
onView() {
49+
const scene = this.props.host.getScene();
50+
51+
if (!scene) {
52+
return;
53+
}
54+
55+
if ((this.props.attractor as any)._impostor) {
56+
this.props.removeImpostor(this.props.attractor);
57+
this.setState({ viewing: false });
58+
return;
59+
}
60+
61+
this.props.addImpostor(this.props.attractor, this.props.lineIndex);
62+
63+
this.setState({ viewing: true });
64+
}
65+
66+
onControl() {
67+
if (!this.state.viewing) {
68+
return;
69+
}
70+
this.props.onControl(this.props.attractor);
71+
}
72+
73+
override render() {
74+
const attractor = this.props.attractor;
75+
76+
return (
77+
<div className="attractor-step">
78+
<div className="index">{`#${this.props.lineIndex}`}</div>
79+
<div className="strength-value">{attractor.strength.toFixed(2)}</div>
80+
<div className="strength-slider">
81+
<input
82+
className="range"
83+
type="range"
84+
step={0.01}
85+
min={-10.0}
86+
max={10.0}
87+
value={attractor.strength}
88+
onChange={(evt) => this.updateStrength(parseFloat(evt.target.value))}
89+
/>
90+
</div>
91+
<div className={"attractor-control hoverIcon icon" + (this.state.viewing && this.props.isControlled(attractor) ? " active" : "")} onClick={() => this.onControl()}>
92+
<FontAwesomeIcon icon={faArrowsAlt} />
93+
</div>
94+
<div className={"attractor-view hoverIcon icon" + (this.state.viewing ? " active" : "")} onClick={() => this.onView()}>
95+
<FontAwesomeIcon icon={faEye} />
96+
</div>
97+
<div className="attractor-delete hoverIcon icon" onClick={() => this.props.onDelete(attractor)}>
98+
<FontAwesomeIcon icon={faTrash} />
99+
</div>
100+
</div>
101+
);
102+
}
103+
}

0 commit comments

Comments
 (0)