Add route name transparrency effect
- Added useCameraSubscriber hook - Added route name transparrency effect
This commit is contained in:
parent
3a242bb8ad
commit
e9230f5eed
@ -1,9 +1,13 @@
|
|||||||
|
import { useRef, useCallback, useEffect } from 'react';
|
||||||
import { ReactSVG } from "react-svg";
|
import { ReactSVG } from "react-svg";
|
||||||
import AlwaysUpText from "../text/AlwaysUpText";
|
import AlwaysUpText from "../text/AlwaysUpText";
|
||||||
import AngleHelper from "../../../helpers/angleHelper";
|
import AngleHelper from "../../../helpers/angleHelper";
|
||||||
|
import { useCameraSubscriber } from '../../../hooks/useZoomPubSub';
|
||||||
|
import Constants from '../../../helpers/constants';
|
||||||
|
|
||||||
export default function RouteRenderer(props) {
|
export default function RouteRenderer(props) {
|
||||||
const { object } = props;
|
const { object } = props;
|
||||||
|
const textRef = useRef(null);
|
||||||
|
|
||||||
const [startX, startY] = object.pos.toSVGCoords();
|
const [startX, startY] = object.pos.toSVGCoords();
|
||||||
const startAngle = object.rot.y;
|
const startAngle = object.rot.y;
|
||||||
@ -14,6 +18,18 @@ export default function RouteRenderer(props) {
|
|||||||
const offY = object.track_count === 2 ? -22 : -20;
|
const offY = object.track_count === 2 ? -22 : -20;
|
||||||
const arrowOffset = - object.track_offset - 37.8;
|
const arrowOffset = - object.track_offset - 37.8;
|
||||||
|
|
||||||
|
const handleZoomTransparrency = useCallback((camera) => {
|
||||||
|
if (!textRef.current?.style || !camera) return;
|
||||||
|
|
||||||
|
const min = Constants.map.routeTextMinZoom;
|
||||||
|
const max = Constants.map.routeTextMaxZoom;
|
||||||
|
const value = (max - camera.zoom) / (max - min);
|
||||||
|
const opacity = Math.pow(Math.min(Math.max(value, 0), 1), 2);
|
||||||
|
textRef.current.style.opacity = opacity;
|
||||||
|
}, [textRef]);
|
||||||
|
|
||||||
|
useCameraSubscriber(handleZoomTransparrency);
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
<g className="map-icon" transform={`translate(${endX}, ${endY}) rotate(${endAngle + 90}) translate(-80, ${arrowOffset})`}>
|
<g className="map-icon" transform={`translate(${endX}, ${endY}) rotate(${endAngle + 90}) translate(-80, ${arrowOffset})`}>
|
||||||
<ReactSVG
|
<ReactSVG
|
||||||
@ -34,8 +50,9 @@ export default function RouteRenderer(props) {
|
|||||||
textProps={{
|
textProps={{
|
||||||
y: offY,
|
y: offY,
|
||||||
dominantBaseline: "bottom",
|
dominantBaseline: "bottom",
|
||||||
className: "route-text"
|
className: "route-text",
|
||||||
}}
|
}}
|
||||||
|
textRef={textRef}
|
||||||
text={object.route_name}
|
text={object.route_name}
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
|
|||||||
@ -2,10 +2,20 @@ import { useCallback, useEffect, useRef } from "react";
|
|||||||
import AngleHelper from "../../../helpers/angleHelper";
|
import AngleHelper from "../../../helpers/angleHelper";
|
||||||
import { mapRotation$ } from "../../../services/mapRotationService";
|
import { mapRotation$ } from "../../../services/mapRotationService";
|
||||||
|
|
||||||
export default function AlwaysUpText(props) {
|
export default function AlwaysUpText({
|
||||||
const { baseRot, additionalRot, additionalPreRot, text, reverseAnchor, offsetX, offsetY, textProps } = props;
|
baseRot,
|
||||||
|
additionalRot,
|
||||||
|
additionalPreRot,
|
||||||
|
text,
|
||||||
|
reverseAnchor,
|
||||||
|
offsetX,
|
||||||
|
offsetY,
|
||||||
|
textProps,
|
||||||
|
textRef
|
||||||
|
}) {
|
||||||
const gRef = useRef(null);
|
const gRef = useRef(null);
|
||||||
const textRef = useRef(null);
|
const ownTextRef = useRef(null);
|
||||||
|
if(!textRef) textRef = ownTextRef;
|
||||||
|
|
||||||
const getTransformString = useCallback((upsideDown) => {
|
const getTransformString = useCallback((upsideDown) => {
|
||||||
const upsideDownRot = upsideDown ? 180 : 0;
|
const upsideDownRot = upsideDown ? 180 : 0;
|
||||||
|
|||||||
@ -15,7 +15,9 @@ const Constants = {
|
|||||||
showDebugTrackIds: false,
|
showDebugTrackIds: false,
|
||||||
mapZoomTrackDetailsThreshold: 1 / 1.44,
|
mapZoomTrackDetailsThreshold: 1 / 1.44,
|
||||||
mapZoomObjectDetailsThreshold: 0.5,
|
mapZoomObjectDetailsThreshold: 0.5,
|
||||||
distanceMeterMaxMovePx: 10
|
distanceMeterMaxMovePx: 10,
|
||||||
|
routeTextMinZoom: 1.5,
|
||||||
|
routeTextMaxZoom: 3
|
||||||
},
|
},
|
||||||
parser: {
|
parser: {
|
||||||
logSceneryAfterFinished: readEnvBool('VITE_DO_LOG_SCENERY') ?? false,
|
logSceneryAfterFinished: readEnvBool('VITE_DO_LOG_SCENERY') ?? false,
|
||||||
|
|||||||
@ -37,6 +37,15 @@ export function useZoomPanSubscriber(setCamera, onAlign) {
|
|||||||
}, [onAlign]);
|
}, [onAlign]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useCameraSubscriber(onCameraUpdate) {
|
||||||
|
useEffect(() => {
|
||||||
|
const sub = camera$.subscribe((camera) => {
|
||||||
|
onCameraUpdate(camera);
|
||||||
|
});
|
||||||
|
return () => sub.unsubscribe();
|
||||||
|
}, [onCameraUpdate]);
|
||||||
|
}
|
||||||
|
|
||||||
export function useZoomPanEmitter() {
|
export function useZoomPanEmitter() {
|
||||||
return {
|
return {
|
||||||
setCamera: (x, y, rot = null, zoom = null) => {
|
setCamera: (x, y, rot = null, zoom = null) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user