dlindh commited on
Commit
43425bf
·
verified ·
1 Parent(s): 2a2cd71

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +310 -19
  3. prompts.txt +2 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Image Rater
3
- emoji: 💻
4
- colorFrom: red
5
- colorTo: red
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: image-rater
3
+ emoji: 🐳
4
+ colorFrom: pink
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,310 @@
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>Image Rating System</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ .rating-line {
10
+ background: linear-gradient(to right, red, yellow, green);
11
+ }
12
+ .draggable-image {
13
+ transition: transform 0.2s;
14
+ }
15
+ .draggable-image.dragging {
16
+ opacity: 0.5;
17
+ transform: scale(1.1);
18
+ }
19
+ .drop-zone {
20
+ transition: background-color 0.2s;
21
+ }
22
+ .drop-zone.highlight {
23
+ background-color: rgba(0, 0, 0, 0.1);
24
+ }
25
+ </style>
26
+ </head>
27
+ <body class="bg-gray-100 min-h-screen">
28
+ <div class="container mx-auto px-4 py-8">
29
+ <div class="max-w-4xl mx-auto bg-white rounded-xl shadow-md overflow-hidden p-6">
30
+ <h1 class="text-3xl font-bold text-center text-indigo-700 mb-6">Rate These Images</h1>
31
+
32
+ <div class="mb-8">
33
+ <label for="username" class="block text-sm font-medium text-gray-700 mb-2">Your Username</label>
34
+ <input type="text" id="username"
35
+ class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"
36
+ placeholder="Enter your username">
37
+ </div>
38
+
39
+ <div class="mb-6">
40
+ <p class="text-sm text-gray-600 mb-2">Drag and drop images on the line below from <span class="font-bold text-red-500">worst</span> to <span class="font-bold text-green-600">best</span></p>
41
+ <div class="rating-line h-4 rounded-full mb-4 relative">
42
+ <div class="absolute left-0 -bottom-6 text-xs text-red-500">Worst</div>
43
+ <div class="absolute right-0 -bottom-6 text-xs text-green-600">Best</div>
44
+ </div>
45
+
46
+ <div id="image-container" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-5 gap-4 mb-8">
47
+ <!-- Images will be loaded here -->
48
+ </div>
49
+
50
+ <div id="rating-line-container" class="relative h-32 bg-gray-100 rounded-lg drop-zone p-4">
51
+ <div class="absolute inset-0 flex items-center justify-center text-gray-400" id="empty-message">
52
+ Drag images here to rate them
53
+ </div>
54
+ <div id="rating-area" class="relative h-full flex items-center"></div>
55
+ </div>
56
+ </div>
57
+
58
+ <div class="flex justify-center">
59
+ <button id="submit-btn"
60
+ class="px-6 py-3 bg-indigo-600 text-white font-medium rounded-md hover:bg-indigo-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
61
+ disabled>
62
+ Submit Ratings
63
+ </button>
64
+ </div>
65
+ </div>
66
+ </div>
67
+
68
+ <script>
69
+ document.addEventListener('DOMContentLoaded', function() {
70
+ // Image data
71
+ const images = [
72
+ { id: 1, url: "https://www.vectorstock.com/royalty-free-vector/square-shapes-in-different-colors-vector-29224168" },
73
+ { id: 2, url: "https://www.freepik.com/premium-vector/colorful-square-with-squares-different-colors_40716687.htm" },
74
+ { id: 3, url: "https://www.freepik.com/premium-ai-image/colorful-square-with-many-squares-different-colors_61409150.htm" },
75
+ { id: 4, url: "https://www.pinterest.com/pin/242631498655376169/" },
76
+ { id: 5, url: "https://www.vectorstock.com/royalty-free-vector/colourful-squares-vector-2709299" },
77
+ { id: 6, url: "https://pixabay.com/en/color-square-arrangement-tile-198892/" },
78
+ { id: 7, url: "https://www.dreamstime.com/stock-illustration-set-geometric-shapes-made-up-squares-different-colors-image52041527" },
79
+ { id: 8, url: "https://www.dreamstime.com/royalty-free-stock-photography-color-squares-two-different-sizes-shadow-beige-background-image37420697" },
80
+ { id: 9, url: "https://www.teachercreated.com/products/spot-on-carpet-markers-colorful-squares-4-77049" },
81
+ { id: 10, url: "https://www.vectorstock.com/royalty-free-vector/background-different-colors-separated-squares-vector-32141203" }
82
+ ];
83
+
84
+ const imageContainer = document.getElementById('image-container');
85
+ const ratingArea = document.getElementById('rating-area');
86
+ const emptyMessage = document.getElementById('empty-message');
87
+ const submitBtn = document.getElementById('submit-btn');
88
+ const usernameInput = document.getElementById('username');
89
+ const ratingLineContainer = document.getElementById('rating-line-container');
90
+
91
+ // Load images into the container
92
+ images.forEach(image => {
93
+ const imgElement = document.createElement('div');
94
+ imgElement.className = 'draggable-image cursor-move bg-white p-2 rounded-lg shadow-md hover:shadow-lg transition-shadow';
95
+ imgElement.draggable = true;
96
+ imgElement.dataset.id = image.id;
97
+
98
+ imgElement.innerHTML = `
99
+ <img src="${image.url}" alt="Image ${image.id}" class="w-full h-24 object-cover rounded">
100
+ <div class="text-center mt-1 text-xs text-gray-600">Image ${image.id}</div>
101
+ `;
102
+
103
+ imgElement.addEventListener('dragstart', handleDragStart);
104
+ imgElement.addEventListener('dragend', handleDragEnd);
105
+
106
+ imageContainer.appendChild(imgElement);
107
+ });
108
+
109
+ // Rating line event listeners
110
+ ratingLineContainer.addEventListener('dragover', handleDragOver);
111
+ ratingLineContainer.addEventListener('dragleave', handleDragLeave);
112
+ ratingLineContainer.addEventListener('drop', handleDrop);
113
+
114
+ // Username input validation
115
+ usernameInput.addEventListener('input', validateForm);
116
+
117
+ // Submit button handler
118
+ submitBtn.addEventListener('click', submitRatings);
119
+
120
+ let draggedItem = null;
121
+ let isFromRatingArea = false;
122
+
123
+ function handleDragStart(e) {
124
+ draggedItem = e.target.closest('.draggable-image');
125
+ isFromRatingArea = draggedItem.parentElement === ratingArea;
126
+ e.dataTransfer.setData('text/plain', draggedItem.dataset.id);
127
+ setTimeout(() => {
128
+ draggedItem.classList.add('dragging', 'opacity-50', 'scale-110');
129
+ }, 0);
130
+ }
131
+
132
+ function handleDragEnd() {
133
+ draggedItem.classList.remove('dragging', 'opacity-50', 'scale-110');
134
+ draggedItem = null;
135
+ isFromRatingArea = false;
136
+ }
137
+
138
+ function handleDragOver(e) {
139
+ e.preventDefault();
140
+ ratingLineContainer.classList.add('highlight');
141
+ }
142
+
143
+ function handleDragLeave() {
144
+ ratingLineContainer.classList.remove('highlight');
145
+ }
146
+
147
+ function handleDrop(e) {
148
+ e.preventDefault();
149
+ ratingLineContainer.classList.remove('highlight');
150
+
151
+ const id = e.dataTransfer.getData('text/plain');
152
+ const droppedImage = document.querySelector(`.draggable-image[data-id="${id}"]`);
153
+
154
+ // If the image is already in the rating area, just update its position
155
+ if (isFromRatingArea) {
156
+ updateImagePosition(droppedImage, e.clientX);
157
+ return;
158
+ }
159
+
160
+ // Check if this image is already in the rating area
161
+ const existingImage = ratingArea.querySelector(`.draggable-image[data-id="${id}"]`);
162
+ if (existingImage) {
163
+ updateImagePosition(existingImage, e.clientX);
164
+ return;
165
+ }
166
+
167
+ // Remove from original container
168
+ droppedImage.remove();
169
+
170
+ // Add to rating area
171
+ positionNewImage(droppedImage, e.clientX);
172
+ ratingArea.appendChild(droppedImage);
173
+
174
+ // Update empty message
175
+ if (ratingArea.children.length > 0) {
176
+ emptyMessage.style.display = 'none';
177
+ }
178
+
179
+ validateForm();
180
+ }
181
+
182
+ function positionNewImage(imageElement, clientX) {
183
+ const rect = ratingArea.getBoundingClientRect();
184
+ const xPos = clientX - rect.left;
185
+ const percentage = Math.min(100, Math.max(0, (xPos / rect.width) * 100));
186
+
187
+ imageElement.style.position = 'absolute';
188
+ imageElement.style.left = `${percentage}%`;
189
+ imageElement.style.transform = 'translateX(-50%)';
190
+
191
+ // Set initial rating based on position
192
+ const rating = Math.round((percentage / 100) * 9) + 1; // 1-10 scale
193
+ imageElement.dataset.rating = rating;
194
+
195
+ // Add rating indicator
196
+ const ratingIndicator = document.createElement('div');
197
+ ratingIndicator.className = 'absolute -bottom-6 left-1/2 transform -translate-x-1/2 text-xs font-bold';
198
+ ratingIndicator.textContent = rating;
199
+ ratingIndicator.style.color = getRatingColor(rating);
200
+ imageElement.appendChild(ratingIndicator);
201
+ }
202
+
203
+ function updateImagePosition(imageElement, clientX) {
204
+ const rect = ratingArea.getBoundingClientRect();
205
+ const xPos = clientX - rect.left;
206
+ const percentage = Math.min(100, Math.max(0, (xPos / rect.width) * 100));
207
+
208
+ imageElement.style.left = `${percentage}%`;
209
+
210
+ // Update rating based on new position
211
+ const rating = Math.round((percentage / 100) * 9) + 1; // 1-10 scale
212
+ imageElement.dataset.rating = rating;
213
+
214
+ // Update rating indicator
215
+ const ratingIndicator = imageElement.querySelector('div:last-child');
216
+ ratingIndicator.textContent = rating;
217
+ ratingIndicator.style.color = getRatingColor(rating);
218
+ }
219
+
220
+ function getRatingColor(rating) {
221
+ // Red (1) to yellow (5) to green (10)
222
+ if (rating <= 3) return '#ef4444'; // red-500
223
+ if (rating <= 6) return '#eab308'; // yellow-500
224
+ return '#22c55e'; // green-500
225
+ }
226
+
227
+ function validateForm() {
228
+ const hasRatings = ratingArea.children.length > 0;
229
+ const hasUsername = usernameInput.value.trim().length > 0;
230
+
231
+ submitBtn.disabled = !(hasRatings && hasUsername);
232
+ }
233
+
234
+ async function submitRatings() {
235
+ const username = usernameInput.value.trim();
236
+ const ratings = [];
237
+
238
+ Array.from(ratingArea.children).forEach(item => {
239
+ ratings.push({
240
+ imageId: parseInt(item.dataset.id),
241
+ rating: parseInt(item.dataset.rating)
242
+ });
243
+ });
244
+
245
+ // Prepare data for API
246
+ const data = {
247
+ username,
248
+ ratings
249
+ };
250
+
251
+ // In a real app, you would send this to your API
252
+ console.log('Submitting data:', data);
253
+
254
+ // Simulate API call
255
+ submitBtn.disabled = true;
256
+ submitBtn.textContent = 'Submitting...';
257
+
258
+ try {
259
+ // Replace with actual API call
260
+ // const response = await fetch('your-api-endpoint', {
261
+ // method: 'POST',
262
+ // headers: {
263
+ // 'Content-Type': 'application/json',
264
+ // },
265
+ // body: JSON.stringify(data)
266
+ // });
267
+
268
+ // Simulate API delay
269
+ await new Promise(resolve => setTimeout(resolve, 1500));
270
+
271
+ // Show success message
272
+ alert('Your ratings have been submitted successfully!');
273
+
274
+ // Reset form
275
+ usernameInput.value = '';
276
+ ratingArea.innerHTML = '';
277
+ emptyMessage.style.display = 'block';
278
+ submitBtn.disabled = true;
279
+ submitBtn.textContent = 'Submit Ratings';
280
+
281
+ // Reload images
282
+ imageContainer.innerHTML = '';
283
+ images.forEach(image => {
284
+ const imgElement = document.createElement('div');
285
+ imgElement.className = 'draggable-image cursor-move bg-white p-2 rounded-lg shadow-md hover:shadow-lg transition-shadow';
286
+ imgElement.draggable = true;
287
+ imgElement.dataset.id = image.id;
288
+
289
+ imgElement.innerHTML = `
290
+ <img src="${image.url}" alt="Image ${image.id}" class="w-full h-24 object-cover rounded">
291
+ <div class="text-center mt-1 text-xs text-gray-600">Image ${image.id}</div>
292
+ `;
293
+
294
+ imgElement.addEventListener('dragstart', handleDragStart);
295
+ imgElement.addEventListener('dragend', handleDragEnd);
296
+
297
+ imageContainer.appendChild(imgElement);
298
+ });
299
+
300
+ } catch (error) {
301
+ console.error('Error submitting ratings:', error);
302
+ alert('There was an error submitting your ratings. Please try again.');
303
+ submitBtn.disabled = false;
304
+ submitBtn.textContent = 'Submit Ratings';
305
+ }
306
+ }
307
+ });
308
+ </script>
309
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=dlindh/image-rater" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
310
+ </html>
prompts.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ create website where people can drag and drop images on a line from "worst" to "best". There should also be a username field and a submit button. When the button is pressed the information should be posted to an api with all the image ids, their rating (from 1-10), and the username. The you should be able to drag and drop and rearrange the images as you like. use these images const image1 = "https://www.vectorstock.com/royalty-free-vector/square-shapes-in-different-colors-vector-29224168"; const image2 = "https://www.freepik.com/premium-vector/colorful-square-with-squares-different-colors_40716687.htm"; const image3 = "https://www.freepik.com/premium-ai-image/colorful-square-with-many-squares-different-colors_61409150.htm"; const image4 = "https://www.pinterest.com/pin/242631498655376169/"; const image5 = "https://www.vectorstock.com/royalty-free-vector/colourful-squares-vector-2709299"; const image6 = "https://pixabay.com/en/color-square-arrangement-tile-198892/"; const image7 = "https://www.dreamstime.com/stock-illustration-set-geometric-shapes-made-up-squares-different-colors-image52041527"; const image8 = "https://www.dreamstime.com/royalty-free-stock-photography-color-squares-two-different-sizes-shadow-beige-background-image37420697"; const image9 = "https://www.teachercreated.com/products/spot-on-carpet-markers-colorful-squares-4-77049"; const image10 = "https://www.vectorstock.com/royalty-free-vector/background-different-colors-separated-squares-vector-32141203";
2
+ Almost right! Now when I drag the same image again it copies instead of just moving. So I get doubles of the same image. I just want to be able to rearrange the same image