💄 Add ScrollingText component and use it in StopAreaRepr component
Update DestinationPassages component to use it.
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
import { VoidComponent, createResource, onMount, ParentComponent, ParentProps, Show, useContext, For } from 'solid-js';
|
||||
import { createDateNow, getTime } from '@solid-primitives/date';
|
||||
import { timeline } from '@motionone/dom';
|
||||
import { AnimationOptions } from '@motionone/types';
|
||||
import { Motion } from "@motionone/solid";
|
||||
import { format } from "date-fns";
|
||||
|
||||
import { Line, TrafficStatus } from './types';
|
||||
import { renderLineTransportMode, renderLinePicto } from './utils';
|
||||
import { renderLineTransportMode, renderLinePicto, ScrollingText } from './utils';
|
||||
import { BusinessDataContext, BusinessDataStore } from "./businessData";
|
||||
|
||||
import "./passagesPanel.scss";
|
||||
@@ -123,24 +122,6 @@ const DestinationPassages: VoidComponent<{ line: Line, destination: string }> =
|
||||
// const trafficStatusStyle = { fill: trafficStatusColor.get(props.line.trafficStatus) };
|
||||
const trafficStatusStyle = { fill: trafficStatusColor.get(TrafficStatus.UNKNOWN) };
|
||||
|
||||
let destinationViewboxRef: SVGSVGElement | undefined = undefined;
|
||||
let destinationTextRef: SVGTextElement | undefined = undefined;
|
||||
|
||||
onMount(() => {
|
||||
if (destinationViewboxRef !== undefined && destinationTextRef !== undefined) {
|
||||
const overlap = destinationTextRef.getComputedTextLength() - destinationViewboxRef.viewBox.baseVal.width;
|
||||
if (overlap > 0) {
|
||||
timeline(
|
||||
[
|
||||
[destinationTextRef, { x: [-overlap] }, { duration: 5 }],
|
||||
[destinationTextRef, { x: [0] }, { duration: 2 }],
|
||||
],
|
||||
{ repeat: Infinity },
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div class="line">
|
||||
<div class="transportMode">
|
||||
@@ -148,14 +129,7 @@ const DestinationPassages: VoidComponent<{ line: Line, destination: string }> =
|
||||
</div>
|
||||
{renderLinePicto(props.line)}
|
||||
<div class="destination">
|
||||
<svg ref={destinationViewboxRef} viewBox="0 0 600 40">
|
||||
<text ref={destinationTextRef} x="0" y="50%"
|
||||
dominant-baseline="middle"
|
||||
font-size="40"
|
||||
style={{ fill: "#000000" }}>
|
||||
{props.destination}
|
||||
</text>
|
||||
</svg>
|
||||
<ScrollingText height={40} width={600} content={props.destination} />
|
||||
</div>
|
||||
<div class="trafficStatus">
|
||||
<svg viewBox="0 0 51 51">
|
||||
|
@@ -53,16 +53,19 @@
|
||||
border-bottom: solid calc(2px);
|
||||
|
||||
.name {
|
||||
margin-left: calc(40/1920*100%);
|
||||
width: 60%;
|
||||
aspect-ratio: 2.5;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
font-family: IDFVoyageur-bold;
|
||||
}
|
||||
|
||||
.lineRepr {
|
||||
// height: 100%;
|
||||
width: 40%;
|
||||
aspect-ratio: 2.5;
|
||||
// margin-left: auto;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@@ -9,7 +9,7 @@ import {
|
||||
} from 'leaflet';
|
||||
|
||||
import { Stop } from './types';
|
||||
import { PositionedPanel, renderLineTransportMode, renderLinePicto, TransportModeWeights } from './utils';
|
||||
import { PositionedPanel, renderLineTransportMode, renderLinePicto, ScrollingText, TransportModeWeights } from './utils';
|
||||
|
||||
import { AppContextContext, AppContextStore } from "./appContext";
|
||||
import { BusinessDataContext, BusinessDataStore } from "./businessData";
|
||||
@@ -191,10 +191,10 @@ const StopRepr: VoidComponent<{ stop: Stop }> = (props) => {
|
||||
type ByTransportModeReprs = {
|
||||
mode: JSX.Element | undefined;
|
||||
lines: Record<string, JSX.Element | JSX.Element[] | undefined>;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const StopAreaRepr: VoidComponent<{ stop: Stop }> = (props) => {
|
||||
const fontSize: number = 10;
|
||||
|
||||
const businessDataStore: BusinessDataStore | undefined = useContext(BusinessDataContext);
|
||||
const appContextStore: AppContextStore | undefined = useContext(AppContextContext);
|
||||
@@ -248,7 +248,9 @@ const StopAreaRepr: VoidComponent<{ stop: Stop }> = (props) => {
|
||||
|
||||
return (
|
||||
<div class="stop" onClick={() => setDisplayedStops([props.stop])}>
|
||||
<div class="name">{props.stop.name}</div>
|
||||
<div class="name" >
|
||||
<ScrollingText height={fontSize} width={100} content={props.stop.name} />
|
||||
</div>
|
||||
{lineReprs()}
|
||||
</div>
|
||||
);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { JSX } from 'solid-js';
|
||||
import { JSX, onMount, VoidComponent } from 'solid-js';
|
||||
import { timeline } from '@motionone/dom';
|
||||
|
||||
import { Line } from './types';
|
||||
|
||||
@@ -129,3 +130,37 @@ export type PositionedPanel = {
|
||||
// TODO: Should be PassagesPanelComponent ?
|
||||
panel: JSX.Element;
|
||||
};
|
||||
|
||||
|
||||
export const ScrollingText: VoidComponent<{ height: number, width: number, content: string }> = (props) => {
|
||||
|
||||
let viewBoxRef: SVGSVGElement | undefined = undefined;
|
||||
let textRef: SVGTextElement | undefined = undefined;
|
||||
|
||||
onMount(() => {
|
||||
if (viewBoxRef !== undefined && textRef !== undefined) {
|
||||
const overlap = textRef.getComputedTextLength() - viewBoxRef.viewBox.baseVal.width;
|
||||
if (overlap > 0) {
|
||||
timeline(
|
||||
[
|
||||
[textRef, { x: [-overlap] }, { duration: 5 }],
|
||||
[textRef, { x: [0] }, { duration: 2 }],
|
||||
],
|
||||
{ repeat: Infinity },
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<svg ref={viewBoxRef} viewBox={`0 0 ${props.width} ${props.height}`}>
|
||||
<text
|
||||
ref={textRef}
|
||||
x="0%" y="55%"
|
||||
dominant-baseline="middle"
|
||||
font-size={`${props.height}px`}>
|
||||
{props.content}
|
||||
</text>
|
||||
</svg >
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user