!2763 优化:在特性面板增加灯光参数批量调整功能

pull/2541/MERGE
钱若寒 3 months ago committed by ChenX
parent 0d41dc7d04
commit 3adf1ac6c4

@ -0,0 +1,656 @@
import { Alignment, Button, Classes, FormGroup, Icon, InputGroup, Label, NumericInput, Popover, PopoverPosition, Position, Slider, Switch, Tooltip } from "@blueprintjs/core";
import { observable } from "mobx";
import { observer } from "mobx-react";
import React from "react";
import { ColorResult } from "react-color";
import SketchPicker from "react-color/lib/components/sketch/Sketch";
import { MathUtils, Vector3 } from "three";
import { Color } from "three/src/math/Color";
import { app } from "../../ApplicationServices/Application";
import { CoolDownTime } from "../../Common/CoolDownTime";
import { ResourcesCDN_HOST } from "../../Common/HostUrl";
import { KeyBoard } from "../../Common/KeyEnum";
import { UpdateDraw } from "../../Common/Status";
import { Intent } from "../../Common/Toaster";
import { FixedNotZero } from "../../Common/Utils";
import { DirectionalLight } from "../../DatabaseServices/Lights/DirectionalLight";
import { Light } from "../../DatabaseServices/Lights/Light";
import { PointLight } from "../../DatabaseServices/Lights/PointLight";
import { RectAreaLight } from "../../DatabaseServices/Lights/RectAreaLight";
import { SpotLight } from "../../DatabaseServices/Lights/SpotLight";
import { CommandWrap, commandMachine } from "../../Editor/CommandMachine";
import { CommandState } from "../../Editor/CommandState";
import { PromptStatus } from "../../Editor/PromptResult";
import { userConfig } from "../../Editor/UserConfig";
import { BoardModalType } from "../../UI/Components/Board/BoardModalType";
import { AppToaster } from "../../UI/Components/Toaster";
import { PropertiesStore } from "../../UI/Components/ToolBar/PropertiesStore";
import { LightStore } from "../../UI/Store/RightPanelStore/LightStore";
import { Entitys2Data } from "../ExportData";
import './LightBoxModel.less';
interface LightBoxModelProps
{
store: PropertiesStore;
}
@observer
export class LightBoxModel extends React.Component<LightBoxModelProps, {}>
{
render()
{
let ents = this.props.store.GetEntitys();
let lightType: BoardModalType;
let currentLight = ents[0] as RectAreaLight | SpotLight | PointLight;
let lightStore = new LightStore().InitLightData(ents[0] as RectAreaLight | SpotLight | PointLight);
lightStore.IsDrawLight = true;
let targetLightStores: LightStore[] = [];
for (let i = 1; i < ents.length; i++)
{
let targetLight = ents[i];
if (targetLight instanceof RectAreaLight || targetLight instanceof SpotLight || targetLight instanceof PointLight)
{
let targetLightStore = new LightStore().InitLightData(targetLight);
targetLightStores.push(targetLightStore);
}
}
ents = ents.filter((entity, index) => index !== 0 && (entity instanceof SpotLight || entity instanceof RectAreaLight || entity instanceof PointLight));
if (currentLight instanceof SpotLight)
{
lightType = BoardModalType.SpotLight;
}
else if (currentLight instanceof RectAreaLight)
{
lightType = BoardModalType.RectAreaLight;
}
else if (currentLight instanceof PointLight)
{
lightType = BoardModalType.PointLight;
}
return (
<div id="SpotLightModel" className={Classes.DIALOG_CONTAINER}
style={{ width: 'auto', border: '1px solid #ccc', borderRadius: '5px', minHeight: 0 }}>
<LightModel store={lightStore} lightType={lightType} lights={targetLightStores} />
</div >
);
}
}
interface LightConfigModelProps
{
store: LightStore;
lightType: BoardModalType;
lights: LightStore[];
}
interface ILightProperty
{
Target: Vector3;
ShowHelper: boolean;
CaseShadow: boolean;
Color: string;
Temperature: string;
}
@observer
export class LightModel extends React.Component<LightConfigModelProps, {}>
{
@observable _Target: string = this.props.lightType === BoardModalType.PointLight ? "" : (this.props.store.currentSelectEnt as SpotLight | RectAreaLight).Target.sub(this.props.store.currentSelectEnt.Position).normalize().ceil().toArray().toString();
@observable _Position: string = this.props.store.currentSelectEnt.Position.ceil().toArray().toString();
private removeFuncs: Function[] = []; //移除注入
private coolTime = new CoolDownTime;
handleSelectTarget = async (light: Light, isDirection?: boolean) =>
{
await app.Editor.ModalManage.EndExecingCmd();
CommandWrap(async () =>
{
app.Editor.MaskManage.Clear();
let ptRes = await app.Editor.GetPoint({
Msg: "选择目标"
});
if (ptRes.Status === PromptStatus.OK)
{
if (isDirection)
{
if (light instanceof SpotLight || light instanceof DirectionalLight)
{
light.Target = ptRes.Point;
this._Target = ptRes.Point.clone().sub(this.props.store.currentSelectEnt.Position).normalize().ceil().toArray().toString();
light.Update(UpdateDraw.Matrix);
this.changeLightSettings('Target', ptRes.Point);
}
else if (light instanceof RectAreaLight)
{
light.Target = ptRes.Point;
this.changeLightSettings('Target', ptRes.Point);
}
if (userConfig.synchronousEnable)
app.WebSocket.Send(JSON.stringify(Entitys2Data([light])));
}
}
}, "target");
};
//同步数据
private SyncLight()
{
if (userConfig.synchronousEnable)
this.coolTime.Debounce(() =>
{
app.WebSocket.Send(JSON.stringify(Entitys2Data([this.props.store.currentSelectEnt])));
}, 10);
}
// 批量修改灯光属性
changeLightSettings = (propertyName: keyof ILightProperty, propertyValue: ILightProperty[keyof ILightProperty]) =>
{
for (const light of this.props.lights)
{
let targetLightData = light.lightData;
let targetLight = light.currentSelectEnt;
if (targetLightData.hasOwnProperty(propertyName))
{
targetLight[propertyName] = propertyValue;
targetLightData[propertyName] = propertyValue;
}
if (propertyName === 'Target')
{
if (targetLight instanceof SpotLight || targetLight instanceof DirectionalLight)
{
targetLight.Target = propertyValue as Vector3;
this._Target = (propertyValue as Vector3).clone().sub(this.props.store.currentSelectEnt.Position).normalize().ceil().toArray().toString();
targetLight.Update(UpdateDraw.Matrix);
}
else if (targetLight instanceof RectAreaLight)
targetLight.Target = propertyValue as Vector3;;
if (userConfig.synchronousEnable)
app.WebSocket.Send(JSON.stringify(Entitys2Data([targetLight])));
}
}
};
render()
{
let lightData = this.props.store.lightData;
let light = this.props.store.currentSelectEnt;
return (
<div className={Classes.DIALOG_CONTAINER}>
<div className={Classes.DIALOG} style={{ height: "100%", margin: '0 auto', boxShadow: 'none', width: '100%' }}>
<div className={Classes.DIALOG_BODY}>
<div style={{ height: 25 }}>
<Switch
style={{ paddingLeft: '5px', paddingRight: '42px' }}
checked={lightData.ShowHelper}
label="显示灯光助手"
onChange={e =>
{
CommandWrap(() =>
{
light.ShowHelper = !light.ShowHelper;
this.changeLightSettings('ShowHelper', lightData.ShowHelper);
}, "灯光助手显示/隐藏");
app.Viewer.UpdateRender();
lightData.ShowHelper = !lightData.ShowHelper;
}}
alignIndicator={Alignment.RIGHT}
/>
</div>
<div style={{ height: 25 }}>
<Switch
checked={lightData.CaseShadow}
style={{ paddingLeft: '5px', paddingRight: '42px' }}
label="阴影"
onChange={e =>
{
CommandWrap(() =>
{
light.CaseShadow = !light.CaseShadow;
this.changeLightSettings('CaseShadow', lightData.CaseShadow);
}, "阴影显示/隐藏");
app.Viewer.UpdateRender();
lightData.CaseShadow = !lightData.CaseShadow;
}}
alignIndicator={Alignment.RIGHT}
/>
</div>
{
(this.props.lightType === BoardModalType.PointLight) ||
<div style={{ paddingLeft: '5px', display: 'flex', alignItems: 'center' }}>
<Label className="side-light-dir">:</Label>
<input
className={Classes.INPUT}
style={{ width: '137px', height: '22px' }}
value={this._Target}
disabled
/>
<div style={{ margin: '0px 5px' }}>
<Tooltip
content="选择照射方向"
position="top"
>
<Button
icon="select"
onClick={() => { this.handleSelectTarget(light, true); }}
className="light-select-target"
/>
</Tooltip>
</div>
</div>
}
<div className="flex" style={{ paddingLeft: '3px', marginTop: '5px' }}>
<Label style={{ float: "left", width: '33px', marginTop: '0' }}>:</Label>
<Popover
position={PopoverPosition.TOP}
minimal
onClose={(e) => { e.preventDefault(); }}
content={
<SketchPicker
color={lightData.Color.toUpperCase()}
onChange={async (e: ColorResult) =>
{
const KEY = '修改颜色';
if (CommandState.CommandIng)
{
if (app.Database.hm.UndoData.CommandName !== KEY)
{
await app.Editor.ModalManage.EndExecingCmd();
if (CommandState.CommandIng)
{
AppToaster.show({
message: "命令正在执行中!无法修改天光颜色!",
timeout: 5000,
intent: Intent.DANGER
});
return;
}
commandMachine.CommandStart(KEY);
}
} else
{
commandMachine.CommandStart(KEY);
}
this.props.store.currentSelectEnt.Color = new Color(e.hex.toString());
app.Viewer.UpdateRender();
this.SyncLight();
lightData.Color = e.hex;
this.changeLightSettings('Color', lightData.Color);
}}
onChangeComplete={() =>
{
const KEY = '修改颜色';
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
{
commandMachine.CommandEnd();
}
}}
/>
}>
<InputGroup
value={lightData.Color.toUpperCase()}
small
readOnly
className="light-panel-color layer-panel-input"
leftIcon={
<Icon
icon='stop'
size={20}
color={this.props.store.lightData["Color"]} />
}
/>
</Popover>
</div>
<div className="flex">
<Label style={{ float: "left", paddingLeft: '5px', width: '36px', marginTop: '0' }}>:</Label>
<Popover
position={Position.TOP_LEFT}
minimal
onClose={(e) => { e.preventDefault(); }}
>
<InputGroup
className="layer-panel-input"
readOnly
value={this.props.store.lightData.Temperature.toString() + 'K'}
/>
<div className='sun-colortemp'>
<img alt='色温' draggable={false} src={`${ResourcesCDN_HOST}/colortemperature.webp`} />
<Slider
min={1700}
max={12000}
stepSize={1}
labelStepSize={1775}
showTrackFill={false}
labelRenderer={() => (`${this.props.store.lightData.Temperature}K`)}
value={parseInt(this.props.store.lightData.Temperature)}
onChange={async (val) =>
{
const KEY = "修改射灯色温";
if (CommandState.CommandIng)
{
if (app.Database.hm.UndoData.CommandName !== KEY)
{
await app.Editor.ModalManage.EndExecingCmd();
AppToaster.show({
message: "命令正在执行中!无法修改射灯色温!",
timeout: 5000,
intent: Intent.DANGER,
});
return;
}
}
else
{
commandMachine.CommandStart(KEY);
}
this.props.store.currentSelectEnt.Temperature = val;
this.SyncLight();
app.Viewer.UpdateRender();
this.props.store.lightData.Temperature = val.toString();
this.changeLightSettings('Temperature', this.props.store.lightData.Temperature);
}}
onRelease={() =>
{
const KEY = "修改射灯色温";
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
commandMachine.CommandEnd();
}}
/>
</div>
</Popover>
</div>
{
this.props.store.pars.map(([k, v]) =>
{
let max: number = 200;
let min: number = 0;
let isFloat: boolean = false; //stepsize 是否为0.1
let scale: number = 1;
let noLim: boolean = false;//不限制最大值?
switch (k)
{
case "Intensity":
max = 200;
scale = 10;
break;
case "IndirectLightingIntensity":
max = 6;
scale = 1;
break;
case "Angle":
case "InnerConeAngle":
case "BarnDoorAngle":
max = 90;
scale = 1;
break;
case "SpecularScale":
max = 1;
isFloat = true;
scale = 1;
break;
case "SourceLength":
max = 100;
scale = 10;
break;
case "SourceRadius":
case "SoftSourceRadius":
max = 300;
scale = 1;
break;
case "AttenuationRadius":
min = 1;
max = 100;
scale = 10;
break;
case "Width":
case "Height":
min = 1;
max = 50;
noLim = true;
scale = 100;
break;
case "BarnDoorLength":
max = 100;
scale = 1;
break;
default:
break;
}
return <UseInputAndSlider
key={k}
pars={[k, v]}
store={this.props.store}
max={max}
min={min}
scale={scale}
isFloat={isFloat}
noLim={noLim}
lights={this.props.lights}
/>;
})
}
</div>
</div>
</div >
);
}
}
@observer
export class UseInputAndSlider extends React.Component<{ pars: string[], store: LightStore; max: number; isFloat: boolean; min: number; scale: number; noLim: boolean; lights: LightStore[]; }, {}>
{
OldData: number = 0;
private coolTime = new CoolDownTime;
_InputRef = React.createRef<NumericInput>();
private SyncLight()
{
if (userConfig.synchronousEnable)
this.coolTime.Debounce(() =>
{
app.WebSocket.Send(JSON.stringify(Entitys2Data([this.props.store.currentSelectEnt])));
}, 10);
}
handleLightDataUpdate(store: LightStore, value: string)
{
switch (this.props.pars[0])
{
case "InnerConeAngle":
store.lightData.InnerConeAngle = value;
store.currentSelectEnt[this.props.pars[0]] = parseFloat(value);
if (parseFloat(value) > parseFloat(store.lightData.Angle))
{
store.lightData.Angle = value;
store.currentSelectEnt["Angle"] = MathUtils.degToRad(parseFloat(value));
}
store.currentSelectEnt.Update();
break;
case "Angle":
store.lightData.Angle = value;
store.currentSelectEnt["Angle"] = MathUtils.degToRad(parseFloat(value));
if (parseFloat(value) < parseFloat(store.lightData.InnerConeAngle))
{
store.lightData.InnerConeAngle = value;
store.currentSelectEnt["InnerConeAngle"] = parseFloat(value);
}
store.currentSelectEnt.Update();
break;
case "SpecularScale":
store.lightData.SpecularScale = value;
store.currentSelectEnt.SpecularScale = parseFloat(value);
break;
default:
store.lightData[this.props.pars[0]] = value;
store.currentSelectEnt[this.props.pars[0]] = parseFloat(value);
break;
}
}
async SetValue(value: string)
{
const KEY = "修改灯光" + this.props.pars[1];;
if (CommandState.CommandIng)
{
if (app.Database.hm.UndoData.CommandName !== KEY)
{
await app.Editor.ModalManage.EndExecingCmd();
if (CommandState.CommandIng)
{
AppToaster.show({
message: "命令正在执行中!无法修改灯光" + this.props.pars[1] + "!",
timeout: 5000,
intent: Intent.DANGER,
});
return;
}
commandMachine.CommandStart(KEY);
}
} else
{
commandMachine.CommandStart(KEY);
}
this.handleLightDataUpdate(this.props.store, value);
this.changeLightSliderSettings(this.props.pars[0], this.props.store.lightData[this.props.pars[0]]);
this.SyncLight();
app.Editor.UpdateScreen();
}
changeLightSliderSettings = (propertyName, propertyValue) =>
{
for (const light of this.props.lights)
{
let targetLightData = light.lightData;
if (targetLightData.hasOwnProperty(propertyName))
{
this.handleLightDataUpdate(light, propertyValue);
}
}
};
render()
{
let store = this.props.store;
return (
<FormGroup className="side-light-panel">
<div className='inputslider side-light-input' style={{ marginBottom: '15px' }}>
{
["Height", "Width"].includes(this.props.pars[0]) ?
<Label className="side-light-width">
<div style={{ marginTop: -3, marginLeft: -24 }}>{this.props.pars[1]}:</div>
</Label> :
<Label style={{ float: "left", width: 70, marginTop: 1, textAlign: 'left', paddingLeft: '8px' }}>
{this.props.pars[1]}:
</Label>
}
<NumericInput
ref={this._InputRef}
tabIndex={1}
min={this.props.min * this.props.scale}
max={this.props.noLim ? 10e6 : this.props.max * this.props.scale}
buttonPosition={"none"}
value={this.props.store.lightData[this.props.pars[0]]}
allowNumericCharactersOnly
onKeyDown={(e) =>
{
if (e.keyCode === KeyBoard.Escape || e.keyCode === KeyBoard.Enter || e.keyCode === KeyBoard.Space)
{
this._InputRef.current.inputElement.blur();
}
e.stopPropagation();
}}
onValueChange={(numberValue, strValue, e) =>
{
let min = this.props.min * this.props.scale;
let max = this.props.noLim ? 1e7 : this.props.max * this.props.scale;
// 处理小数点 Data赋值不上传
if (numberValue >= min && numberValue < max && strValue === numberValue + ".")
{
this.props.store.lightData[this.props.pars[0]] = numberValue + ".";
return;
}
if (isNaN(numberValue) || numberValue > max) return;
if (numberValue < min)
{
this.props.store.lightData[this.props.pars[0]] = numberValue;
this.OldData = this.props.store.lightData[this.props.pars[0]];
return;
}
else
this.SetValue(FixedNotZero(numberValue, 1));
}}
onBlur={(e) =>
{
let min = this.props.min * this.props.scale;
if (e.currentTarget.value[e.currentTarget.value.length - 1] === ".")
{
this.props.store.lightData[this.props.pars[0]] = this.props.store.currentSelectEnt[this.props.pars[0]];
}
if (this.props.store.lightData[this.props.pars[0]] < min)
{
if (this.OldData === this.props.store.currentSelectEnt[this.props.pars[0]])
{
this.props.store.lightData[this.props.pars[0]] = this.props.store.currentSelectEnt[this.props.pars[0]];
return;
}
this.SetValue(FixedNotZero(min, 1));
}
const KEY = '修改灯光' + this.props.pars[1];
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
{
commandMachine.CommandEnd();
}
}}
onFocus={(e) =>
{
e.target.select();
}}
/>
<div style={{ marginLeft: -133, }}>
<Slider
className="side-light-container"
min={this.props.min}
max={this.props.max}
stepSize={this.props.isFloat ? 0.1 : 1}
value={parseFloat(store.lightData[this.props.pars[0]]) / this.props.scale > this.props.max ? this.props.max : parseFloat(store.lightData[this.props.pars[0]]) / this.props.scale}
onChange={(e) =>
{
e = e * this.props.scale;
let coolTime = new CoolDownTime;
coolTime.Debounce(() =>
{
this.SetValue((FixedNotZero(e, this.props.isFloat ? 1 : 0)));
}, 0);
}}
onRelease={() =>
{
let coolTime = new CoolDownTime;
coolTime.Debounce(() =>
{
const KEY = '修改灯光' + this.props.pars[1];
if (CommandState.CommandIng && app.Database.hm.UndoData.CommandName === KEY)
{
commandMachine.CommandEnd();
}
}, 50);
}}
/>
</div>
</div>
</FormGroup>
);
}
}

@ -0,0 +1,148 @@
#SpotLightModel {
width: 310px;
font-size: 13px;
.bp3-dialog-body {
padding: 5px;
.bp3-control.bp3-switch.bp3-align-right {
padding-left: 24px;
padding-right: 47px;
}
>div {
height: 32px;
}
input {
width: 100px;
height: 27px;
}
.bp3-label.side-light-dir {
float: left;
width: 34px;
margin-top: 9px;
text-align: center;
}
.side-light-width.bp3-label {
width: 68px;
}
.bp3-label .bp3-popover-wrapper {
margin: 0;
width: 16px;
height: 16px;
.checkbox {
margin: 0 0 0 5px;
}
}
.bp3-form-group {
margin: 0;
}
.bp3-form-group.side-light-panel {
margin-bottom: 18px;
}
.bp3-input-group.bp3-disabled.bp3-small.bp3-inline {
width: 130px;
}
.bp3-popover-wrapper {
.light-panel-color {
.bp3-icon.bp3-icon-stop {
margin-top: 1px;
}
}
.bp3-icon.bp3-icon-stop {
margin-left: 13px;
margin-top: 4px;
}
.layer-panel-input .bp3-input {
width: 164px;
height: 22px;
margin-left: 4px;
text-indent: 18px;
}
}
.bp3-control-group.bp3-numeric-input {
float: left;
.bp3-input {
height: 27px;
width: 50px;
margin-left: 0;
padding: 10px;
}
}
.side-light-input {
.bp3-control-group.bp3-numeric-input {
.bp3-input {
height: 22px;
width: 133px;
}
}
}
.lg-pos {
.bp3-button {
height: 30px;
}
}
.bp3-slider {
min-width: none;
width: 130px;
height: auto;
position: absolute;
margin-top: 5px;
margin-left: 140px;
.bp3-slider-axis {
display: none;
}
.bp3-slider-handle {
.bp3-slider-label {
display: none;
}
}
}
.bp3-slider.side-light-container {
margin-top: 30px;
min-width: 188px;
}
.bp3-list.bp3-list-unstyled {
.pos {
display: flex;
}
}
.light-select-target.bp3-button {
min-height: 20px;
min-width: 20px;
span.bp3-icon {
margin: -2px -7px;
}
}
}
.bp3-dialog-footer {
padding: 7px 10px 7px 15px;
border-top: 1px solid #dddddd;
background-color: white;
}
}

