Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selection boxes keep the same border thickness as the scale changes #19

Merged
merged 1 commit into from
Jul 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ImageLayerFactory } from './image-layer/ImageLayerFactory';
import { DefaultCanvasState } from './DefaultCanvasState';
import { CanvasEngineListener } from '@projectstorm/react-canvas-core';
import { ConceptCanvasModel } from './ConceptCanvasModel';
import { ControlsLayerFactory } from './controls-layer/ControlsLayerFactory';

export class ConceptCanvasEngine extends CanvasEngine<CanvasEngineListener, ConceptCanvasModel> {
elementBank: FactoryBank<ImageElementFactory>;
Expand All @@ -26,6 +27,8 @@ export class ConceptCanvasEngine extends CanvasEngine<CanvasEngineListener, Conc

this.getLayerFactories().registerFactory(new SelectionBoxLayerFactory());
this.getLayerFactories().registerFactory(new ImageLayerFactory());
this.getLayerFactories().registerFactory(new ControlsLayerFactory());

this.getStateMachine().pushState(new DefaultCanvasState());

// @ts-ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import * as _ from 'lodash';
import { ImageElement } from './image-element/ImageElementFactory';
import { action } from 'mobx';
import { FileData } from '@projectstorm/tornado-common';
import { ControlsLayerModel } from './controls-layer/ControlsLayerFactory';

export class ConceptCanvasModel extends CanvasModel {
constructor(public model: ConceptBoardModel) {
super();

const layer = new ImageLayerModel();
this.addLayer(layer);
this.addLayer(new ImageLayerModel());
this.addLayer(new ControlsLayerModel());
}

load(engine: CanvasEngine) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as React from 'react';
import { ImageElement } from '../image-element/ImageElementFactory';
import { styled } from '../../../../../theme/theme';
import { useForceUpdate } from '../../../../../hooks/useForceUpdate';
import { useEffect } from 'react';
import { ImageLayerModel } from '../image-layer/ImageLayerFactory';

export interface ControlsElementWidgetProps {
model: ImageElement;
}

export const ControlsElementWidget: React.FC<ControlsElementWidgetProps> = (props) => {
const forceUpdate = useForceUpdate();
useEffect(() => {
const l = props.model.registerListener({
selectionChanged: () => {
forceUpdate();
}
});
return l.deregister;
}, []);
if (!props.model.isSelected()) {
return null;
}

const canvas = (props.model.getParent() as ImageLayerModel).getParent();
const zoom = canvas.getZoomLevel() / 100;

return (
<S.Container
style={{
left: props.model.getX() * zoom + canvas.getOffsetX(),
top: props.model.getY() * zoom + canvas.getOffsetY(),
width: props.model.width * zoom,
height: props.model.height * zoom
}}
/>
);
};
namespace S {
export const Container = styled.div`
position: absolute;
border: solid 2px ${(p) => p.theme.editor.selected};
box-shadow: 0 0 20px ${(p) => p.theme.editor.selectedShadow};
box-sizing: border-box;
pointer-events: none;
`;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as React from 'react';
import {
AbstractReactFactory,
FactoryBank,
GenerateModelEvent,
GenerateWidgetEvent,
LayerModel,
LayerModelGenerics
} from '@projectstorm/react-canvas-core';
import { ImageElement, ImageElementFactory } from '../image-element/ImageElementFactory';
import * as _ from 'lodash';
import { ConceptCanvasEngine } from '../ConceptCanvasEngine';
import { ConceptCanvasModel } from '../ConceptCanvasModel';
import { ControlsElementWidget } from './ControlsElementWidget';

export class ControlsLayerFactory extends AbstractReactFactory<ControlsLayerModel, ConceptCanvasEngine> {
static TYPE = 'concept/controls/layer';

constructor() {
super(ControlsLayerFactory.TYPE);
}

generateModel(event: GenerateModelEvent): ControlsLayerModel {
return new ControlsLayerModel();
}

generateReactWidget(event: GenerateWidgetEvent<ControlsLayerModel>): JSX.Element {
return (
<>
{_.map(event.model.getParent().getLayers()[0].getModels(), (m: ImageElement) => {
return <ControlsElementWidget model={m} key={m.getID()} />;
})}
</>
);
}
}

export type ControlsLayerGenerics = LayerModelGenerics & {
ENGINE: ConceptCanvasEngine;
PARENT: ConceptCanvasModel;
};

export class ControlsLayerModel extends LayerModel<ControlsLayerGenerics> {
constructor() {
super({
type: ControlsLayerFactory.TYPE,
transformed: false
});
}

getChildModelFactoryBank(engine: ControlsLayerGenerics['ENGINE']): FactoryBank<ImageElementFactory> {
return engine.elementBank;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,9 @@ export interface ImageElementWidgetProps {
}

export const ImageElementWidget: React.FC<ImageElementWidgetProps> = (props) => {
const forceUpdate = useForceUpdate();
useEffect(() => {
const l = props.model.registerListener({
selectionChanged: () => {
forceUpdate();
}
});
return l.deregister;
}, []);

return (
<S.Container
data-imageid={props.model.getID()}
selected={props.model.isSelected()}
style={{
left: props.model.getX(),
top: props.model.getY(),
Expand All @@ -36,10 +25,8 @@ export const ImageElementWidget: React.FC<ImageElementWidgetProps> = (props) =>
);
};
namespace S {
export const Container = styled.div<{ selected: boolean }>`
export const Container = styled.div`
position: absolute;
border: solid 2px ${(p) => (p.selected ? p.theme.editor.selected : 'transparent')};
${(p) => (p.selected ? `box-shadow: 0 0 20px ${p.theme.editor.selectedShadow}` : '')};
box-sizing: border-box;
pointer-events: all;
`;
Expand Down