Skip to content

Commit fd5c26c

Browse files
committed
speedspacechart: fix blinking in speed limit tags by importing images only once
Signed-off-by: Alice Khoudli <[email protected]>
1 parent bc09581 commit fd5c26c

File tree

3 files changed

+40
-27
lines changed

3 files changed

+40
-27
lines changed

ui-speedspacechart/src/components/helpers/drawElements/speedLimitTags.ts

+15-26
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,14 @@ import {
1313
} from '../../const';
1414
import {
1515
clearCanvas,
16-
createSvgBlobUrl,
1716
drawLinearLayerBackground,
1817
drawRoundedRect,
1918
drawSeparatorLinearLayer,
2019
drawSvgImageWithColor,
21-
loadSvgImage,
2220
maxPositionValue,
2321
positionOnGraphScale,
2422
} from '../../utils';
2523

26-
const questionSvg =
27-
'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13M6.92 6.085h.001a.75.75 0 1 1-1.342-.67c.169-.339.436-.701.849-.977C6.845 4.16 7.369 4 8 4a2.76 2.76 0 0 1 1.637.525c.503.377.863.965.863 1.725 0 .448-.115.83-.329 1.15-.205.307-.47.513-.692.662-.109.072-.22.138-.313.195l-.006.004a6 6 0 0 0-.26.16 1 1 0 0 0-.276.245.75.75 0 0 1-1.248-.832c.184-.264.42-.489.692-.661q.154-.1.313-.195l.007-.004c.1-.061.182-.11.258-.161a1 1 0 0 0 .277-.245C8.96 6.514 9 6.427 9 6.25a.61.61 0 0 0-.262-.525A1.27 1.27 0 0 0 8 5.5c-.369 0-.595.09-.74.187-.146.1-.263.238-.34.398M9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/></svg>';
28-
const alertFillSvg =
29-
'<svg xmlns="http://www.w3.org/2000/svg" width = "16" height = "16" viewBox = "0 0 16 16" > <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575zM8 5a.75.75 0 0 0-.75.75v2.5a.75.75 0 0 0 1.5 0v-2.5A.75.75 0 0 0 8 5m1 6a1 1 0 1 0-2 0 1 1 0 0 0 2 0" /> </svg>';
30-
const questionBlobUrl = createSvgBlobUrl(questionSvg);
31-
const alertFillBlobUrl = createSvgBlobUrl(alertFillSvg);
32-
3324
const RECT_HEIGHT = 17;
3425
const Y_POSITION = 12;
3526
const RECTANGLE_SPACING = 1;
@@ -43,11 +34,12 @@ const TEXT_PADDING_TOP = 1;
4334
const ICON_BACKGROUND_WIDTH = 24;
4435
const ICON_BACKGROUND_HEIGHT = 24;
4536

