mkfashion-sdk 1.0.0
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/.vscode/launch.json +15 -0
- package/README.md +62 -0
- package/package.json +19 -0
- package/src/mkfashion.js +437 -0
- package/test.html +235 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"type": "chrome",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"name": "Launch Chrome against localhost",
|
|
11
|
+
"url": "http://localhost:8080",
|
|
12
|
+
"webRoot": "${workspaceFolder}"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# mKFashion SDK
|
|
2
|
+
|
|
3
|
+
SDK para integrar o provador virtual de roupas com IA em qualquer site ou e-commerce.
|
|
4
|
+
|
|
5
|
+
## Instalação
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<script src="https://unpkg.com/mkfashion-sdk/src/mkfashion.js"></script>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Uso Rápido
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
// 1. Registrar callback do carrinho
|
|
15
|
+
mkfashion.addToCart(function(payload) {
|
|
16
|
+
console.log("Produto:", payload.identifier);
|
|
17
|
+
console.log("Tamanho:", payload.size);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// 2. Abrir o provador
|
|
21
|
+
mkfashion.open({
|
|
22
|
+
type: 'iframe',
|
|
23
|
+
projectid: 'minha-loja',
|
|
24
|
+
identifier: 'PRODUTO-001',
|
|
25
|
+
width: 400,
|
|
26
|
+
height: 700
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Documentação
|
|
31
|
+
|
|
32
|
+
- [Introdução](./docs/index.md)
|
|
33
|
+
- [Instalação do Plugin](./docs/instalacao.md)
|
|
34
|
+
- [Abrir o Visualizador](./docs/abrir-visualizador.md)
|
|
35
|
+
- [Integração com Carrinho](./docs/integracao-carrinho.md)
|
|
36
|
+
- [SDK Reference](./docs/sdk-reference.md)
|
|
37
|
+
|
|
38
|
+
## Métodos Disponíveis
|
|
39
|
+
|
|
40
|
+
| Método | Descrição |
|
|
41
|
+
|--------|-----------|
|
|
42
|
+
| `open(options)` | Abre o provador virtual |
|
|
43
|
+
| `close()` | Fecha o provador |
|
|
44
|
+
| `restart()` | Reinicia a experiência |
|
|
45
|
+
| `destroy()` | Remove do DOM |
|
|
46
|
+
| `getStatus()` | Retorna estado atual |
|
|
47
|
+
| `addToCart(callback)` | Callback ao adicionar ao carrinho |
|
|
48
|
+
| `onReady(callback)` | Callback quando pronto |
|
|
49
|
+
| `onClose(callback)` | Callback ao fechar |
|
|
50
|
+
| `onGenerationComplete(callback)` | Callback ao gerar imagem |
|
|
51
|
+
| `onError(callback)` | Callback de erro |
|
|
52
|
+
|
|
53
|
+
## Desenvolvimento
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Testar localmente
|
|
57
|
+
# Abra test.html no navegador
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Licença
|
|
61
|
+
|
|
62
|
+
MIT - metaKosmos
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mkfashion-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "SDK para integrar o provador virtual mKFashion",
|
|
5
|
+
"main": "src/mkfashion.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "echo \"Abra test.html no navegador\""
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"fashion",
|
|
12
|
+
"virtual",
|
|
13
|
+
"try-on",
|
|
14
|
+
"sdk",
|
|
15
|
+
"metakosmos"
|
|
16
|
+
],
|
|
17
|
+
"author": "metaKosmos",
|
|
18
|
+
"license": "MIT"
|
|
19
|
+
}
|
package/src/mkfashion.js
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mKFashion SDK
|
|
3
|
+
* SDK para integrar o provador virtual mKFashion em qualquer site
|
|
4
|
+
*
|
|
5
|
+
* Instalacao:
|
|
6
|
+
* <script src="https://unpkg.com/mkfashion-sdk/src/mkfashion.js"></script>
|
|
7
|
+
*
|
|
8
|
+
* Uso:
|
|
9
|
+
* mkfashion.open({
|
|
10
|
+
* type: 'iframe',
|
|
11
|
+
* projectid: 'gregory',
|
|
12
|
+
* identifier: 'SKU-001',
|
|
13
|
+
* width: 400,
|
|
14
|
+
* height: 700
|
|
15
|
+
* })
|
|
16
|
+
*
|
|
17
|
+
* mkfashion.addToCart(function(payload) {
|
|
18
|
+
* console.log('Produto adicionado:', payload)
|
|
19
|
+
* })
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const mkfashion = {
|
|
23
|
+
|
|
24
|
+
// ============ CONFIGURACAO ============
|
|
25
|
+
|
|
26
|
+
appUrl: 'https://fashion.metakosmos.com/',
|
|
27
|
+
debug: false,
|
|
28
|
+
|
|
29
|
+
// Estado interno
|
|
30
|
+
_iframe: null,
|
|
31
|
+
_modal: null,
|
|
32
|
+
_isOpen: false,
|
|
33
|
+
_config: null,
|
|
34
|
+
_callbacks: {
|
|
35
|
+
onReady: null,
|
|
36
|
+
onClose: null,
|
|
37
|
+
onAddToCart: null,
|
|
38
|
+
onGenerationComplete: null,
|
|
39
|
+
onError: null
|
|
40
|
+
},
|
|
41
|
+
_escHandler: null,
|
|
42
|
+
_messageHandler: null,
|
|
43
|
+
|
|
44
|
+
// ============ METODOS PUBLICOS ============
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Abre o provador virtual
|
|
48
|
+
* @param {Object} options - Configuracoes
|
|
49
|
+
* @param {string} options.type - 'iframe' (modal) ou 'embed' (default: 'iframe')
|
|
50
|
+
* @param {string} options.projectid - Identificador do projeto/empresa (obrigatorio)
|
|
51
|
+
* @param {string} options.identifier - SKU ou ID do produto (obrigatorio)
|
|
52
|
+
* @param {string|number} options.width - Largura (ex: 800 ou '90%')
|
|
53
|
+
* @param {string|number} options.height - Altura (ex: 600 ou '95%')
|
|
54
|
+
* @param {string} options.targetId - ID do container (obrigatorio para type='embed')
|
|
55
|
+
*/
|
|
56
|
+
open(options = {}) {
|
|
57
|
+
if (this._isOpen) {
|
|
58
|
+
this._log('Ja esta aberto')
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Valida opcoes obrigatorias
|
|
63
|
+
if (!options.projectid) {
|
|
64
|
+
console.error('[mKFashion] projectid e obrigatorio')
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
if (!options.identifier) {
|
|
68
|
+
console.error('[mKFashion] identifier e obrigatorio')
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Salva configuracao
|
|
73
|
+
this._config = {
|
|
74
|
+
type: options.type || 'iframe',
|
|
75
|
+
projectid: options.projectid,
|
|
76
|
+
identifier: options.identifier,
|
|
77
|
+
width: options.width || '90%',
|
|
78
|
+
height: options.height || '95%',
|
|
79
|
+
targetId: options.targetId || null
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Inicia listener de mensagens
|
|
83
|
+
this._setupMessageListener()
|
|
84
|
+
|
|
85
|
+
// Abre de acordo com o tipo
|
|
86
|
+
if (this._config.type === 'iframe') {
|
|
87
|
+
this._openModal()
|
|
88
|
+
} else if (this._config.type === 'embed') {
|
|
89
|
+
this._openEmbed()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this._isOpen = true
|
|
93
|
+
this._log('Aberto', this._config)
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Fecha o provador virtual
|
|
98
|
+
*/
|
|
99
|
+
close() {
|
|
100
|
+
if (!this._isOpen) {
|
|
101
|
+
this._log('Ja esta fechado')
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Remove listener de mensagens
|
|
106
|
+
this._removeMessageListener()
|
|
107
|
+
|
|
108
|
+
if (this._config.type === 'iframe') {
|
|
109
|
+
this._closeModal()
|
|
110
|
+
} else if (this._config.type === 'embed') {
|
|
111
|
+
this._closeEmbed()
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Dispara callback de fechamento
|
|
115
|
+
this._triggerCallback('onClose')
|
|
116
|
+
|
|
117
|
+
this._isOpen = false
|
|
118
|
+
this._log('Fechado')
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Registra callback para quando usuario adicionar ao carrinho
|
|
123
|
+
* @param {Function} callback - Funcao que recebe o payload do produto
|
|
124
|
+
*/
|
|
125
|
+
addToCart(callback) {
|
|
126
|
+
if (typeof callback === 'function') {
|
|
127
|
+
this._callbacks.onAddToCart = callback
|
|
128
|
+
this._log('Callback addToCart registrado')
|
|
129
|
+
} else {
|
|
130
|
+
console.error('[mKFashion] addToCart requer uma funcao como parametro')
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Registra callback para quando app estiver pronta
|
|
136
|
+
* @param {Function} callback - Funcao chamada quando app carregar
|
|
137
|
+
*/
|
|
138
|
+
onReady(callback) {
|
|
139
|
+
if (typeof callback === 'function') {
|
|
140
|
+
this._callbacks.onReady = callback
|
|
141
|
+
this._log('Callback onReady registrado')
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Registra callback para quando modal fechar
|
|
147
|
+
* @param {Function} callback - Funcao chamada ao fechar
|
|
148
|
+
*/
|
|
149
|
+
onClose(callback) {
|
|
150
|
+
if (typeof callback === 'function') {
|
|
151
|
+
this._callbacks.onClose = callback
|
|
152
|
+
this._log('Callback onClose registrado')
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Registra callback para quando geracao completar
|
|
158
|
+
* @param {Function} callback - Funcao que recebe dados da geracao
|
|
159
|
+
*/
|
|
160
|
+
onGenerationComplete(callback) {
|
|
161
|
+
if (typeof callback === 'function') {
|
|
162
|
+
this._callbacks.onGenerationComplete = callback
|
|
163
|
+
this._log('Callback onGenerationComplete registrado')
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Registra callback para erros
|
|
169
|
+
* @param {Function} callback - Funcao que recebe dados do erro
|
|
170
|
+
*/
|
|
171
|
+
onError(callback) {
|
|
172
|
+
if (typeof callback === 'function') {
|
|
173
|
+
this._callbacks.onError = callback
|
|
174
|
+
this._log('Callback onError registrado')
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Reinicia a experiencia (volta para tela de instrucoes)
|
|
180
|
+
*/
|
|
181
|
+
restart() {
|
|
182
|
+
if (!this._iframe || !this._config) {
|
|
183
|
+
this._log('Nenhum iframe ativo')
|
|
184
|
+
return
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this._iframe.src = this._buildUrl()
|
|
188
|
+
this._log('Reiniciado')
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Remove completamente do DOM
|
|
193
|
+
*/
|
|
194
|
+
destroy() {
|
|
195
|
+
this.close()
|
|
196
|
+
this._iframe = null
|
|
197
|
+
this._modal = null
|
|
198
|
+
this._config = null
|
|
199
|
+
this._callbacks = {
|
|
200
|
+
onReady: null,
|
|
201
|
+
onClose: null,
|
|
202
|
+
onAddToCart: null,
|
|
203
|
+
onGenerationComplete: null,
|
|
204
|
+
onError: null
|
|
205
|
+
}
|
|
206
|
+
this._log('Destruido')
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Retorna o estado atual
|
|
211
|
+
*/
|
|
212
|
+
getStatus() {
|
|
213
|
+
return {
|
|
214
|
+
isOpen: this._isOpen,
|
|
215
|
+
config: this._config
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
// ============ METODOS PRIVADOS ============
|
|
220
|
+
|
|
221
|
+
_log(message, data = null) {
|
|
222
|
+
if (this.debug) {
|
|
223
|
+
if (data) {
|
|
224
|
+
console.log(`[mKFashion] ${message}`, data)
|
|
225
|
+
} else {
|
|
226
|
+
console.log(`[mKFashion] ${message}`)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
_triggerCallback(name, data = null) {
|
|
232
|
+
if (this._callbacks && typeof this._callbacks[name] === 'function') {
|
|
233
|
+
try {
|
|
234
|
+
this._callbacks[name](data)
|
|
235
|
+
this._log(`Callback ${name} executado`, data)
|
|
236
|
+
} catch (error) {
|
|
237
|
+
console.error(`[mKFashion] Erro no callback ${name}:`, error)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
_buildUrl() {
|
|
243
|
+
const url = new URL(this.appUrl)
|
|
244
|
+
url.searchParams.set('company', this._config.projectid)
|
|
245
|
+
url.searchParams.set('sku', this._config.identifier)
|
|
246
|
+
url.searchParams.set('sdk', 'true')
|
|
247
|
+
return url.toString()
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
_openModal() {
|
|
251
|
+
// Cria o fundo escuro
|
|
252
|
+
this._modal = document.createElement('div')
|
|
253
|
+
this._modal.style.cssText = `
|
|
254
|
+
position: fixed;
|
|
255
|
+
top: 0;
|
|
256
|
+
left: 0;
|
|
257
|
+
width: 100%;
|
|
258
|
+
height: 100%;
|
|
259
|
+
background: rgba(0, 0, 0, 0.8);
|
|
260
|
+
display: flex;
|
|
261
|
+
align-items: center;
|
|
262
|
+
justify-content: center;
|
|
263
|
+
z-index: 99999;
|
|
264
|
+
opacity: 0;
|
|
265
|
+
transition: opacity 0.3s ease;
|
|
266
|
+
`
|
|
267
|
+
|
|
268
|
+
// Cria o iframe
|
|
269
|
+
this._iframe = this._createIframe()
|
|
270
|
+
this._iframe.style.cssText += `
|
|
271
|
+
border-radius: 12px;
|
|
272
|
+
transform: scale(0.95);
|
|
273
|
+
transition: transform 0.3s ease;
|
|
274
|
+
`
|
|
275
|
+
|
|
276
|
+
// Adiciona ao modal
|
|
277
|
+
this._modal.appendChild(this._iframe)
|
|
278
|
+
document.body.appendChild(this._modal)
|
|
279
|
+
|
|
280
|
+
// Anima a entrada
|
|
281
|
+
requestAnimationFrame(() => {
|
|
282
|
+
this._modal.style.opacity = '1'
|
|
283
|
+
this._iframe.style.transform = 'scale(1)'
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
// Fecha ao clicar fora
|
|
287
|
+
this._modal.addEventListener('click', (e) => {
|
|
288
|
+
if (e.target === this._modal) {
|
|
289
|
+
this.close()
|
|
290
|
+
}
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
// Fecha com ESC
|
|
294
|
+
this._escHandler = (e) => {
|
|
295
|
+
if (e.key === 'Escape') {
|
|
296
|
+
this.close()
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
document.addEventListener('keydown', this._escHandler)
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
_closeModal() {
|
|
303
|
+
if (!this._modal) return
|
|
304
|
+
|
|
305
|
+
// Anima a saida
|
|
306
|
+
this._modal.style.opacity = '0'
|
|
307
|
+
this._iframe.style.transform = 'scale(0.95)'
|
|
308
|
+
|
|
309
|
+
// Remove apos animacao
|
|
310
|
+
setTimeout(() => {
|
|
311
|
+
if (this._modal && this._modal.parentNode) {
|
|
312
|
+
this._modal.parentNode.removeChild(this._modal)
|
|
313
|
+
}
|
|
314
|
+
this._modal = null
|
|
315
|
+
this._iframe = null
|
|
316
|
+
}, 300)
|
|
317
|
+
|
|
318
|
+
// Remove listener do ESC
|
|
319
|
+
if (this._escHandler) {
|
|
320
|
+
document.removeEventListener('keydown', this._escHandler)
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
_openEmbed() {
|
|
325
|
+
const targetId = this._config.targetId
|
|
326
|
+
if (!targetId) {
|
|
327
|
+
console.error('[mKFashion] targetId e obrigatorio para type="embed"')
|
|
328
|
+
return
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const container = document.getElementById(targetId)
|
|
332
|
+
if (!container) {
|
|
333
|
+
console.error(`[mKFashion] Elemento #${targetId} nao encontrado`)
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
this._iframe = this._createIframe()
|
|
338
|
+
this._iframe.style.cssText += `
|
|
339
|
+
border-radius: 12px;
|
|
340
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
|
341
|
+
`
|
|
342
|
+
|
|
343
|
+
container.innerHTML = ''
|
|
344
|
+
container.appendChild(this._iframe)
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
_closeEmbed() {
|
|
348
|
+
if (!this._config.targetId) return
|
|
349
|
+
|
|
350
|
+
const container = document.getElementById(this._config.targetId)
|
|
351
|
+
if (container) {
|
|
352
|
+
container.innerHTML = ''
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
this._iframe = null
|
|
356
|
+
},
|
|
357
|
+
|
|
358
|
+
_createIframe() {
|
|
359
|
+
const { width, height } = this._config
|
|
360
|
+
const iframe = document.createElement('iframe')
|
|
361
|
+
iframe.src = this._buildUrl()
|
|
362
|
+
iframe.style.width = typeof width === 'number' ? `${width}px` : width
|
|
363
|
+
iframe.style.height = typeof height === 'number' ? `${height}px` : height
|
|
364
|
+
iframe.style.border = 'none'
|
|
365
|
+
iframe.setAttribute('allow', 'camera; microphone')
|
|
366
|
+
iframe.setAttribute('allowfullscreen', 'true')
|
|
367
|
+
return iframe
|
|
368
|
+
},
|
|
369
|
+
|
|
370
|
+
// Configura listener para mensagens do iframe
|
|
371
|
+
_setupMessageListener() {
|
|
372
|
+
this._messageHandler = (event) => {
|
|
373
|
+
// Ignora mensagens que nao sao da app
|
|
374
|
+
if (!event.data || event.data.source !== 'mkfashion-app') {
|
|
375
|
+
return
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const { action, data } = event.data
|
|
379
|
+
this._log('Mensagem recebida:', action, data)
|
|
380
|
+
|
|
381
|
+
// Trata as acoes
|
|
382
|
+
switch (action) {
|
|
383
|
+
case 'close_request':
|
|
384
|
+
this.close()
|
|
385
|
+
break
|
|
386
|
+
|
|
387
|
+
case 'restart_request':
|
|
388
|
+
this.restart()
|
|
389
|
+
break
|
|
390
|
+
|
|
391
|
+
case 'ready':
|
|
392
|
+
this._log('App pronta', data)
|
|
393
|
+
this._triggerCallback('onReady', data)
|
|
394
|
+
break
|
|
395
|
+
|
|
396
|
+
case 'add_to_cart':
|
|
397
|
+
this._log('Adicionar ao carrinho', data)
|
|
398
|
+
this._triggerCallback('onAddToCart', {
|
|
399
|
+
identifier: this._config.identifier,
|
|
400
|
+
size: data?.size || null,
|
|
401
|
+
...data
|
|
402
|
+
})
|
|
403
|
+
break
|
|
404
|
+
|
|
405
|
+
case 'generation_complete':
|
|
406
|
+
this._log('Geracao completa', data)
|
|
407
|
+
this._triggerCallback('onGenerationComplete', data)
|
|
408
|
+
break
|
|
409
|
+
|
|
410
|
+
case 'generation_error':
|
|
411
|
+
this._log('Erro na geracao', data)
|
|
412
|
+
this._triggerCallback('onError', data)
|
|
413
|
+
break
|
|
414
|
+
|
|
415
|
+
default:
|
|
416
|
+
this._log('Acao desconhecida:', action)
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
window.addEventListener('message', this._messageHandler)
|
|
421
|
+
this._log('Listener de mensagens ativado')
|
|
422
|
+
},
|
|
423
|
+
|
|
424
|
+
// Remove listener de mensagens
|
|
425
|
+
_removeMessageListener() {
|
|
426
|
+
if (this._messageHandler) {
|
|
427
|
+
window.removeEventListener('message', this._messageHandler)
|
|
428
|
+
this._messageHandler = null
|
|
429
|
+
this._log('Listener de mensagens removido')
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Disponibiliza globalmente
|
|
435
|
+
if (typeof window !== 'undefined') {
|
|
436
|
+
window.mkfashion = mkfashion
|
|
437
|
+
}
|
package/test.html
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="pt-BR">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Teste - mKFashion SDK</title>
|
|
8
|
+
<style>
|
|
9
|
+
* {
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
body {
|
|
16
|
+
font-family: Arial, sans-serif;
|
|
17
|
+
padding: 40px;
|
|
18
|
+
background: #f5f5f5;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
h1 {
|
|
22
|
+
margin-bottom: 10px;
|
|
23
|
+
color: #333;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
p {
|
|
27
|
+
color: #666;
|
|
28
|
+
margin-bottom: 30px;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.buttons {
|
|
32
|
+
display: flex;
|
|
33
|
+
gap: 10px;
|
|
34
|
+
flex-wrap: wrap;
|
|
35
|
+
margin-bottom: 30px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
button {
|
|
39
|
+
padding: 12px 24px;
|
|
40
|
+
font-size: 16px;
|
|
41
|
+
border: none;
|
|
42
|
+
border-radius: 8px;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
transition: transform 0.2s;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
button:hover {
|
|
48
|
+
transform: scale(1.05);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.btn-primary {
|
|
52
|
+
background: #4F46E5;
|
|
53
|
+
color: white;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.btn-secondary {
|
|
57
|
+
background: #6B7280;
|
|
58
|
+
color: white;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.code-box {
|
|
62
|
+
margin-top: 20px;
|
|
63
|
+
padding: 20px;
|
|
64
|
+
background: #1e1e1e;
|
|
65
|
+
border-radius: 8px;
|
|
66
|
+
color: #d4d4d4;
|
|
67
|
+
font-family: monospace;
|
|
68
|
+
font-size: 14px;
|
|
69
|
+
overflow-x: auto;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.code-box .comment {
|
|
73
|
+
color: #6a9955;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.code-box .string {
|
|
77
|
+
color: #ce9178;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.code-box .keyword {
|
|
81
|
+
color: #569cd6;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.code-box .function {
|
|
85
|
+
color: #dcdcaa;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.events-log {
|
|
89
|
+
margin-top: 30px;
|
|
90
|
+
padding: 20px;
|
|
91
|
+
background: white;
|
|
92
|
+
border-radius: 8px;
|
|
93
|
+
border: 1px solid #e5e5e5;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.events-log h3 {
|
|
97
|
+
margin-bottom: 15px;
|
|
98
|
+
color: #333;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.events-log ul {
|
|
102
|
+
list-style: none;
|
|
103
|
+
max-height: 200px;
|
|
104
|
+
overflow-y: auto;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.events-log li {
|
|
108
|
+
padding: 8px 12px;
|
|
109
|
+
margin-bottom: 5px;
|
|
110
|
+
background: #f9f9f9;
|
|
111
|
+
border-radius: 4px;
|
|
112
|
+
font-family: monospace;
|
|
113
|
+
font-size: 13px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.events-log li.ready {
|
|
117
|
+
border-left: 3px solid #22c55e;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.events-log li.close {
|
|
121
|
+
border-left: 3px solid #ef4444;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.events-log li.cart {
|
|
125
|
+
border-left: 3px solid #3b82f6;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.events-log li.generation {
|
|
129
|
+
border-left: 3px solid #a855f7;
|
|
130
|
+
}
|
|
131
|
+
</style>
|
|
132
|
+
</head>
|
|
133
|
+
|
|
134
|
+
<body>
|
|
135
|
+
<h1>mKFashion SDK - Teste</h1>
|
|
136
|
+
<p>Clique no botao para testar o provador virtual</p>
|
|
137
|
+
|
|
138
|
+
<div class="buttons">
|
|
139
|
+
<button class="btn-primary" onclick="abrirModal()">Abrir Modal</button>
|
|
140
|
+
<button class="btn-secondary" onclick="mkfashion.close()">Fechar</button>
|
|
141
|
+
<button class="btn-secondary" onclick="mkfashion.restart()">Reiniciar</button>
|
|
142
|
+
<button class="btn-secondary" onclick="limparLogs()">Limpar Logs</button>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<div class="code-box">
|
|
146
|
+
<span class="comment">// 1. Instalar via CDN</span><br>
|
|
147
|
+
<script src=<span class="string">"https://unpkg.com/mkfashion-sdk/src/mkfashion.js"</span>></script><br><br>
|
|
148
|
+
|
|
149
|
+
<span class="comment">// 2. Registrar callback do carrinho</span><br>
|
|
150
|
+
mkfashion.<span class="function">addToCart</span>(<span class="keyword">function</span>(payload) {<br>
|
|
151
|
+
<span class="keyword">console</span>.log(<span class="string">"Produto adicionado:"</span>, payload);<br>
|
|
152
|
+
});<br><br>
|
|
153
|
+
|
|
154
|
+
<span class="comment">// 3. Abrir o visualizador</span><br>
|
|
155
|
+
mkfashion.<span class="function">open</span>({<br>
|
|
156
|
+
type: <span class="string">'iframe'</span>,<br>
|
|
157
|
+
projectid: <span class="string">'gregory'</span>,<br>
|
|
158
|
+
identifier: <span class="string">'VEST-001-AZUL'</span>,<br>
|
|
159
|
+
width: <span class="keyword">400</span>,<br>
|
|
160
|
+
height: <span class="keyword">700</span><br>
|
|
161
|
+
});
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
<div class="events-log">
|
|
165
|
+
<h3>Eventos recebidos:</h3>
|
|
166
|
+
<ul id="eventsList">
|
|
167
|
+
<li style="color: #999;">Nenhum evento ainda...</li>
|
|
168
|
+
</ul>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<script src="src/mkfashion.js"></script>
|
|
172
|
+
<script>
|
|
173
|
+
// Ativa logs no console
|
|
174
|
+
mkfashion.debug = true
|
|
175
|
+
|
|
176
|
+
// Para testar local, mude a URL
|
|
177
|
+
mkfashion.appUrl = 'http://localhost:5173/'
|
|
178
|
+
|
|
179
|
+
// Funcao para adicionar evento na lista
|
|
180
|
+
function logEvent(type, message, data = null) {
|
|
181
|
+
const list = document.getElementById('eventsList')
|
|
182
|
+
|
|
183
|
+
// Remove mensagem inicial
|
|
184
|
+
if (list.children.length === 1 && list.children[0].style.color) {
|
|
185
|
+
list.innerHTML = ''
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const li = document.createElement('li')
|
|
189
|
+
li.className = type
|
|
190
|
+
const time = new Date().toLocaleTimeString()
|
|
191
|
+
li.textContent = `[${time}] ${message}${data ? ': ' + JSON.stringify(data) : ''}`
|
|
192
|
+
list.insertBefore(li, list.firstChild)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Registra callbacks (padrao mK3D)
|
|
196
|
+
mkfashion.addToCart(function(payload) {
|
|
197
|
+
logEvent('cart', 'Adicionar ao carrinho', payload)
|
|
198
|
+
alert(`Produto ${payload.identifier} tamanho ${payload.size} adicionado ao carrinho!`)
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
mkfashion.onReady(function(data) {
|
|
202
|
+
logEvent('ready', 'App pronta', data)
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
mkfashion.onClose(function() {
|
|
206
|
+
logEvent('close', 'Modal fechado')
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
mkfashion.onGenerationComplete(function(data) {
|
|
210
|
+
logEvent('generation', 'Geracao completa', data)
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
mkfashion.onError(function(data) {
|
|
214
|
+
logEvent('close', 'Erro', data)
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
function abrirModal() {
|
|
218
|
+
mkfashion.open({
|
|
219
|
+
type: 'iframe',
|
|
220
|
+
projectid: 'gregory',
|
|
221
|
+
identifier: 'VEST-001-AZUL',
|
|
222
|
+
width: 400,
|
|
223
|
+
height: 700
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
logEvent('ready', 'Modal aberto')
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function limparLogs() {
|
|
230
|
+
document.getElementById('eventsList').innerHTML = '<li style="color: #999;">Nenhum evento ainda...</li>'
|
|
231
|
+
}
|
|
232
|
+
</script>
|
|
233
|
+
</body>
|
|
234
|
+
|
|
235
|
+
</html>
|