Spaces:
Runtime error
Runtime error
feat: enhance UI with Granim.js animated gradient backgrounds
Browse files- Add Granim.js animated gradient backgrounds to all pages
- Replace static CSS gradients/animations with dynamic canvas-based animations
- Use high-quality forest background image from Unsplash for consistent theming
- Update index.html: diagonal direction with overlay blending mode
- Update map.html: radial direction with multiply blending mode
- Update login.html: top-bottom direction with multiply blending, enhanced states
- Maintain responsive design and accessibility across all breakpoints
- Ensure header content remains properly layered above animated backgrounds
- Add smooth gradient transitions with nature-inspired color palettes
- static/index.html +43 -12
- static/login.html +4 -57
- static/map.html +43 -13
static/index.html
CHANGED
|
@@ -8,6 +8,8 @@
|
|
| 8 |
<meta http-equiv="Expires" content="0">
|
| 9 |
<title>TreeTrack - Professional Field Research</title>
|
| 10 |
<link rel="stylesheet" href="/static/css/design-system.css">
|
|
|
|
|
|
|
| 11 |
<style>
|
| 12 |
|
| 13 |
:root {
|
|
@@ -80,28 +82,26 @@
|
|
| 80 |
-moz-osx-font-smoothing: grayscale;
|
| 81 |
}
|
| 82 |
|
| 83 |
-
/* Updated header
|
| 84 |
.tt-header {
|
| 85 |
position: relative;
|
| 86 |
overflow: hidden;
|
| 87 |
}
|
| 88 |
|
| 89 |
-
|
| 90 |
-
|
| 91 |
position: absolute;
|
| 92 |
top: 0;
|
| 93 |
left: 0;
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
background-size: 200px 20px;
|
| 98 |
-
background-position: bottom;
|
| 99 |
-
animation: wave 8s linear infinite;
|
| 100 |
}
|
| 101 |
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
|
|
|
| 105 |
}
|
| 106 |
|
| 107 |
/* Button styles now handled by design system */
|
|
@@ -927,6 +927,9 @@
|
|
| 927 |
</head>
|
| 928 |
<body>
|
| 929 |
<div class="tt-header">
|
|
|
|
|
|
|
|
|
|
| 930 |
<div class="tt-header-content">
|
| 931 |
<div class="tt-header-brand">
|
| 932 |
<div class="tt-header-logo">TreeTrack</div>
|
|
@@ -1136,5 +1139,33 @@
|
|
| 1136 |
</div>
|
| 1137 |
|
| 1138 |
<script type="module" src="/static/js/tree-track-app.js?v=5.0.0"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1139 |
</body>
|
| 1140 |
</html>
|
|
|
|
| 8 |
<meta http-equiv="Expires" content="0">
|
| 9 |
<title>TreeTrack - Professional Field Research</title>
|
| 10 |
<link rel="stylesheet" href="/static/css/design-system.css">
|
| 11 |
+
<!-- Granim.js for gradient animations -->
|
| 12 |
+
<script src="https://cdn.jsdelivr.net/npm/granim@2.0.0/dist/granim.min.js"></script>
|
| 13 |
<style>
|
| 14 |
|
| 15 |
:root {
|
|
|
|
| 82 |
-moz-osx-font-smoothing: grayscale;
|
| 83 |
}
|
| 84 |
|
| 85 |
+
/* Updated header with Granim animated background */
|
| 86 |
.tt-header {
|
| 87 |
position: relative;
|
| 88 |
overflow: hidden;
|
| 89 |
}
|
| 90 |
|
| 91 |
+
/* Granim Canvas for Header */
|
| 92 |
+
#header-canvas {
|
| 93 |
position: absolute;
|
| 94 |
top: 0;
|
| 95 |
left: 0;
|
| 96 |
+
width: 100%;
|
| 97 |
+
height: 100%;
|
| 98 |
+
z-index: 1;
|
|
|
|
|
|
|
|
|
|
| 99 |
}
|
| 100 |
|
| 101 |
+
/* Ensure header content is above canvas */
|
| 102 |
+
.tt-header-content {
|
| 103 |
+
position: relative;
|
| 104 |
+
z-index: 2;
|
| 105 |
}
|
| 106 |
|
| 107 |
/* Button styles now handled by design system */
|
|
|
|
| 927 |
</head>
|
| 928 |
<body>
|
| 929 |
<div class="tt-header">
|
| 930 |
+
<!-- Granim Canvas for Header Background -->
|
| 931 |
+
<canvas id="header-canvas"></canvas>
|
| 932 |
+
|
| 933 |
<div class="tt-header-content">
|
| 934 |
<div class="tt-header-brand">
|
| 935 |
<div class="tt-header-logo">TreeTrack</div>
|
|
|
|
| 1139 |
</div>
|
| 1140 |
|
| 1141 |
<script type="module" src="/static/js/tree-track-app.js?v=5.0.0"></script>
|
| 1142 |
+
|
| 1143 |
+
<script>
|
| 1144 |
+
// Initialize Granim background animation on page load
|
| 1145 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 1146 |
+
// Initialize Granim.js with forest background for header
|
| 1147 |
+
var headerGranimInstance = new Granim({
|
| 1148 |
+
element: '#header-canvas',
|
| 1149 |
+
direction: 'diagonal',
|
| 1150 |
+
isPausedWhenNotInView: true,
|
| 1151 |
+
image: {
|
| 1152 |
+
source: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?q=80&w=1200&auto=format&fit=crop&ixlib=rb-4.0.3',
|
| 1153 |
+
blendingMode: 'overlay',
|
| 1154 |
+
stretchMode: 'stretch'
|
| 1155 |
+
},
|
| 1156 |
+
states: {
|
| 1157 |
+
"default-state": {
|
| 1158 |
+
gradients: [
|
| 1159 |
+
['#29323c', '#485563'],
|
| 1160 |
+
['#FF6B6B', '#556270'],
|
| 1161 |
+
['#80d3fe', '#7ea0c4'],
|
| 1162 |
+
['#f0ab51', '#eceba3']
|
| 1163 |
+
],
|
| 1164 |
+
transitionSpeed: 7000
|
| 1165 |
+
}
|
| 1166 |
+
}
|
| 1167 |
+
});
|
| 1168 |
+
});
|
| 1169 |
+
</script>
|
| 1170 |
</body>
|
| 1171 |
</html>
|
static/login.html
CHANGED
|
@@ -359,67 +359,14 @@
|
|
| 359 |
|
| 360 |
// Auto-fill demo username on page load for development
|
| 361 |
document.addEventListener('DOMContentLoaded', () => {
|
| 362 |
-
// Initialize Granim.js with forest background
|
| 363 |
var granimInstance = new Granim({
|
| 364 |
element: '#granim-canvas',
|
| 365 |
-
direction: '
|
| 366 |
isPausedWhenNotInView: true,
|
| 367 |
image: {
|
| 368 |
-
source: '
|
| 369 |
-
|
| 370 |
-
<!-- Forest Silhouette Background -->
|
| 371 |
-
<defs>
|
| 372 |
-
<linearGradient id="skyGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
| 373 |
-
<stop offset="0%" style="stop-color:#87ceeb;stop-opacity:0.1" />
|
| 374 |
-
<stop offset="100%" style="stop-color:#deb887;stop-opacity:0.05" />
|
| 375 |
-
</linearGradient>
|
| 376 |
-
</defs>
|
| 377 |
-
|
| 378 |
-
<!-- Sky gradient -->
|
| 379 |
-
<rect width="800" height="400" fill="url(#skyGrad)" />
|
| 380 |
-
|
| 381 |
-
<!-- Mountain silhouettes -->
|
| 382 |
-
<path d="M0,300 Q200,250 400,300 Q600,250 800,300 L800,400 L0,400 Z" fill="#2d5a2d" opacity="0.15"/>
|
| 383 |
-
<path d="M0,350 Q150,300 300,350 Q500,300 650,350 Q750,320 800,350 L800,400 L0,400 Z" fill="#1a4d1a" opacity="0.2"/>
|
| 384 |
-
|
| 385 |
-
<!-- Tree line silhouettes -->
|
| 386 |
-
<g opacity="0.25" fill="#0f3d0f">
|
| 387 |
-
<!-- Large background trees -->
|
| 388 |
-
<ellipse cx="100" cy="380" rx="25" ry="40"/>
|
| 389 |
-
<ellipse cx="180" cy="375" rx="30" ry="45"/>
|
| 390 |
-
<ellipse cx="250" cy="385" rx="20" ry="35"/>
|
| 391 |
-
<ellipse cx="320" cy="380" rx="35" ry="50"/>
|
| 392 |
-
<ellipse cx="420" cy="375" rx="25" ry="40"/>
|
| 393 |
-
<ellipse cx="500" cy="385" rx="30" ry="45"/>
|
| 394 |
-
<ellipse cx="580" cy="380" rx="20" ry="35"/>
|
| 395 |
-
<ellipse cx="650" cy="375" rx="25" ry="40"/>
|
| 396 |
-
<ellipse cx="720" cy="385" rx="30" ry="45"/>
|
| 397 |
-
</g>
|
| 398 |
-
|
| 399 |
-
<!-- Foreground tree details -->
|
| 400 |
-
<g opacity="0.3" fill="#0a330a">
|
| 401 |
-
<!-- Individual tree shapes -->
|
| 402 |
-
<circle cx="150" cy="370" r="18"/>
|
| 403 |
-
<circle cx="280" cy="365" r="22"/>
|
| 404 |
-
<circle cx="380" cy="375" r="16"/>
|
| 405 |
-
<circle cx="520" cy="370" r="20"/>
|
| 406 |
-
<circle cx="620" cy="365" r="18"/>
|
| 407 |
-
|
| 408 |
-
<!-- Tree trunks -->
|
| 409 |
-
<rect x="148" y="375" width="4" height="25" fill="#4d2d1a"/>
|
| 410 |
-
<rect x="278" y="370" width="4" height="30" fill="#4d2d1a"/>
|
| 411 |
-
<rect x="378" y="380" width="4" height="20" fill="#4d2d1a"/>
|
| 412 |
-
<rect x="518" y="375" width="4" height="25" fill="#4d2d1a"/>
|
| 413 |
-
<rect x="618" y="370" width="4" height="30" fill="#4d2d1a"/>
|
| 414 |
-
</g>
|
| 415 |
-
|
| 416 |
-
<!-- Misty ground fog -->
|
| 417 |
-
<ellipse cx="200" cy="420" rx="150" ry="20" fill="white" opacity="0.08"/>
|
| 418 |
-
<ellipse cx="500" cy="425" rx="200" ry="15" fill="white" opacity="0.06"/>
|
| 419 |
-
<ellipse cx="650" cy="418" rx="120" ry="18" fill="white" opacity="0.07"/>
|
| 420 |
-
</svg>
|
| 421 |
-
`),
|
| 422 |
-
blendingMode: 'overlay',
|
| 423 |
stretchMode: 'stretch'
|
| 424 |
},
|
| 425 |
states: {
|
|
|
|
| 359 |
|
| 360 |
// Auto-fill demo username on page load for development
|
| 361 |
document.addEventListener('DOMContentLoaded', () => {
|
| 362 |
+
// Initialize Granim.js with actual forest background image
|
| 363 |
var granimInstance = new Granim({
|
| 364 |
element: '#granim-canvas',
|
| 365 |
+
direction: 'top-bottom',
|
| 366 |
isPausedWhenNotInView: true,
|
| 367 |
image: {
|
| 368 |
+
source: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?q=80&w=1200&auto=format&fit=crop&ixlib=rb-4.0.3',
|
| 369 |
+
blendingMode: 'multiply',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
stretchMode: 'stretch'
|
| 371 |
},
|
| 372 |
states: {
|
static/map.html
CHANGED
|
@@ -11,6 +11,8 @@
|
|
| 11 |
<!-- Leaflet CSS -->
|
| 12 |
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
| 13 |
<link rel="stylesheet" href="/static/css/design-system.css">
|
|
|
|
|
|
|
| 14 |
|
| 15 |
<style>
|
| 16 |
|
|
@@ -92,29 +94,26 @@
|
|
| 92 |
flex-direction: column;
|
| 93 |
}
|
| 94 |
|
| 95 |
-
/* Map-specific header styling */
|
| 96 |
.map-header {
|
| 97 |
-
background: var(--gradient-primary);
|
| 98 |
position: relative;
|
| 99 |
overflow: hidden;
|
| 100 |
}
|
| 101 |
|
| 102 |
-
|
| 103 |
-
|
| 104 |
position: absolute;
|
| 105 |
top: 0;
|
| 106 |
left: 0;
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
background-size: 200px 20px;
|
| 111 |
-
background-position: bottom;
|
| 112 |
-
animation: wave 8s linear infinite;
|
| 113 |
}
|
| 114 |
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
|
|
|
| 118 |
}
|
| 119 |
|
| 120 |
.header-stats {
|
|
@@ -746,6 +745,9 @@
|
|
| 746 |
<div class="app-container">
|
| 747 |
<!-- Header -->
|
| 748 |
<div class="tt-header map-header">
|
|
|
|
|
|
|
|
|
|
| 749 |
<div class="tt-header-content">
|
| 750 |
<div class="tt-header-brand">
|
| 751 |
<div class="tt-header-logo">TreeTrack Map</div>
|
|
@@ -852,5 +854,33 @@
|
|
| 852 |
<!-- Leaflet JS -->
|
| 853 |
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
| 854 |
<script src="/static/map.js?v=4.0.0&t=1754657582"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 855 |
</body>
|
| 856 |
</html>
|
|
|
|
| 11 |
<!-- Leaflet CSS -->
|
| 12 |
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
| 13 |
<link rel="stylesheet" href="/static/css/design-system.css">
|
| 14 |
+
<!-- Granim.js for gradient animations -->
|
| 15 |
+
<script src="https://cdn.jsdelivr.net/npm/granim@2.0.0/dist/granim.min.js"></script>
|
| 16 |
|
| 17 |
<style>
|
| 18 |
|
|
|
|
| 94 |
flex-direction: column;
|
| 95 |
}
|
| 96 |
|
| 97 |
+
/* Map-specific header styling with Granim */
|
| 98 |
.map-header {
|
|
|
|
| 99 |
position: relative;
|
| 100 |
overflow: hidden;
|
| 101 |
}
|
| 102 |
|
| 103 |
+
/* Granim Canvas for Map Header */
|
| 104 |
+
#map-header-canvas {
|
| 105 |
position: absolute;
|
| 106 |
top: 0;
|
| 107 |
left: 0;
|
| 108 |
+
width: 100%;
|
| 109 |
+
height: 100%;
|
| 110 |
+
z-index: 1;
|
|
|
|
|
|
|
|
|
|
| 111 |
}
|
| 112 |
|
| 113 |
+
/* Ensure header content is above canvas */
|
| 114 |
+
.tt-header-content {
|
| 115 |
+
position: relative;
|
| 116 |
+
z-index: 2;
|
| 117 |
}
|
| 118 |
|
| 119 |
.header-stats {
|
|
|
|
| 745 |
<div class="app-container">
|
| 746 |
<!-- Header -->
|
| 747 |
<div class="tt-header map-header">
|
| 748 |
+
<!-- Granim Canvas for Map Header Background -->
|
| 749 |
+
<canvas id="map-header-canvas"></canvas>
|
| 750 |
+
|
| 751 |
<div class="tt-header-content">
|
| 752 |
<div class="tt-header-brand">
|
| 753 |
<div class="tt-header-logo">TreeTrack Map</div>
|
|
|
|
| 854 |
<!-- Leaflet JS -->
|
| 855 |
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
| 856 |
<script src="/static/map.js?v=4.0.0&t=1754657582"></script>
|
| 857 |
+
|
| 858 |
+
<script>
|
| 859 |
+
// Initialize Granim background animation on page load
|
| 860 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 861 |
+
// Initialize Granim.js with forest background for map header
|
| 862 |
+
var mapHeaderGranimInstance = new Granim({
|
| 863 |
+
element: '#map-header-canvas',
|
| 864 |
+
direction: 'radial',
|
| 865 |
+
isPausedWhenNotInView: true,
|
| 866 |
+
image: {
|
| 867 |
+
source: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?q=80&w=1200&auto=format&fit=crop&ixlib=rb-4.0.3',
|
| 868 |
+
blendingMode: 'multiply',
|
| 869 |
+
stretchMode: 'stretch'
|
| 870 |
+
},
|
| 871 |
+
states: {
|
| 872 |
+
"default-state": {
|
| 873 |
+
gradients: [
|
| 874 |
+
['#29323c', '#485563'],
|
| 875 |
+
['#FF6B6B', '#556270'],
|
| 876 |
+
['#80d3fe', '#7ea0c4'],
|
| 877 |
+
['#f0ab51', '#eceba3']
|
| 878 |
+
],
|
| 879 |
+
transitionSpeed: 7000
|
| 880 |
+
}
|
| 881 |
+
}
|
| 882 |
+
});
|
| 883 |
+
});
|
| 884 |
+
</script>
|
| 885 |
</body>
|
| 886 |
</html>
|