Skip to content

Commit

Permalink
Climbing: Bug fixes in ClimbingEditor (#792)
Browse files Browse the repository at this point in the history
  • Loading branch information
jvaclavik authored Nov 20, 2024
1 parent 1afd3ea commit 4d81758
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 76 deletions.
3 changes: 3 additions & 0 deletions src/components/FeaturePanel/Climbing/ClimbingView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import MapIcon from '@mui/icons-material/Map';
import EditIcon from '@mui/icons-material/Edit';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import { useGetCragViewLayout } from './utils/useCragViewLayout';
import { RouteFloatingMenu } from './Editor/RouteFloatingMenu';

export const DEFAULT_CRAG_VIEW_LAYOUT = 'horizontal';

Expand Down Expand Up @@ -483,6 +484,7 @@ export const ClimbingView = ({ photo }: { photo?: string }) => {
</FullLoadingContainer>
)}
<BlurContainer>
<RouteFloatingMenu />
<TransformWrapper>
<TransformComponent
wrapperStyle={{ height: '100%', width: '100%' }}
Expand All @@ -501,6 +503,7 @@ export const ClimbingView = ({ photo }: { photo?: string }) => {
</>
</TransformComponent>
</TransformWrapper>

{isEditMode && <ControlPanel />}
</BlurContainer>
</>
Expand Down
7 changes: 5 additions & 2 deletions src/components/FeaturePanel/Climbing/Editor/Points/Point.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const Point = ({
setRouteIndexHovered,
photoZoom,
getCurrentPath,
setIsPanningDisabled,
} = useClimbingContext();
const isMobileMode = useMobileMode();
const isPointSelected =
Expand All @@ -84,15 +85,17 @@ export const Point = ({
};

const onMouseDown = (e) => {
setIsPanningDisabled(true);
setPointSelectedIndex(index);
setIsPointClicked(true);
e.preventDefault();
e.stopPropagation();
};

const onMouseUp = (e) => {
// @TODO unify with RouteMarks.tsx
if (!isPointMoving) {
setPointSelectedIndex(null);
setIsPanningDisabled(false);
onPointInSelectedRouteClick(e);
setPointElement(pointElement !== null ? null : e.currentTarget);
setPointSelectedIndex(index);
Expand Down Expand Up @@ -133,7 +136,7 @@ export const Point = ({
<PointElement
fill={pointColor}
stroke={pointStroke}
r={isTouchDevice ? 5 : 3}
r={isTouchDevice ? 7 : 4}
$isHovered={isHovered}
$isPointSelected={isPointSelected}
{...commonProps}
Expand Down
20 changes: 10 additions & 10 deletions src/components/FeaturePanel/Climbing/Editor/RouteFloatingMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ import {
import { useClimbingContext } from '../contexts/ClimbingContext';
import { PointType } from '../types';

const ScaleContainer = styled.div<{ $scale: number }>`
transform: scale(${({ $scale }) => 1 / $scale});
const Container = styled.div`
position: absolute;
z-index: 1;
bottom: 16px;
right: 16px;
`;

export const RouteFloatingMenu = () => {
Expand All @@ -31,7 +34,6 @@ export const RouteFloatingMenu = () => {
routes,
routeSelectedIndex,
getCurrentPath,
photoZoom,
setRouteIndexHovered,
} = useClimbingContext();

Expand Down Expand Up @@ -122,8 +124,8 @@ export const RouteFloatingMenu = () => {
</DialogActions>
</Dialog>

{showTypeMenu ? (
<ScaleContainer $scale={photoZoom.scale}>
<Container>
{showTypeMenu ? (
<ButtonGroup variant="contained" size="small" color="primary">
<Button
onClick={() => {
Expand Down Expand Up @@ -174,9 +176,7 @@ export const RouteFloatingMenu = () => {
None
</Button>
</ButtonGroup>
</ScaleContainer>
) : (
<ScaleContainer $scale={photoZoom.scale}>
) : (
<ButtonGroup variant="contained" size="small" color="primary">
{machine.currentStateName === 'pointMenu' &&
routes[routeSelectedIndex] &&
Expand Down Expand Up @@ -216,8 +216,8 @@ export const RouteFloatingMenu = () => {
</Button>
)}
</ButtonGroup>
</ScaleContainer>
)}
)}
</Container>
</>
);
};
7 changes: 4 additions & 3 deletions src/components/FeaturePanel/Climbing/Editor/RoutePath.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const RoutePath = ({ route, routeNumber }) => {
routeIndexHovered,
setRouteIndexHovered,
getPathForRoute,
photoRef,
svgRef,
photoZoom,
} = useClimbingContext();
const isSelected = isRouteSelected(routeNumber);
Expand Down Expand Up @@ -62,7 +62,7 @@ export const RoutePath = ({ route, routeNumber }) => {
units: 'px',
};
const positionInImage = getPositionInImageFromMouse(
photoRef,
svgRef,
mousePosition,
photoZoom,
);
Expand Down Expand Up @@ -171,7 +171,8 @@ export const RoutePath = ({ route, routeNumber }) => {
cy={tempPointPosition.y}
fill="white"
stroke="rgba(0,0,0,0.3)"
r={5}
r={7 / photoZoom.scale}
strokeWidth={1 / photoZoom.scale}
/>
)}
{machine.currentStateName === 'extendRoute' &&
Expand Down
11 changes: 8 additions & 3 deletions src/components/FeaturePanel/Climbing/Editor/RoutesEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import { RoutesLayer } from './RoutesLayer';
import { useClimbingContext } from '../contexts/ClimbingContext';
import { updateElementOnIndex } from '../utils/array';
import { PositionPx } from '../types';
import { getPositionInImageFromMouse } from '../utils/mousePositionUtils';
import {
getMouseFromPositionInImage,
getPositionInImageFromMouse,
} from '../utils/mousePositionUtils';
import { getCommonsImageUrl } from '../../../../services/images/getCommonsImageUrl';
import { isMobileDevice } from '../../../helpers';
import { RouteFloatingMenu } from './RouteFloatingMenu';

const EditorContainer = styled.div<{ imageHeight: number }>`
display: flex;
Expand All @@ -33,7 +37,7 @@ const ImageContainer = styled.div`
`;

const ImageElement = styled.img<{ zoom?: number }>`
object-fit: contain;
object-fit: contain; // @TODO try to delete this
max-width: 100%;
transition: all 0.1s ease-in;
height: 100%;
Expand Down Expand Up @@ -61,6 +65,7 @@ export const RoutesEditor = ({
loadPhotoRelatedData,
loadedPhotos,
photoRef,
svgRef,
photoPath,
setLoadedPhotos,
photoZoom,
Expand Down Expand Up @@ -117,7 +122,7 @@ export const RoutesEditor = ({
units: 'px',
};
const positionInImage = getPositionInImageFromMouse(
photoRef,
svgRef,
mousePosition,
photoZoom,
);
Expand Down
69 changes: 23 additions & 46 deletions src/components/FeaturePanel/Climbing/Editor/RoutesLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ const Svg = styled.svg<{
`}
`;

const RouteFloatingMenuContainer = styled.div<{ $x: number; $y: number }>`
position: absolute;
left: ${({ $x }) => $x}px;
top: ${({ $y }) => $y}px;
z-index: 10000;
`;
type Props = {
onClick: (e: any) => void;
onEditorMouseMove?: (e: any) => void;
Expand Down Expand Up @@ -71,8 +65,8 @@ export const RoutesLayer = ({
setPointSelectedIndex,
getCurrentPath,
routes,
photoRef,
photoZoom,
svgRef,
} = useClimbingContext();

const machine = getMachine();
Expand Down Expand Up @@ -167,45 +161,28 @@ export const RoutesLayer = ({
? selectedPointOfSelectedRoute
: lastPointOfSelectedRoute;

// TODO this position doesnt work well when zoomed
const absolutePositionFromScreen = getMouseFromPositionInImage(
photoRef,
routeFloatingMenuPosition,
photoZoom,
);

return (
<>
<Svg
$hasEditableCursor={machine.currentStateName === 'extendRoute'}
onClick={(e) => {
onClick(e);
}}
onMouseUp={handleMovingPointDrop}
onMouseMove={onEditorMouseMove}
onTouchMove={onEditorTouchMove}
onPointerMove={onEditorTouchMove}
$imageSize={imageSize}
$isVisible={isVisible}
$transformOrigin={transformOrigin}
xmlns="http://www.w3.org/2000/svg"
>
{sortedRoutes.rest.map((item) => item.route)}
{sortedRoutes.rest.map((item) => item.marks)}
{sortedRoutes.selected.map((item) => item.route)}
{sortedRoutes.selected.map((item) => item.marks)}
{sortedRoutes.hovered.map((item) => item.route)}
{sortedRoutes.hovered.map((item) => item.marks)}
</Svg>

{absolutePositionFromScreen && (
<RouteFloatingMenuContainer
$x={absolutePositionFromScreen.x + 20}
$y={absolutePositionFromScreen.y - DIALOG_TOP_BAR_HEIGHT - 15}
>
<RouteFloatingMenu />
</RouteFloatingMenuContainer>
)}
</>
<Svg
$hasEditableCursor={machine.currentStateName === 'extendRoute'}
onClick={(e) => {
onClick(e);
}}
onMouseUp={handleMovingPointDrop}
onMouseMove={onEditorMouseMove}
onTouchMove={onEditorTouchMove}
onPointerMove={onEditorTouchMove}
$imageSize={imageSize}
$isVisible={isVisible}
$transformOrigin={transformOrigin}
xmlns="http://www.w3.org/2000/svg"
ref={svgRef}
>
{sortedRoutes.rest.map((item) => item.route)}
{sortedRoutes.rest.map((item) => item.marks)}
{sortedRoutes.selected.map((item) => item.route)}
{sortedRoutes.selected.map((item) => item.marks)}
{sortedRoutes.hovered.map((item) => item.route)}
{sortedRoutes.hovered.map((item) => item.marks)}
</Svg>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ const RouteName = styled.div<{ opacity: number }>`
gap: 4px;
justify-content: space-between;
position: relative;
user-select: text;
`;

const RouteDescription = styled.div<{ opacity: number }>`
font-size: 10px;
opacity: ${({ opacity }) => opacity};
color: ${({ theme }) => theme.palette.text.secondary};
user-select: text;
`;

const RouteGrade = styled.div``;
Expand Down
9 changes: 7 additions & 2 deletions src/components/FeaturePanel/Climbing/TransformWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import { useClimbingContext } from './contexts/ClimbingContext';
import { ZoomState } from './types';

export const TransformWrapper = ({ children }) => {
const { setArePointerEventsDisabled, setPhotoZoom, isEditMode } =
useClimbingContext();
const {
setArePointerEventsDisabled,
setPhotoZoom,
isEditMode,
isPanningDisabled,
} = useClimbingContext();

const startPointerEvents = () => {
setArePointerEventsDisabled(false);
Expand All @@ -31,6 +35,7 @@ export const TransformWrapper = ({ children }) => {
onPanningStart={startPointerEvents}
onPanningStop={startPointerEvents}
disablePadding
panning={{ disabled: isPanningDisabled }}
wheel={{ step: 100 }}
centerOnInit
onTransformed={(_ref, state: ZoomState) => {
Expand Down
12 changes: 10 additions & 2 deletions src/components/FeaturePanel/Climbing/contexts/ClimbingContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type ClimbingContextType = {
imageSize: ImageSize;
imageContainerSize: ImageSize;
isPointMoving: boolean;
isPanningDisabled: boolean;
setIsPanningDisabled: (isPanningDisabled: boolean) => void;
isRouteSelected: (routeNumber: number) => boolean;
isOtherRouteSelected: (routeNumber: number) => boolean;
isRouteHovered: (routeNumber: number) => boolean;
Expand Down Expand Up @@ -111,6 +113,7 @@ type ClimbingContextType = {
filterDifficulty: Array<string>;
setFilterDifficulty: (filterDifficulty: Array<string>) => void;
photoRef: React.MutableRefObject<any>;
svgRef: React.MutableRefObject<any>;
getAllRoutesPhotos: (cragPhotos: Array<string>) => void;
showDebugMenu: boolean;
setShowDebugMenu: (showDebugMenu: boolean) => void;
Expand Down Expand Up @@ -142,6 +145,7 @@ export const ClimbingContextProvider = ({ children, feature }: Props) => {
const initialRoutes = osmToClimbingRoutes(feature);
publishDbgObject('climbingRoutes', initialRoutes);
const photoRef = useRef(null);
const svgRef = useRef(null);
const [photoPaths, setPhotoPaths] = useState<Array<string>>(null);
const [photoPath, setPhotoPath] = useState<string>(null); // photo, should be null
const [showDebugMenu, setShowDebugMenu] = useState(false);
Expand All @@ -155,6 +159,7 @@ export const ClimbingContextProvider = ({ children, feature }: Props) => {
const [routes, setRoutes] = useState<Array<ClimbingRoute>>(initialRoutes);
const [splitPaneSize, setSplitPaneSize] = useState<number | null>(null);
const [isPointMoving, setIsPointMoving] = useState<boolean>(false);
const [isPanningDisabled, setIsPanningDisabled] = useState<boolean>(false);
const [isPointClicked, setIsPointClicked] = useState<boolean>(false);
const [areRoutesLoading, setAreRoutesLoading] = useState<boolean>(true);
const [arePointerEventsDisabled, setArePointerEventsDisabled] =
Expand Down Expand Up @@ -270,7 +275,7 @@ export const ClimbingContextProvider = ({ children, feature }: Props) => {
updateRouteOnIndex,
getPercentagePosition,
findCloserPoint,
photoRef,
svgRef,
photoZoom,
});

Expand Down Expand Up @@ -323,6 +328,8 @@ export const ClimbingContextProvider = ({ children, feature }: Props) => {
imageSize,
isPointClicked,
isPointMoving,
isPanningDisabled,
setIsPanningDisabled,
isRouteSelected,
isOtherRouteSelected,
isRouteHovered,
Expand Down Expand Up @@ -366,7 +373,8 @@ export const ClimbingContextProvider = ({ children, feature }: Props) => {
loadPhotoRelatedData,
filterDifficulty,
setFilterDifficulty,
photoRef,
photoRef, // @TODO rename: technically it's not photoRef but photoContainerRef, because photo is scaled by object-fit: contain
svgRef,
areRoutesLoading,
setAreRoutesLoading,
photoZoom,
Expand Down
Loading

0 comments on commit 4d81758

Please sign in to comment.