@ -594,3 +594,11 @@
}
}
}
.light-slider.bp3-dialog-body .bp3-slider {
min-width: none;
width: 130px;
height: auto;
position: absolute;
margin-top: 5px;
}

@ -1,19 +1,21 @@
.properties {
width: 230px;
.bp3-card {
padding: 5px;
height : 100%;
height: 100%;
.header {
span {
font-size : 12px;
font-size: 12px;
font-weight: 600;
}
margin : 5px 0;
display : flex;
margin : 5px 0;
display : flex;
justify-content: space-between;
padding : 0 5px;
align-items : center;
padding : 0 5px;
align-items : center;
}
.select {
@ -21,9 +23,9 @@
width: 100%;
select {
height : 2.0rem;
height: 2.0rem;
line-height: 2.0rem;
min-height : 2.0rem;
min-height: 2.0rem;
}
>span {
@ -43,8 +45,32 @@
.li-title {
display: block;
padding: 5px;
margin : 5px 0;
width : 100%;
margin: 5px 0;
width: 100%;
}
.light-box {
display: inline-block;
height: 600px;
overflow: auto;
}
td {
border: 1px solid #ccc;
}
.pers-td {
border: 1px solid #ccc;
white-space: nowrap;
padding: 3px;
min-width: 40px;
text-align: center;
}
.first-tr {
td {
border-top: none;
}
}
>li {
@ -52,31 +78,42 @@
}
.color {
margin : 5px 0 0 0 !important;
width : 100% !important;
margin: 5px 0 0 0 !important;
width: 100% !important;
display: flex;
>label {
width : 20%;
margin-top : 2px;
width: 40px;
text-align: center;
border: 1px solid #ccc;
border-right: none;
padding: 2px;
}
>ul {
width: 100% !important;
width: 120px !important;
border: 1px solid #ccc;
.props-color {
display : flex;
justify-content: space-between;
border : 1px ridge transparent;
position: relative;
width: 100%;
display: inline-block;
border: 1px ridge transparent;
.bp3-icon {
position: absolute;
right: 0;
}
&:hover {
border : 1px ridge #8A9BA8;
border: 1px ridge #8A9BA8;
background: #BFCCD6;
cursor : pointer;
cursor: pointer;
}
>li {
pointer-events: none;
display: inline-block;
}
}
@ -87,7 +124,7 @@
>ul {
//.props-color-list
outline : none;
outline: none;
background: none !important;
>li {
@ -109,10 +146,10 @@
.outline {
div {
width : 100%;
display : flex;
width: 100%;
display: flex;
justify-content: space-between;
align-items : center;
align-items: center;
}
}
@ -130,7 +167,7 @@
}
}
display : flex;
display : flex;
justify-content: space-between;
}
}
@ -139,24 +176,24 @@
display: flex;
>span {
width : 70%;
margin : auto 0;
width: 70%;
margin: auto 0;
align-items: center;
}
}
.leadLength-editor{
.paramPanel{
.leadLength-editor {
.paramPanel {
&:hover {
background: #E1E8ED;
cursor : pointer;
cursor: pointer;
}
margin-top: 10px;
}
.input_group{
display : flex;
.input_group {
display: flex;
justify-content: space-between;
.numeric_input {
@ -165,22 +202,34 @@
}
}
.bp3-slider.bp3-slider-unlabeled{
.bp3-slider.bp3-slider-unlabeled {
margin-top: 5px;
}
.bp3-intent-warning{
.bp3-intent-warning {
width: 100%;
}
}
}
}
.light-container {
width: auto;
overflow: auto;
.li-title {
display: block;
padding: 5px;
margin: 5px 0;
width: 100%;
}
}
}
}
#PropertiesBtn {
>button {
background : #fff;
transform : perspective(3em) rotateY(40deg);
background: #fff;
transform: perspective(3em) rotateY(40deg);
border-radius: 0 10px 10px 0;
margin-bottom: 30%;
}
@ -188,24 +237,24 @@
.bp3-button.bp3-small {
&.iconTransBtn {
>span {
transform : rotate(-90deg);
transform: rotate(-90deg);
-webkit-transition: transform .25s linear;
-moz-transition : transform .25s linear;
-o-transition : transform .25s linear;
transition : transform .25s linear;
-moz-transition: transform .25s linear;
-o-transition: transform .25s linear;
transition: transform .25s linear;
}
}
border-radius: 0 3px 3px 0;
min-height : 30px;
padding : 5px 5px 5px 0;
min-height : 30px;
padding : 5px 5px 5px 0;
>span {
transform : rotate(90deg);
transform: rotate(90deg);
-webkit-transition: transform .25s linear;
-moz-transition : transform .25s linear;
-o-transition : transform .25s linear;
transition : transform .25s linear;
-moz-transition: transform .25s linear;
-o-transition: transform .25s linear;
transition: transform .25s linear;
}
}
}

@ -1,11 +1,15 @@
import { Button, Card, Classes, HTMLSelect } from "@blueprintjs/core";
import { observer } from "mobx-react";
import React from "react";
import { LightBoxModel } from "../../../Add-on/DrawLight/LightBoxModal";
import { app } from "../../../ApplicationServices/Application";
import { DimStyleRecord } from "../../../DatabaseServices/DimStyle/DimStyleRecord";
import { AlignedDimension } from "../../../DatabaseServices/Dimension/AlignedDimension";
import { Dimension } from "../../../DatabaseServices/Dimension/Dimension";
import { Entity } from "../../../DatabaseServices/Entity/Entity";
import { PointLight } from "../../../DatabaseServices/Lights/PointLight";
import { RectAreaLight } from "../../../DatabaseServices/Lights/RectAreaLight";
import { SpotLight } from "../../../DatabaseServices/Lights/SpotLight";
import { Text } from "../../../DatabaseServices/Text/Text";
import { CommandWrap } from "../../../Editor/CommandMachine";
import { DownPanelStore } from "../../Store/DownPanelStore";
@ -150,7 +154,20 @@ export class PropertiesPanel extends React.Component<{}, {}>
<li className="color">
<ColorModal store={store} />
</li>
{pers.map(p => <li>{p}</li>)}
<table style={{ borderCollapse: 'collapse' }}>
<tbody>
{pers.map((p, index) =>
{
const parts = p.split(':');
return (
<tr className={`${index === 0 ? "first-tr" : ""}`}>
<td className="pers-td">{parts[0]}</td>
<td>{parts[1]}</td>
</tr>
);
})}
</tbody>
</table>
{
ents[0] instanceof AlignedDimension &&
<>
@ -199,6 +216,18 @@ export class PropertiesPanel extends React.Component<{}, {}>
</li>
</>
}
{(ents[0] instanceof PointLight ||
(ents[0] instanceof RectAreaLight || ents[0] instanceof SpotLight))
&&
<div >
<span className="li-title">
{ents.length > 1 ? '灯光设置(批量设置)' : '灯光设置'}
</span>
<div className="light-box">
<LightBoxModel store={store} />
</div>
</div>
}
</>
}
</ul>

@ -23,6 +23,7 @@ export class EntityStore extends Singleton
@action
AddEntitysToMap(ens: Entity[])
{
this.enMap.clear();
for (let en of ens)
{
let type: string = "";

@ -16,7 +16,7 @@ import { DirectionalLight } from "../../../DatabaseServices/Lights/DirectionalLi
import { Light } from "../../../DatabaseServices/Lights/Light";
import { RectAreaLight } from "../../../DatabaseServices/Lights/RectAreaLight";
import { SpotLight } from "../../../DatabaseServices/Lights/SpotLight";
import { commandMachine, CommandWrap } from "../../../Editor/CommandMachine";
import { CommandWrap, commandMachine } from "../../../Editor/CommandMachine";
import { CommandState } from "../../../Editor/CommandState";
import { PromptStatus } from "../../../Editor/PromptResult";
import { userConfig } from "../../../Editor/UserConfig";
@ -146,6 +146,11 @@ export class LightConfigModel extends React.Component<LightConfigModelProps, {}>
{
light.ShowHelper = !light.ShowHelper;
}, "灯光助手显示/隐藏");
else
{
light.ShowHelper = !light.ShowHelper;
app.Viewer.UpdateRender();
}
lightData.ShowHelper = !lightData.ShowHelper;
}}
alignIndicator={Alignment.RIGHT}

Loading…
Cancel
Save