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

fix(ui): edge case where entity isn't visible until interacting with canvas #7099

Merged
merged 2 commits into from
Oct 11, 2024
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 @@ -16,7 +16,8 @@ import {
selectIsolatedTransformingPreview,
} from 'features/controlLayers/store/canvasSettingsSlice';
import {
buildEntityIsHiddenSelector,
buildSelectIsHidden,
buildSelectIsSelected,
selectBboxRect,
selectCanvasSlice,
selectEntity,
Expand Down Expand Up @@ -165,6 +166,7 @@ export abstract class CanvasEntityAdapterBase<
};

selectIsHidden: Selector<RootState, boolean>;
selectIsSelected: Selector<RootState, boolean>;

/**
* The Konva nodes that make up the entity adapter:
Expand Down Expand Up @@ -248,7 +250,8 @@ export abstract class CanvasEntityAdapterBase<
assert(state !== undefined, 'Missing entity state on creation');
this.state = state;

this.selectIsHidden = buildEntityIsHiddenSelector(this.entityIdentifier);
this.selectIsHidden = buildSelectIsHidden(this.entityIdentifier);
this.selectIsSelected = buildSelectIsSelected(this.entityIdentifier);

/**
* There are a number of reason we may need to show or hide a layer:
Expand All @@ -257,6 +260,7 @@ export abstract class CanvasEntityAdapterBase<
* - Staging status changes and `isolatedStagingPreview` is enabled
* - Global filtering status changes and `isolatedFilteringPreview` is enabled
* - Global transforming status changes and `isolatedTransformingPreview` is enabled
* - The entity is selected or deselected (only selected and onscreen entities are rendered)
*/
this.subscriptions.add(this.manager.stateApi.createStoreSubscription(this.selectIsHidden, this.syncVisibility));
this.subscriptions.add(
Expand All @@ -267,6 +271,7 @@ export abstract class CanvasEntityAdapterBase<
this.manager.stateApi.createStoreSubscription(selectIsolatedTransformingPreview, this.syncVisibility)
);
this.subscriptions.add(this.manager.stateApi.$transformingAdapter.listen(this.syncVisibility));
this.subscriptions.add(this.manager.stateApi.createStoreSubscription(this.selectIsSelected, this.syncVisibility));

/**
* The tool preview may need to be updated when the entity is locked or disabled. For example, when we disable the
Expand Down Expand Up @@ -305,21 +310,8 @@ export abstract class CanvasEntityAdapterBase<

syncIsOnscreen = () => {
const stageRect = this.manager.stage.getScaledStageRect();
const entityRect = this.transformer.$pixelRect.get();
const position = this.manager.stateApi.runSelector(this.selectPosition);
if (!position) {
return;
}
const entityRectRelativeToStage = {
x: entityRect.x + position.x,
y: entityRect.y + position.y,
width: entityRect.width,
height: entityRect.height,
};

const intersection = getRectIntersection(stageRect, entityRectRelativeToStage);
const isOnScreen = this.checkIntersection(stageRect);
const prevIsOnScreen = this.$isOnScreen.get();
const isOnScreen = intersection.width > 0 && intersection.height > 0;
this.$isOnScreen.set(isOnScreen);
if (prevIsOnScreen !== isOnScreen) {
this.log.trace(`Moved ${isOnScreen ? 'on-screen' : 'off-screen'}`);
Expand All @@ -329,25 +321,29 @@ export abstract class CanvasEntityAdapterBase<

syncIntersectsBbox = () => {
const bboxRect = this.manager.stateApi.getBbox().rect;
const intersectsBbox = this.checkIntersection(bboxRect);
const prevIntersectsBbox = this.$intersectsBbox.get();
this.$intersectsBbox.set(intersectsBbox);
if (prevIntersectsBbox !== intersectsBbox) {
this.log.trace(`Moved ${intersectsBbox ? 'into bbox' : 'out of bbox'}`);
}
};

checkIntersection = (rect: Rect): boolean => {
const entityRect = this.transformer.$pixelRect.get();
const position = this.manager.stateApi.runSelector(this.selectPosition);
if (!position) {
return;
return false;
}
const entityRectRelativeToStage = {
x: entityRect.x + position.x,
y: entityRect.y + position.y,
width: entityRect.width,
height: entityRect.height,
};

const intersection = getRectIntersection(bboxRect, entityRectRelativeToStage);
const prevIntersectsBbox = this.$intersectsBbox.get();
const intersectsBbox = intersection.width > 0 && intersection.height > 0;
this.$intersectsBbox.set(intersectsBbox);
if (prevIntersectsBbox !== intersectsBbox) {
this.log.trace(`Moved ${intersectsBbox ? 'into bbox' : 'out of bbox'}`);
}
const intersection = getRectIntersection(rect, entityRectRelativeToStage);
const doesIntersect = intersection.width > 0 && intersection.height > 0;
return doesIntersect;
};

initialize = async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ const getSelectIsTypeHidden = (type: CanvasEntityType) => {
/**
* Builds a selector taht selects if the entity is hidden.
*/
export const buildEntityIsHiddenSelector = (entityIdentifier: CanvasEntityIdentifier) => {
export const buildSelectIsHidden = (entityIdentifier: CanvasEntityIdentifier) => {
const selectIsTypeHidden = getSelectIsTypeHidden(entityIdentifier.type);
return createSelector(
[selectCanvasSlice, selectIsTypeHidden, selectIsStaging, selectIsolatedStagingPreview],
Expand Down Expand Up @@ -339,6 +339,16 @@ export const buildEntityIsHiddenSelector = (entityIdentifier: CanvasEntityIdenti
);
};

/**
* Builds a selector taht selects if the entity is selected.
*/
export const buildSelectIsSelected = (entityIdentifier: CanvasEntityIdentifier) => {
return createSelector(
selectSelectedEntityIdentifier,
(selectedEntityIdentifier) => selectedEntityIdentifier?.id === entityIdentifier.id
);
};

export const selectWidth = createSelector(selectCanvasSlice, (canvas) => canvas.bbox.rect.width);
export const selectHeight = createSelector(selectCanvasSlice, (canvas) => canvas.bbox.rect.height);
export const selectAspectRatioID = createSelector(selectCanvasSlice, (canvas) => canvas.bbox.aspectRatio.id);
Expand Down
Loading