Onise commited on
Commit
32112d6
·
verified ·
1 Parent(s): 9845c22

create a zone selector for clothes

Browse files
Files changed (2) hide show
  1. components/clothes-selector.js +158 -0
  2. index.html +2 -2
components/clothes-selector.js ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class ClothesSelector extends HTMLElement {
2
+ constructor() {
3
+ super();
4
+ this.selectionPoints = [];
5
+ this.selectionMode = false;
6
+ this.attachShadow({ mode: 'open' });
7
+ }
8
+
9
+ connectedCallback() {
10
+ this.render();
11
+ this.setupEventListeners();
12
+ }
13
+
14
+ render() {
15
+ this.shadowRoot.innerHTML = `
16
+ <style>
17
+ .selector-container {
18
+ position: relative;
19
+ display: inline-block;
20
+ }
21
+ canvas {
22
+ position: absolute;
23
+ top: 0;
24
+ left: 0;
25
+ pointer-events: none;
26
+ }
27
+ img {
28
+ display: block;
29
+ max-width: 100%;
30
+ cursor: crosshair;
31
+ }
32
+ .tools {
33
+ margin-top: 1rem;
34
+ display: flex;
35
+ gap: 0.5rem;
36
+ }
37
+ button {
38
+ padding: 0.5rem 1rem;
39
+ border-radius: 0.25rem;
40
+ cursor: pointer;
41
+ border: none;
42
+ background: #6366f1;
43
+ color: white;
44
+ font-weight: 500;
45
+ }
46
+ button:hover {
47
+ opacity: 0.9;
48
+ }
49
+ button.clear {
50
+ background: #ef4444;
51
+ }
52
+ button.download {
53
+ background: #10b981;
54
+ }
55
+ </style>
56
+ <div class="selector-container">
57
+ <img id="previewImage" src="#" alt="Clothing Preview">
58
+ <canvas id="selectionCanvas"></canvas>
59
+ </div>
60
+ <div class="tools">
61
+ <button id="selectBtn">Select Area</button>
62
+ <button id="clearBtn" class="clear">Clear</button>
63
+ <button id="downloadBtn" class="download">Download</button>
64
+ </div>
65
+ `;
66
+ }
67
+
68
+ setupEventListeners() {
69
+ const img = this.shadowRoot.getElementById('previewImage');
70
+ const canvas = this.shadowRoot.getElementById('selectionCanvas');
71
+ const ctx = canvas.getContext('2d');
72
+ const selectBtn = this.shadowRoot.getElementById('selectBtn');
73
+ const clearBtn = this.shadowRoot.getElementById('clearBtn');
74
+ const downloadBtn = this.shadowRoot.getElementById('downloadBtn');
75
+
76
+ selectBtn.addEventListener('click', () => {
77
+ this.selectionMode = true;
78
+ this.selectionPoints = [];
79
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
80
+ img.style.cursor = 'crosshair';
81
+ });
82
+
83
+ clearBtn.addEventListener('click', () => {
84
+ this.selectionPoints = [];
85
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
86
+ img.style.cursor = 'default';
87
+ this.selectionMode = false;
88
+ });
89
+
90
+ downloadBtn.addEventListener('click', () => {
91
+ if (this.selectionPoints.length > 0) {
92
+ const tempCanvas = document.createElement('canvas');
93
+ const tempCtx = tempCanvas.getContext('2d');
94
+ tempCanvas.width = img.naturalWidth;
95
+ tempCanvas.height = img.naturalHeight;
96
+
97
+ tempCtx.drawImage(img, 0, 0);
98
+ tempCtx.globalCompositeOperation = 'destination-in';
99
+ tempCtx.fillStyle = 'black';
100
+ tempCtx.beginPath();
101
+ tempCtx.moveTo(this.selectionPoints[0].x, this.selectionPoints[0].y);
102
+ for (let i = 1; i < this.selectionPoints.length; i++) {
103
+ tempCtx.lineTo(this.selectionPoints[i].x, this.selectionPoints[i].y);
104
+ }
105
+ tempCtx.closePath();
106
+ tempCtx.fill();
107
+
108
+ const link = document.createElement('a');
109
+ link.download = 'selected-clothing.png';
110
+ link.href = tempCanvas.toDataURL('image/png');
111
+ link.click();
112
+ }
113
+ });
114
+
115
+ img.addEventListener('click', (e) => {
116
+ if (!this.selectionMode) return;
117
+
118
+ const rect = img.getBoundingClientRect();
119
+ const x = e.clientX - rect.left;
120
+ const y = e.clientY - rect.top;
121
+
122
+ this.selectionPoints.push({x, y});
123
+
124
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
125
+ ctx.strokeStyle = '#3B82F6';
126
+ ctx.lineWidth = 2;
127
+ ctx.fillStyle = 'rgba(59, 130, 246, 0.2)';
128
+
129
+ if (this.selectionPoints.length > 0) {
130
+ ctx.beginPath();
131
+ ctx.moveTo(this.selectionPoints[0].x, this.selectionPoints[0].y);
132
+
133
+ for (let i = 1; i < this.selectionPoints.length; i++) {
134
+ ctx.lineTo(this.selectionPoints[i].x, this.selectionPoints[i].y);
135
+ }
136
+
137
+ if (this.selectionPoints.length > 2) {
138
+ ctx.closePath();
139
+ ctx.fill();
140
+ }
141
+
142
+ ctx.stroke();
143
+ }
144
+ });
145
+
146
+ img.addEventListener('load', () => {
147
+ canvas.width = img.naturalWidth;
148
+ canvas.height = img.naturalHeight;
149
+ });
150
+ }
151
+
152
+ setImage(src) {
153
+ const img = this.shadowRoot.getElementById('previewImage');
154
+ img.src = src;
155
+ }
156
+ }
157
+
158
+ customElements.define('clothes-selector', ClothesSelector);
index.html CHANGED
@@ -90,11 +90,11 @@
90
  </main>
91
 
92
  <custom-footer></custom-footer>
93
-
94
  <script src="components/navbar.js"></script>
95
  <script src="components/footer.js"></script>
 
96
  <script src="script.js"></script>
97
- <script>
98
  feather.replace();
99
  </script>
100
  <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
 
90
  </main>
91
 
92
  <custom-footer></custom-footer>
 
93
  <script src="components/navbar.js"></script>
94
  <script src="components/footer.js"></script>
95
+ <script src="components/clothes-selector.js"></script>
96
  <script src="script.js"></script>
97
+ <script>
98
  feather.replace();
99
  </script>
100
  <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>