Tingchenliang commited on
Commit
ced83f7
·
verified ·
1 Parent(s): bf0bd45

build a web app in single html with CSS and JS.

Browse files

APP 概念:健身资历测试“你有几年经验?”

拍照 / 上传图像后,点击按钮,跳转输出总结报告,如:“你有 3 年健身经验,是*浣熊*类型的健身达人,超过了 99% 的熊系用户"

- 语言全英

- 以白、tiffany 绿、鹅蛋黄为主的UI,light mode,不要渐层

- static,只是一个 demo 简单模拟,不需要调用任何 API,不管上传什么照片,报告结果直接显示“你有 3 年健身经验,是*浣熊*类型的健身达人,超过了 99% 的熊系用户"

Files changed (4) hide show
  1. README.md +8 -5
  2. index.html +156 -19
  3. script.js +103 -0
  4. style.css +77 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Fitness Fortune
3
- emoji: 🐠
4
- colorFrom: pink
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: Fitness Fortune 🏋️‍♂️
3
+ colorFrom: blue
4
+ colorTo: green
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
index.html CHANGED
@@ -1,19 +1,156 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Fitness Fortune - How experienced are you?</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
10
+ <script src="https://unpkg.com/feather-icons"></script>
11
+ <link rel="stylesheet" href="style.css">
12
+ </head>
13
+ <body class="min-h-screen bg-white flex flex-col">
14
+ <header class="bg-tiffany-green p-6 shadow-sm">
15
+ <div class="container mx-auto">
16
+ <h1 class="text-3xl font-bold text-white text-center flex items-center justify-center gap-3">
17
+ <i data-feather="activity"></i>
18
+ Fitness Fortune
19
+ </h1>
20
+ <p class="text-center text-white/90 mt-2">Discover your fitness experience level</p>
21
+ </div>
22
+ </header>
23
+
24
+ <main class="flex-grow container mx-auto px-4 py-8 max-w-2xl">
25
+ <!-- Upload Section -->
26
+ <section id="uploadSection" class="space-y-6">
27
+ <div class="bg-duck-egg-yellow rounded-2xl p-8 shadow-lg">
28
+ <h2 class="text-2xl font-semibold text-gray-800 mb-4 text-center">
29
+ Upload Your Photo
30
+ </h2>
31
+ <p class="text-gray-600 text-center mb-6">
32
+ Take or upload a photo to reveal your fitness experience
33
+ </p>
34
+
35
+ <div id="uploadArea" class="border-3 border-dashed border-tiffany-green rounded-xl p-12 text-center bg-white cursor-pointer hover:bg-gray-50 transition-colors">
36
+ <div id="uploadContent">
37
+ <i data-feather="camera" class="w-16 h-16 mx-auto text-tiffany-green mb-4"></i>
38
+ <p class="text-gray-700 font-medium mb-2">Click to upload or take a photo</p>
39
+ <p class="text-gray-500 text-sm">JPG, PNG or GIF (MAX. 5MB)</p>
40
+ </div>
41
+ <img id="previewImage" class="hidden mx-auto max-h-64 rounded-lg">
42
+ </div>
43
+
44
+ <input type="file" id="fileInput" class="hidden" accept="image/*" capture="camera">
45
+
46
+ <button id="analyzeBtn" class="hidden mt-6 w-full bg-tiffany-green text-white font-semibold py-4 px-6 rounded-xl hover:bg-opacity-90 transition-all transform hover:scale-105 flex items-center justify-center gap-2">
47
+ <i data-feather="zap"></i>
48
+ Analyze My Fitness Level
49
+ </button>
50
+ </div>
51
+
52
+ <div class="bg-tiffany-green/10 rounded-xl p-6">
53
+ <h3 class="font-semibold text-gray-800 mb-3 flex items-center gap-2">
54
+ <i data-feather="info" class="w-5 h-5 text-tiffany-green"></i>
55
+ How it works
56
+ </h3>
57
+ <ul class="space-y-2 text-gray-600">
58
+ <li class="flex items-start gap-2">
59
+ <i data-feather="check-circle" class="w-5 h-5 text-tiffany-green flex-shrink-0 mt-0.5"></i>
60
+ <span>Upload a photo of yourself</span>
61
+ </li>
62
+ <li class="flex items-start gap-2">
63
+ <i data-feather="check-circle" class="w-5 h-5 text-tiffany-green flex-shrink-0 mt-0.5"></i>
64
+ <span>Our AI analyzes your physique and fitness aura</span>
65
+ </li>
66
+ <li class="flex items-start gap-2">
67
+ <i data-feather="check-circle" class="w-5 h-5 text-tiffany-green flex-shrink-0 mt-0.5"></i>
68
+ <span>Get your personalized fitness profile</span>
69
+ </li>
70
+ </ul>
71
+ </div>
72
+ </section>
73
+
74
+ <!-- Result Section -->
75
+ <section id="resultSection" class="hidden">
76
+ <div class="bg-duck-egg-yellow rounded-2xl p-8 shadow-lg space-y-6">
77
+ <div class="text-center">
78
+ <div class="w-24 h-24 bg-tiffany-green rounded-full flex items-center justify-center mx-auto mb-4">
79
+ <i data-feather="award" class="w-12 h-12 text-white"></i>
80
+ </div>
81
+ <h2 class="text-3xl font-bold text-gray-800 mb-2">Your Fitness Profile</h2>
82
+ </div>
83
+
84
+ <div class="bg-white rounded-xl p-6 space-y-4">
85
+ <div class="flex items-center gap-4">
86
+ <i data-feather="trending-up" class="w-6 h-6 text-tiffany-green"></i>
87
+ <div>
88
+ <p class="text-sm text-gray-500">Experience Level</p>
89
+ <p class="text-xl font-bold text-gray-800">3 Years of Fitness Experience</p>
90
+ </div>
91
+ </div>
92
+
93
+ <div class="flex items-center gap-4">
94
+ <i data-feather="tag" class="w-6 h-6 text-tiffany-green"></i>
95
+ <div>
96
+ <p class="text-sm text-gray-500">Fitness Type</p>
97
+ <p class="text-xl font-bold text-gray-800">
98
+ <span class="text-tiffany-green">Raccoon</span> Type Fitness Enthusiast
99
+ </p>
100
+ </div>
101
+ </div>
102
+
103
+ <div class="flex items-center gap-4">
104
+ <i data-feather="bar-chart-2" class="w-6 h-6 text-tiffany-green"></i>
105
+ <div>
106
+ <p class="text-sm text-gray-500">Ranking</p>
107
+ <p class="text-xl font-bold text-gray-800">
108
+ Top 1% (exceeds 99% of Bear-type users)
109
+ </p>
110
+ </div>
111
+ </div>
112
+ </div>
113
+
114
+ <div class="bg-tiffany-green/10 rounded-xl p-4">
115
+ <p class="text-gray-700 text-center italic">
116
+ "The raccoon type brings agility, curiosity, and surprising strength to every workout!"
117
+ </p>
118
+ </div>
119
+
120
+ <button id="retakeBtn" class="w-full bg-white border-2 border-tiffany-green text-tiffany-green font-semibold py-4 px-6 rounded-xl hover:bg-tiffany-green hover:text-white transition-all transform hover:scale-105 flex items-center justify-center gap-2">
121
+ <i data-feather="refresh-cw"></i>
122
+ Try Another Photo
123
+ </button>
124
+ </div>
125
+
126
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-6">
127
+ <div class="bg-white rounded-xl p-4 text-center shadow-md">
128
+ <i data-feather="target" class="w-8 h-8 text-tiffany-green mx-auto mb-2"></i>
129
+ <p class="font-semibold text-gray-800">Precision</p>
130
+ <p class="text-sm text-gray-600">98% Match</p>
131
+ </div>
132
+ <div class="bg-white rounded-xl p-4 text-center shadow-md">
133
+ <i data-feather="zap" class="w-8 h-8 text-tiffany-green mx-auto mb-2"></i>
134
+ <p class="font-semibold text-gray-800">Energy</p>
135
+ <p class="text-sm text-gray-600">High Level</p>
136
+ </div>
137
+ <div class="bg-white rounded-xl p-4 text-center shadow-md">
138
+ <i data-feather="star" class="w-8 h-8 text-tiffany-green mx-auto mb-2"></i>
139
+ <p class="font-semibold text-gray-800">Potential</p>
140
+ <p class="text-sm text-gray-600">Elite</p>
141
+ </div>
142
+ </div>
143
+ </section>
144
+ </main>
145
+
146
+ <footer class="bg-tiffany-green p-4 mt-8">
147
+ <p class="text-center text-white text-sm">
148
+ © 2024 Fitness Fortune - For entertainment purposes only
149
+ </p>
150
+ </footer>
151
+
152
+ <script src="script.js"></script>
153
+ <script>feather.replace();</script>
154
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
155
+ </body>
156
+ </html>
script.js ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', function() {
2
+ const uploadArea = document.getElementById('uploadArea');
3
+ const fileInput = document.getElementById('fileInput');
4
+ const uploadContent = document.getElementById('uploadContent');
5
+ const previewImage = document.getElementById('previewImage');
6
+ const analyzeBtn = document.getElementById('analyzeBtn');
7
+ const uploadSection = document.getElementById('uploadSection');
8
+ const resultSection = document.getElementById('resultSection');
9
+ const retakeBtn = document.getElementById('retakeBtn');
10
+
11
+ // Upload area click handler
12
+ uploadArea.addEventListener('click', function() {
13
+ fileInput.click();
14
+ });
15
+
16
+ // File input change handler
17
+ fileInput.addEventListener('change', function(e) {
18
+ const file = e.target.files[0];
19
+ if (file && file.type.startsWith('image/')) {
20
+ const reader = new FileReader();
21
+
22
+ reader.onload = function(e) {
23
+ previewImage.src = e.target.result;
24
+ previewImage.classList.remove('hidden');
25
+ uploadContent.classList.add('hidden');
26
+ analyzeBtn.classList.remove('hidden');
27
+ };
28
+
29
+ reader.readAsDataURL(file);
30
+ }
31
+ });
32
+
33
+ // Drag and drop handlers
34
+ uploadArea.addEventListener('dragover', function(e) {
35
+ e.preventDefault();
36
+ this.classList.add('bg-gray-100');
37
+ });
38
+
39
+ uploadArea.addEventListener('dragleave', function(e) {
40
+ e.preventDefault();
41
+ this.classList.remove('bg-gray-100');
42
+ });
43
+
44
+ uploadArea.addEventListener('drop', function(e) {
45
+ e.preventDefault();
46
+ this.classList.remove('bg-gray-100');
47
+
48
+ const files = e.dataTransfer.files;
49
+ if (files.length > 0 && files[0].type.startsWith('image/')) {
50
+ fileInput.files = files;
51
+ const event = new Event('change', { bubbles: true });
52
+ fileInput.dispatchEvent(event);
53
+ }
54
+ });
55
+
56
+ // Analyze button click handler
57
+ analyzeBtn.addEventListener('click', function() {
58
+ // Simulate loading
59
+ this.innerHTML = '<i data-feather="loader" class="animate-spin"></i> Analyzing...';
60
+ this.disabled = true;
61
+
62
+ // Simulate API call delay
63
+ setTimeout(() => {
64
+ showResults();
65
+ }, 2000);
66
+ });
67
+
68
+ // Retake button click handler
69
+ retakeBtn.addEventListener('click', function() {
70
+ resetUpload();
71
+ });
72
+
73
+ function showResults() {
74
+ uploadSection.classList.add('hidden');
75
+ resultSection.classList.remove('hidden');
76
+ resultSection.classList.add('result-card');
77
+
78
+ // Scroll to top of results
79
+ window.scrollTo({ top: 0, behavior: 'smooth' });
80
+
81
+ // Re-initialize feather icons
82
+ feather.replace();
83
+ }
84
+
85
+ function resetUpload() {
86
+ uploadSection.classList.remove('hidden');
87
+ resultSection.classList.add('hidden');
88
+
89
+ // Reset upload area
90
+ previewImage.classList.add('hidden');
91
+ uploadContent.classList.remove('hidden');
92
+ analyzeBtn.classList.add('hidden');
93
+ analyzeBtn.innerHTML = '<i data-feather="zap"></i> Analyze My Fitness Level';
94
+ analyzeBtn.disabled = false;
95
+ fileInput.value = '';
96
+
97
+ // Scroll to top
98
+ window.scrollTo({ top: 0, behavior: 'smooth' });
99
+
100
+ // Re-initialize feather icons
101
+ feather.replace();
102
+ }
103
+ });
style.css CHANGED
@@ -1,28 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
 
 
 
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --tiffany-green: #81D8D0;
3
+ --duck-egg-yellow: #F3E78E;
4
+ }
5
+
6
+ .bg-tiffany-green {
7
+ background-color: var(--tiffany-green);
8
+ }
9
+
10
+ .text-tiffany-green {
11
+ color: var(--tiffany-green);
12
+ }
13
+
14
+ .border-tiffany-green {
15
+ border-color: var(--tiffany-green);
16
+ }
17
+
18
+ .bg-duck-egg-yellow {
19
+ background-color: var(--duck-egg-yellow);
20
+ }
21
+
22
+ .border-3 {
23
+ border-width: 3px;
24
+ }
25
+
26
+ * {
27
+ transition: all 0.3s ease;
28
+ }
29
+
30
  body {
31
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
32
+ }
33
+
34
+ #uploadArea:hover {
35
+ border-color: var(--tiffany-green);
36
+ background-color: rgba(129, 216, 208, 0.05);
37
+ }
38
+
39
+ button:active {
40
+ transform: scale(0.98);
41
+ }
42
+
43
+ #previewImage {
44
+ animation: fadeIn 0.5s ease;
45
+ }
46
+
47
+ @keyframes fadeIn {
48
+ from {
49
+ opacity: 0;
50
+ transform: scale(0.95);
51
+ }
52
+ to {
53
+ opacity: 1;
54
+ transform: scale(1);
55
+ }
56
  }
57
 
58
+ .result-card {
59
+ animation: slideUp 0.6s ease;
 
60
  }
61
 
62
+ @keyframes slideUp {
63
+ from {
64
+ opacity: 0;
65
+ transform: translateY(20px);
66
+ }
67
+ to {
68
+ opacity: 1;
69
+ transform: translateY(0);
70
+ }
71
  }
72
 
73
+ .shadow-lg {
74
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08);
 
 
 
 
75
  }
76
 
77
+ .shadow-md {
78
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.06);
79
  }
80
+
81
+ .hover\:scale-105:hover {
82
+ transform: scale(1.05);
83
+ }
84
+
85
+ .hover\:bg-opacity-90:hover {
86
+ background-color: rgba(129, 216, 208, 0.9);
87
+ }