46-
export const drawSpeedLimitTags = async ({
37+
export const drawSpeedLimitTags = ({
4738
ctx,
4839
width,
4940
height: marginTop,
5041
store,
42+
images,
5143
}: SpeedLimitTagsLayerDrawFunctionParams) => {
5244
const {
5345
speedLimitTags,
@@ -65,9 +57,6 @@ export const drawSpeedLimitTags = async ({
6557

6658
const maxPosition = maxPositionValue(store.speeds);
6759

68-
const questionImage = await loadSvgImage(questionBlobUrl);
69-
const alertFillImage = await loadSvgImage(alertFillBlobUrl);
70-
7160
let speedLimitTagsBackgroundColor = LINEAR_LAYERS_BACKGROUND_COLOR.FIRST;
7261

7362
if (electricalProfiles && powerRestrictions) {
@@ -127,7 +116,7 @@ export const drawSpeedLimitTags = async ({
127116
}
128117

129118
if (tag === 'incompatible' || tag === 'missing_from_train') {
130-
const image = tag === 'incompatible' ? alertFillImage : questionImage;
119+
const image = tag === 'incompatible' ? images.alertFillImage : images.questionImage;
131120

132121
ctx.fillStyle = color;
133122

@@ -143,16 +132,16 @@ export const drawSpeedLimitTags = async ({
143132
ICON_BACKGROUND_HEIGHT,
144133
cornerRadius
145134
);
146-
147-
drawSvgImageWithColor(
148-
ctx,
149-
image,
150-
iconXPosition + ICON_OFFSET,
151-
iconYPosition + ICON_OFFSET,
152-
ICON_WIDTH,
153-
ICON_HEIGHT,
154-
WHITE.hex()
155-
);
135+
if (image !== null)
136+
drawSvgImageWithColor(
137+
ctx,
138+
image,
139+
iconXPosition + ICON_OFFSET,
140+
iconYPosition + ICON_OFFSET,
141+
ICON_WIDTH,
142+
ICON_HEIGHT,
143+
WHITE.hex()
144+
);
156145
} else {
157146
ctx.fillStyle = 'white';
158147
ctx.font = '600 12px "IBM Plex Sans"';
@@ -172,11 +161,11 @@ export const drawSpeedLimitTags = async ({
172161
ctx.clearRect(width - MARGIN_RIGHT, 0, width, LINEAR_LAYERS_HEIGHTS.SPEED_LIMIT_TAGS_HEIGHT);
173162
};
174163

175-
export const computeTooltip = async ({
164+
export const computeTooltip = ({
176165
width,
177166
height: marginTop,
178167
store,
179-
}: DrawFunctionParams): Promise<tooltipInfos | null> => {
168+
}: DrawFunctionParams): tooltipInfos | null => {
180169
const { speedLimitTags, ratioX, leftOffset, cursor } = store;
181170

182171
const { MARGIN_TOP, MARGIN_LEFT } = MARGINS;

ui-speedspacechart/src/components/layers/SpeedLimitTagsLayer.tsx

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,42 @@
1-
import React, { useEffect, useRef } from 'react';
1+
import React, { useEffect, useRef, useState } from 'react';
22

33
import type { Store, tooltipInfos } from '../../types/chartTypes';
44
import Tooltip from '../common/Tooltip';
55
import { LINEAR_LAYERS_HEIGHTS } from '../const';
66
import { drawSpeedLimitTags, computeTooltip } from '../helpers/drawElements/speedLimitTags';
7+
import { createSvgBlobUrl, loadSvgImage } from '../utils';
78

89
type SpeedLimitTagsLayerProps = {
910
width: number;
1011
marginTop: number;
1112
store: Store;
1213
};
14+
type LoadedImages = {
15+
questionImage: HTMLImageElement | null;
16+
alertFillImage: HTMLImageElement | null;
17+
};
1318
const TOOLTIP_HEIGHT = 40;
1419
const MARGIN_ADJUSTMENT = 2;
1520

1621
const SpeedLimitTagsLayer = ({ width, marginTop, store }: SpeedLimitTagsLayerProps) => {
1722
const canvas = useRef<HTMLCanvasElement>(null);
1823
const tooltip = useRef<tooltipInfos | null>();
24+
const [images, setImages] = useState<LoadedImages>({ questionImage: null, alertFillImage: null });
25+
26+
useEffect(() => {
27+
const fetchImages = async () => {
28+
const questionSvg =
29+
'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13M6.92 6.085h.001a.75.75 0 1 1-1.342-.67c.169-.339.436-.701.849-.977C6.845 4.16 7.369 4 8 4a2.76 2.76 0 0 1 1.637.525c.503.377.863.965.863 1.725 0 .448-.115.83-.329 1.15-.205.307-.47.513-.692.662-.109.072-.22.138-.313.195l-.006.004a6 6 0 0 0-.26.16 1 1 0 0 0-.276.245.75.75 0 0 1-1.248-.832c.184-.264.42-.489.692-.661q.154-.1.313-.195l.007-.004c.1-.061.182-.11.258-.161a1 1 0 0 0 .277-.245C8.96 6.514 9 6.427 9 6.25a.61.61 0 0 0-.262-.525A1.27 1.27 0 0 0 8 5.5c-.369 0-.595.09-.74.187-.146.1-.263.238-.34.398M9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/></svg>';
30+
const alertFillSvg =
31+
'<svg xmlns="http://www.w3.org/2000/svg" width = "16" height = "16" viewBox = "0 0 16 16" > <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575zM8 5a.75.75 0 0 0-.75.75v2.5a.75.75 0 0 0 1.5 0v-2.5A.75.75 0 0 0 8 5m1 6a1 1 0 1 0-2 0 1 1 0 0 0 2 0" /> </svg>';
32+
const questionBlobUrl = createSvgBlobUrl(questionSvg);
33+
const alertFillBlobUrl = createSvgBlobUrl(alertFillSvg);
34+
const questionImage = await loadSvgImage(questionBlobUrl);
35+
const alertFillImage = await loadSvgImage(alertFillBlobUrl);
36+
setImages({ questionImage, alertFillImage });
37+
};
38+
fetchImages();
39+
}, []);
1940

2041
useEffect(() => {
2142
const updateCanvas = async () => {
@@ -36,6 +57,7 @@ const SpeedLimitTagsLayer = ({ width, marginTop, store }: SpeedLimitTagsLayerPro
3657
width,
3758
height: marginTop,
3859
store: restrictedStore,
60+
images,
3961
});
4062
};
4163
updateCanvas();
@@ -48,6 +70,7 @@ const SpeedLimitTagsLayer = ({ width, marginTop, store }: SpeedLimitTagsLayerPro
4870
store.layersDisplay.electricalProfiles,
4971
store.layersDisplay.powerRestrictions,
5072
store.speeds,
73+
images,
5174
]);
5275

5376
useEffect(() => {

ui-speedspacechart/src/types/chartTypes.ts

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export type SpeedLimitTagsLayerDrawFunctionParams = {
105105
width: number;
106106
height: number;
107107
store: SpeedLimitTagsLayerDrawingStore;
108+
images: { questionImage: HTMLImageElement | null; alertFillImage: HTMLImageElement | null };
108109
};
109110

110111
export type TrainDetails = {

0 commit comments

Comments
 (0)