Implement basic selector + fix text position
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
42cd768cf4
commit
7236fc85bf
4 changed files with 59 additions and 7 deletions
|
@ -228,7 +228,7 @@ class App extends React.Component<IAppProps> {
|
||||||
selectContainer={(container: Container) => this.SelectContainer(container)}
|
selectContainer={(container: Container) => this.SelectContainer(container)}
|
||||||
/>
|
/>
|
||||||
<button className='fixed z-10 top-4 right-12 text-lg bg-slate-200 hover:bg-slate-300 transition-all drop-shadow-md hover:drop-shadow-lg py-2 px-3 rounded-lg' onClick={() => this.ToggleElementsSidebar()}>☰ Elements</button>
|
<button className='fixed z-10 top-4 right-12 text-lg bg-slate-200 hover:bg-slate-300 transition-all drop-shadow-md hover:drop-shadow-lg py-2 px-3 rounded-lg' onClick={() => this.ToggleElementsSidebar()}>☰ Elements</button>
|
||||||
<SVG>
|
<SVG selected={this.state.SelectedContainer}>
|
||||||
{ this.state.MainContainer }
|
{ this.state.MainContainer }
|
||||||
</SVG>
|
</SVG>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,9 +14,6 @@ interface IContainerProps {
|
||||||
const GAP = 50;
|
const GAP = 50;
|
||||||
|
|
||||||
export class Container extends React.Component<IContainerProps> {
|
export class Container extends React.Component<IContainerProps> {
|
||||||
componentWillUnMount() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public GetProperties(): Properties {
|
public GetProperties(): Properties {
|
||||||
const properties : Properties = {
|
const properties : Properties = {
|
||||||
...this.props.properties
|
...this.props.properties
|
||||||
|
@ -55,10 +52,22 @@ export class Container extends React.Component<IContainerProps> {
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getAbsolutePosition(): [number, number] {
|
||||||
|
let x = Number(this.props.properties.x);
|
||||||
|
let y = Number(this.props.properties.y);
|
||||||
|
let current = this.props.parent;
|
||||||
|
while (current != null) {
|
||||||
|
x += Number(current.props.properties.x);
|
||||||
|
y += Number(current.props.properties.y);
|
||||||
|
current = current.props.parent;
|
||||||
|
}
|
||||||
|
return [x, y];
|
||||||
|
}
|
||||||
|
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const containersElements = this.props.children.map(child => child.render());
|
const containersElements = this.props.children.map(child => child.render());
|
||||||
const xText = (this.props.properties.x * 2 + Number(this.props.properties.width)) / 2;
|
const xText = Number(this.props.properties.width) / 2;
|
||||||
const yText = (this.props.properties.y * 2 + Number(this.props.properties.height)) / 2;
|
const yText = Number(this.props.properties.height) / 2;
|
||||||
|
|
||||||
// g style
|
// g style
|
||||||
const defaultStyle = {
|
const defaultStyle = {
|
||||||
|
|
41
src/Components/SVG/Elements/Selector.tsx
Normal file
41
src/Components/SVG/Elements/Selector.tsx
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Container } from './Container';
|
||||||
|
|
||||||
|
interface ISelectorProps {
|
||||||
|
selected: Container | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Selector: React.FC<ISelectorProps> = (props) => {
|
||||||
|
if (props.selected === undefined || props.selected === null) {
|
||||||
|
return (
|
||||||
|
<rect visibility={'hidden'}>
|
||||||
|
</rect>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [x, y] = props.selected.getAbsolutePosition();
|
||||||
|
const [width, height] = [
|
||||||
|
props.selected.props.properties.width,
|
||||||
|
props.selected.props.properties.height
|
||||||
|
];
|
||||||
|
const style = {
|
||||||
|
strokeDasharray: '8, 10',
|
||||||
|
stroke: '#3B82F6', // tw blue-500
|
||||||
|
strokeWidth: 4,
|
||||||
|
fillOpacity: 0,
|
||||||
|
transitionProperty: 'all',
|
||||||
|
transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||||
|
transitionDuration: '150ms'
|
||||||
|
} as React.CSSProperties;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<rect
|
||||||
|
x={x}
|
||||||
|
y={y}
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
style={style}
|
||||||
|
>
|
||||||
|
</rect>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,10 +1,11 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { ReactSVGPanZoom, Tool, Value, TOOL_PAN } from 'react-svg-pan-zoom';
|
import { ReactSVGPanZoom, Tool, Value, TOOL_PAN } from 'react-svg-pan-zoom';
|
||||||
import { Container } from './Elements/Container';
|
import { Container } from './Elements/Container';
|
||||||
import { DimensionLayer } from './Elements/DimensionLayer';
|
import { Selector } from './Elements/Selector';
|
||||||
|
|
||||||
interface ISVGProps {
|
interface ISVGProps {
|
||||||
children: Container | Container[] | null,
|
children: Container | Container[] | null,
|
||||||
|
selected: Container | null
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ISVGState {
|
interface ISVGState {
|
||||||
|
@ -80,6 +81,7 @@ export class SVG extends React.Component<ISVGProps> {
|
||||||
>
|
>
|
||||||
<svg ref={this.svg} {...properties}>
|
<svg ref={this.svg} {...properties}>
|
||||||
{ children }
|
{ children }
|
||||||
|
<Selector selected={this.props.selected} />
|
||||||
</svg>
|
</svg>
|
||||||
</ReactSVGPanZoom>
|
</ReactSVGPanZoom>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue