raain-ui 2.3.14 → 2.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,32 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ## [2.3.13] - 2025-06-04
10
+ ### Fixed
11
11
 
12
- ### Added
12
+ - MapElement changeMarkerStyle
13
13
 
14
- - Added onLastClick callback option to DynamicDateStatusElement
15
- - Improved dataset initialization in DynamicDateStatusElement
16
- - Simplified type definitions using IDataSet interface
14
+ ## [2.3.16] - 2025-07-04
17
15
 
18
- ### Changed
16
+ ### Fixed
19
17
 
20
- - Version bump to 2.3.13
21
- - Version information export in bpInfo.ts
18
+ - UT with local labels in CI
22
19
 
23
- ## [2.3.9] - 2025-05-20
20
+ ## [2.3.15] - 2025-07-04
24
21
 
25
22
  ### Changed
26
23
 
27
- - Version bump to 2.3.9
28
- - Version information export in bpInfo.ts
24
+ - UTC to local date label
25
+ - Chart colors
26
+
27
+ ### Fixed
29
28
 
30
- ## [2.3.8] - 2025-05-20
29
+ - remove drag (edit) capabilities in elements that don't need it
30
+
31
+ ## [2.3.14] - 2025-06-16
31
32
 
32
33
  ### Changed
33
34
 
34
- - Version bump to 2.3.8
35
- - Version information export in bpInfo.ts
35
+ - Lint and pretty
36
+
37
+ ## [2.3.13] - 2025-06-04
38
+
39
+ ### Added
40
+
41
+ - Added onLastClick callback option to DynamicDateStatusElement
42
+ - Improved dataset initialization in DynamicDateStatusElement
43
+ - Simplified type definitions using IDataSet interface
36
44
 
37
45
  ## [2.3.6] - 2025-04-01
38
46
 
package/README.md CHANGED
@@ -99,6 +99,54 @@ npm start
99
99
  This will open the example application at http://localhost:1234, where you can explore the various components and
100
100
  features of raain-ui.
101
101
 
102
+ ### 🌬️ Wind Marker Animations
103
+
104
+ raain-ui includes CSS animations for visualizing wind speed and direction on map markers. To use these animations in your application:
105
+
106
+ **1. Import the CSS file in your global styles:**
107
+
108
+ ```scss
109
+ // In your global.scss or styles.scss
110
+ @import "~raain-ui/data/wind-markers.css";
111
+ ```
112
+
113
+ **Or in HTML:**
114
+
115
+ ```html
116
+ <link rel="stylesheet" href="node_modules/raain-ui/dist/data/wind-markers.css">
117
+ ```
118
+
119
+ **2. Use with MapElement:**
120
+
121
+ ```typescript
122
+ import { MapLatLng } from 'raain-ui';
123
+
124
+ // Create a marker with wind data
125
+ const windMarker = new MapLatLng(
126
+ lat, // latitude
127
+ lng, // longitude
128
+ azimuth, // alt property: azimuth 0-360° (0=North, 90=East, 180=South, 270=West)
129
+ id, // marker id
130
+ name, // marker name
131
+ strengthInMs // value property: wind strength in meters/second
132
+ );
133
+
134
+ // Apply wind animation
135
+ mapElement.changeMarkerStyle(
136
+ windMarker,
137
+ 'marker-wind marker-wind-225', // classes: base + direction
138
+ { strength: 10 } // CSS variable: wind strength
139
+ );
140
+ ```
141
+
142
+ **Available azimuth classes:** 0, 10, 20, 30, 45, 90, 135, 180, 200, 225, 270, 315
143
+
144
+ The animation automatically:
145
+ - Shows a directional arrow indicating wind direction
146
+ - Animates marker movement in the wind direction
147
+ - Adjusts animation speed based on wind strength
148
+ - Displays a blue glow with intensity matching wind strength
149
+
102
150
  ## 📚 Documentation
103
151
 
104
152
  Comprehensive API documentation is available in the [specifications](./specs) directory. This includes detailed
@@ -0,0 +1,174 @@
1
+ /* ============================================================================
2
+ * Wind Speed/Direction Animation for Leaflet Markers
3
+ * ============================================================================
4
+ * Usage: Import this CSS file in your app's global styles or index.html
5
+ *
6
+ * @import "~raain-ui/data/wind-markers.css";
7
+ *
8
+ * Or in HTML:
9
+ * <link rel="stylesheet" href="node_modules/raain-ui/dist/data/wind-markers.css">
10
+ *
11
+ * Then apply classes to markers via MapElement.changeMarkerStyle():
12
+ * mapElement.changeMarkerStyle(marker, 'marker-wind marker-wind-200', {strength: 10});
13
+ */
14
+
15
+ /* Base wind marker class */
16
+ .marker-wind {
17
+ /* Calculate animation speed: stronger wind = faster animation */
18
+ --duration: calc(5s - (min(var(--strength, 5), 25) * 0.08s));
19
+
20
+ /* Calculate displacement: strength in m/s * 2 = pixels */
21
+ --displacement: calc(var(--strength, 5) * 2);
22
+
23
+ /* Visual glow intensity based on strength */
24
+ filter: drop-shadow(0 0 calc(var(--strength, 5) * 0.5px) rgba(100, 150, 255, 0.8));
25
+
26
+ position: relative;
27
+
28
+ /* Rotation will be set by direction-specific classes */
29
+ --rotation: 0deg;
30
+ }
31
+
32
+ .marker-wind img {
33
+ transform: rotate(var(--rotation)) !important;
34
+ }
35
+
36
+ /* Variant: Travel animation (move from src to target, disappear, reappear at src)
37
+ Usage: Add 'marker-wind-travel' class in addition to marker-wind and direction class
38
+ Example: 'marker-wind marker-wind-travel marker-wind-200' */
39
+ .marker-wind-travel {
40
+ /* Override animation to use travel mode */
41
+ }
42
+
43
+ /* Pulse animation (brightness/opacity) */
44
+ @keyframes wind-pulse {
45
+ 0%, 100% {
46
+ opacity: 1;
47
+ filter: brightness(1);
48
+ }
49
+ 50% {
50
+ opacity: 0.85;
51
+ filter: brightness(1.15);
52
+ }
53
+ }
54
+
55
+ /* Travel mode pulse - fade out at destination */
56
+ @keyframes wind-pulse-travel {
57
+ 0% {
58
+ filter: brightness(1.2);
59
+ }
60
+ 70% {
61
+ filter: brightness(0.8);
62
+ }
63
+ 71%, 99% {
64
+ filter: brightness(0);
65
+ }
66
+ 100% {
67
+ filter: brightness(1.2);
68
+ }
69
+ }
70
+
71
+ /* Direction arrow indicator */
72
+ .marker-wind::after {
73
+ content: '→';
74
+ position: absolute;
75
+ top: -20px;
76
+ left: 50%;
77
+ font-size: 18px;
78
+ font-weight: bold;
79
+ color: rgba(100, 150, 255, 0.95);
80
+ text-shadow: 0 0 4px rgba(0, 0, 0, 0.7);
81
+ pointer-events: none;
82
+ transform-origin: center;
83
+ }
84
+
85
+ /* Wind direction classes for every available degree */
86
+ /* Azimuth 0 = North (upward), 90 = East (right), 180 = South (down), 270 = West (left) */
87
+ /* SVG arrow points right (East), so 90° = 0° rotation, others adjust from there */
88
+
89
+ .marker-wind-0::after, .marker-wind-360::after { transform: translateX(-50%) rotate(180deg); }
90
+ .marker-wind-0, .marker-wind-360 { --rotation: -90deg; animation: wind-0 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
91
+ @keyframes wind-0 { 0%, 100% { translate: 0 0; } 50% { translate: 0 calc(var(--displacement) * -1px); } }
92
+ .marker-wind-travel.marker-wind-0, .marker-wind-travel.marker-wind-360 { animation: wind-0-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
93
+ @keyframes wind-0-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: 0 calc(var(--displacement) * -1px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
94
+
95
+ .marker-wind-10::after { transform: translateX(-50%) rotate(190deg); }
96
+ .marker-wind-10 { --rotation: -80deg; animation: wind-10 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
97
+ @keyframes wind-10 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * 0.17px) calc(var(--displacement) * -0.98px); } }
98
+
99
+ .marker-wind-20::after { transform: translateX(-50%) rotate(200deg); }
100
+ .marker-wind-20 { --rotation: -70deg; animation: wind-20 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
101
+ @keyframes wind-20 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * 0.34px) calc(var(--displacement) * -0.94px); } }
102
+
103
+ .marker-wind-30::after { transform: translateX(-50%) rotate(210deg); }
104
+ .marker-wind-30 { --rotation: -60deg; animation: wind-30 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
105
+ @keyframes wind-30 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * 0.5px) calc(var(--displacement) * -0.87px); } }
106
+
107
+ .marker-wind-45::after { transform: translateX(-50%) rotate(225deg); }
108
+ .marker-wind-45 { --rotation: -45deg; animation: wind-45 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
109
+ @keyframes wind-45 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * 0.71px) calc(var(--displacement) * -0.71px); } }
110
+
111
+ .marker-wind-90::after { transform: translateX(-50%) rotate(270deg); }
112
+ .marker-wind-90 { --rotation: 0deg; animation: wind-90 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
113
+ @keyframes wind-90 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * 1px) 0; } }
114
+
115
+ .marker-wind-135::after { transform: translateX(-50%) rotate(315deg); }
116
+ .marker-wind-135 { --rotation: 45deg; animation: wind-135 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
117
+ @keyframes wind-135 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * 0.71px) calc(var(--displacement) * 0.71px); } }
118
+
119
+ .marker-wind-180::after { transform: translateX(-50%) rotate(0deg); }
120
+ .marker-wind-180 { --rotation: 90deg; animation: wind-180 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
121
+ @keyframes wind-180 { 0%, 100% { translate: 0 0; } 50% { translate: 0 calc(var(--displacement) * 1px); } }
122
+
123
+ .marker-wind-200::after { transform: translateX(-50%) rotate(20deg); }
124
+ .marker-wind-200 { --rotation: 110deg; animation: wind-200 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
125
+ @keyframes wind-200 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * 0.34px) calc(var(--displacement) * 0.94px); } }
126
+
127
+ .marker-wind-225::after { transform: translateX(-50%) rotate(45deg); }
128
+ .marker-wind-225 { --rotation: 135deg; animation: wind-225 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
129
+ @keyframes wind-225 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * -0.71px) calc(var(--displacement) * 0.71px); } }
130
+
131
+ .marker-wind-270::after { transform: translateX(-50%) rotate(90deg); }
132
+ .marker-wind-270 { --rotation: 180deg; animation: wind-270 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
133
+ @keyframes wind-270 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * -1px) 0; } }
134
+
135
+ .marker-wind-315::after { transform: translateX(-50%) rotate(135deg); }
136
+ .marker-wind-315 { --rotation: -135deg; animation: wind-315 var(--duration) ease-in-out infinite, wind-pulse var(--duration) ease-in-out infinite; }
137
+ @keyframes wind-315 { 0%, 100% { translate: 0 0; } 50% { translate: calc(var(--displacement) * -0.71px) calc(var(--displacement) * -0.71px); } }
138
+
139
+ /* ============================================================================
140
+ * Travel Mode Animations - Move from source to target, disappear, reappear
141
+ * ============================================================================ */
142
+
143
+ .marker-wind-travel.marker-wind-10 { animation: wind-10-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
144
+ @keyframes wind-10-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * 0.17px) calc(var(--displacement) * -0.98px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
145
+
146
+ .marker-wind-travel.marker-wind-20 { animation: wind-20-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
147
+ @keyframes wind-20-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * 0.34px) calc(var(--displacement) * -0.94px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
148
+
149
+ .marker-wind-travel.marker-wind-30 { animation: wind-30-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
150
+ @keyframes wind-30-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * 0.5px) calc(var(--displacement) * -0.87px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
151
+
152
+ .marker-wind-travel.marker-wind-45 { animation: wind-45-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
153
+ @keyframes wind-45-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * 0.71px) calc(var(--displacement) * -0.71px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
154
+
155
+ .marker-wind-travel.marker-wind-90 { animation: wind-90-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
156
+ @keyframes wind-90-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * 1px) 0; opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
157
+
158
+ .marker-wind-travel.marker-wind-135 { animation: wind-135-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
159
+ @keyframes wind-135-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * 0.71px) calc(var(--displacement) * 0.71px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
160
+
161
+ .marker-wind-travel.marker-wind-180 { animation: wind-180-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
162
+ @keyframes wind-180-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: 0 calc(var(--displacement) * 1px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
163
+
164
+ .marker-wind-travel.marker-wind-200 { animation: wind-200-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
165
+ @keyframes wind-200-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * 0.34px) calc(var(--displacement) * 0.94px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
166
+
167
+ .marker-wind-travel.marker-wind-225 { animation: wind-225-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
168
+ @keyframes wind-225-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * -0.71px) calc(var(--displacement) * 0.71px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
169
+
170
+ .marker-wind-travel.marker-wind-270 { animation: wind-270-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
171
+ @keyframes wind-270-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * -1px) 0; opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }
172
+
173
+ .marker-wind-travel.marker-wind-315 { animation: wind-315-travel var(--duration) linear infinite, wind-pulse-travel var(--duration) linear infinite; }
174
+ @keyframes wind-315-travel { 0% { translate: 0 0; opacity: 1; } 70% { translate: calc(var(--displacement) * -0.71px) calc(var(--displacement) * -0.71px); opacity: 1; } 71% { opacity: 0; } 99% { translate: 0 0; opacity: 0; } 100% { translate: 0 0; opacity: 1; } }