Optimized track rendering
*Optimized track rendering to not always render both scaled and unscaled versions of the track
This commit is contained in:
parent
d7fdf0fc7e
commit
0ca6f6b9e0
@ -2,8 +2,9 @@ import React, { useRef, useEffect, useCallback } from 'react';
|
||||
import './ZoomPanWrapper.css';
|
||||
import Constants from '../../helpers/constants';
|
||||
import { useZoomPanSubscriber, viewBox$, clientRect$, camera$ } from '../../hooks/useZoomPubSub';
|
||||
import {mapRotation$} from '../../services/mapRotationService';
|
||||
import {setMapRotation} from '../../services/mapRotationService';
|
||||
import AngleHelper from "../../helpers/angleHelper";
|
||||
import { setMapZoom } from '../../services/mapZoomService';
|
||||
|
||||
function boundZoom(zoom) {
|
||||
return Math.max(Constants.map.zoomMin, Math.min(Constants.map.zoomMax, zoom));
|
||||
@ -44,7 +45,8 @@ export default function ZoomPanWrapper({children}) {
|
||||
rafScheduledRef.current = false;
|
||||
cameraWrapperRef.current.setAttribute('transform', getCameraTransformString());
|
||||
camera$.next(cameraRef.current);
|
||||
mapRotation$.next(cameraRef.current.rotation);
|
||||
setMapRotation(cameraRef.current.rotation);
|
||||
setMapZoom(cameraRef.current.zoom);
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, {useContext} from "react";
|
||||
import React, {useEffect, useCallback, useContext} from "react";
|
||||
import SettingsContext from "../../../contexts/SettingsContext";
|
||||
import Constants from "../../../helpers/constants";
|
||||
import {ElectrificationStatus} from "../../../model/electrification-status";
|
||||
@ -7,6 +7,7 @@ import {setHoveredTrack, unsetHoveredTrack} from "../../../services/trackHoverIn
|
||||
import GradientsContext from "../../../contexts/GradientsContext";
|
||||
import { TrackShape, TrackSource } from "../../../model/tracks/track";
|
||||
import {useZoomPanEmitter} from "../../../hooks/useZoomPubSub";
|
||||
import { mapZoomTrackDetails$ } from "../../../services/mapZoomService";
|
||||
|
||||
export default function TrackRenderer(props) {
|
||||
const { object } = props;
|
||||
@ -32,25 +33,47 @@ const MemoizedTrackRenderer = React.memo(StatelessTrackRenderer);
|
||||
|
||||
function StatelessTrackRenderer(props) {
|
||||
const {object, trackColorMode, gradientDef, onAlign} = props;
|
||||
const unscaledPathRef = React.useRef(null);
|
||||
const scaledPathRef = React.useRef(null);
|
||||
|
||||
if (object.points.start.distanceSq(object.points.end) < 0.001) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const onMouseEnter = () => {
|
||||
const onMouseEnter = useCallback(() => {
|
||||
setHoveredTrack(object);
|
||||
};
|
||||
}, [object]);
|
||||
|
||||
const onMouseLeave = () => {
|
||||
const onMouseLeave = useCallback(() => {
|
||||
unsetHoveredTrack(null);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const onClick = (event) => {
|
||||
const onClick = useCallback((event) => {
|
||||
if (object.shape === TrackShape.STRAIGHT && event.detail === 2) {
|
||||
event.preventDefault();
|
||||
onAlign(event);
|
||||
}
|
||||
};
|
||||
}, [object, onAlign]);
|
||||
|
||||
const handleDetailsUpdate = useCallback((details) => {
|
||||
if (!unscaledPathRef.current || !scaledPathRef.current) return;
|
||||
|
||||
if(details) {
|
||||
unscaledPathRef.current.style.display = 'none';
|
||||
scaledPathRef.current.style.display = 'block';
|
||||
} else {
|
||||
unscaledPathRef.current.style.display = 'block';
|
||||
scaledPathRef.current.style.display = 'none';
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const subscription = mapZoomTrackDetails$.subscribe(details => {
|
||||
handleDetailsUpdate(details);
|
||||
});
|
||||
|
||||
return () => subscription.unsubscribe();
|
||||
}, [handleDetailsUpdate]);
|
||||
|
||||
if (object.points.start.distanceSq(object.points.end) < 0.001) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const path = getTrackPath(object);
|
||||
const color = getTrackColor(object, trackColorMode, gradientDef);
|
||||
@ -60,11 +83,13 @@ function StatelessTrackRenderer(props) {
|
||||
<g id={`track-${object.id}`}>
|
||||
{defs}
|
||||
<path
|
||||
ref={unscaledPathRef}
|
||||
d={path}
|
||||
stroke={color}
|
||||
className="track-unscaled"
|
||||
/>
|
||||
<path
|
||||
ref={scaledPathRef}
|
||||
d={path}
|
||||
stroke={color}
|
||||
className="track"
|
||||
|
||||
@ -8,7 +8,8 @@ const Constants = {
|
||||
rotationSensitivity: 0.2,
|
||||
forcePointerEvents: false,
|
||||
platformMaxTilt: 0.5,
|
||||
showDebugTrackIds: false
|
||||
showDebugTrackIds: false,
|
||||
mapZoomTrackDetailsThreshold: 1 / 1.44
|
||||
},
|
||||
parser: {
|
||||
logSceneryAfterFinished: true,
|
||||
|
||||
13
src/services/mapZoomService.js
Normal file
13
src/services/mapZoomService.js
Normal file
@ -0,0 +1,13 @@
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import Constants from '../helpers/constants';
|
||||
|
||||
export const mapZoom$ = new BehaviorSubject(null);
|
||||
export const mapZoomTrackDetails$ = new BehaviorSubject(true);
|
||||
export function setMapZoom(zoom) {
|
||||
mapZoom$.next(zoom);
|
||||
|
||||
const newZoomTrackDetails = zoom > Constants.map.mapZoomTrackDetailsThreshold;
|
||||
if (mapZoomTrackDetails$.getValue() !== newZoomTrackDetails) {
|
||||
mapZoomTrackDetails$.next(newZoomTrackDetails);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user