Commit 2469f250 by Иван Кубота

match products and all products variants page

parent 883bf0ca
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -212,20 +212,96 @@ function rgbToHex(r, g, b) { ...@@ -212,20 +212,96 @@ function rgbToHex(r, g, b) {
throw "Invalid color component"; throw "Invalid color component";
return ((r << 16) | (g << 8) | b).toString(16); return ((r << 16) | (g << 8) | b).toString(16);
} }
var extractor = function(ctx, from, k, debug) { var extractor = function(partName, ctx, from, k, debug) {
extracting++; extracting++;
return extractColors(ctx, from, k, debug) var colors = extractColors(ctx, from, k, debug)
.map(function(m) { .map(function(m) {
return {color: hsvToRgb.apply(null, m.color).map(function(a){return a|0}), hsv: m.color, distance: m.distance}; return {color: hsvToRgb.apply(null, m.color).map(function(a){return a|0}), hsv: m.color, distance: m.distance};
});
return D.div({cls: 'colors'},
colors.map(function(m){
return D.span({style: 'background:rgb('+m.color.join(',')+');', cls: 'color-preview'},
'H: '+Math.floor(m.hsv[0]*360),D.h('br'),
'S: '+Math.round(m.hsv[1]*100)+'%', D.h('br'),
'V: '+Math.round(m.hsv[2]*100)+'%'
);
}),
function(draw) {
getData(partName, function(res) {
var list = [];
res.products.forEach(function(product) {
product.variants.forEach(function(variant) {
var color = variant.option2.substr(1),
r = parseInt(color[0]+color[1], 16),
g = parseInt(color[2]+color[3], 16),
b = parseInt(color[4]+color[4], 16);
list.push({
pid: product.id,
vid: variant.id,
description: product.body_html,
title: product.title,
color: variant.option2,
colorName: variant.option1,
img: variant.featured_image && variant.featured_image.src || (product.images[0] || {}).src,
sku: variant.option3,
hsv: rgbToHsv(r,g,b)
});
});
});
var used = {};
var all = [].concat.apply([],
colors.map(function(clr) {
var matched = list.map(function(i) {
return {i: i, d: hsvDistance(i.hsv, clr.hsv), c: clr};
})
.filter(function(i) {
return i.d<0.07;
})
.sort(function(a,b) {
return a.d-b.d;
});
if(!matched.length)
return matched;
if(matched[0].d<0.02){
return matched.slice( 0, 1 )
}else{
return matched.slice(0, 2);
}
})).filter(function(item) {
if(!(item.i.vid in used)){
used[item.i.vid] = true;
return true;
}
return false;
});
var count = all.length;
draw(D.div({cls: 'matched'},
D.span({cls:'action', onClick: function() {
this.parentNode.classList.toggle('opened');
}}, 'Matched: '+count+' '+(count===1?'item':'items')),
D.div({cls: 'collapsed'},
all.map(function(item) {
return D.div({cls: 'row'},
D.div({cls: 'cp1', style: {background: 'rgb('+item.c.color+')'}}),
D.div({cls: 'cp2', style: {background: item.i.color}}),
D.h('img', {cls: 'preview-img', src: item.i.img}),
D.div({cls: 'name'}, item.i.title),
D.div({cls: 'accuracy'}, (Math.max(0,Math.min(100,(1-item.d*8)*100))).toFixed(2)+'%')
)
}) })
.map(function(m){ )
return { ));
html: '<span style="background:rgb('+m.color.join(',')+');" class="color-preview">'+
'H:&nbsp;'+Math.floor(m.hsv[0]*360)+'<br>'+
'S:&nbsp;'+Math.round(m.hsv[1]*100)+'%<br>'+
'V:&nbsp;'+Math.round(m.hsv[2]*100)+'%'+
'</span>'
};
}); });
}
);
}; };
\ No newline at end of file
...@@ -33,7 +33,8 @@ app.get('/bbt_face_matching', (req, res) => res.sendFile(path.join(viewsDir, 'bb ...@@ -33,7 +33,8 @@ app.get('/bbt_face_matching', (req, res) => res.sendFile(path.join(viewsDir, 'bb
app.get('/bbt_face_recognition', (req, res) => res.sendFile(path.join(viewsDir, 'bbtFaceRecognition.html'))) app.get('/bbt_face_recognition', (req, res) => res.sendFile(path.join(viewsDir, 'bbtFaceRecognition.html')))
app.get('/batch_face_landmarks', (req, res) => res.sendFile(path.join(viewsDir, 'batchFaceLandmarks.html'))) app.get('/batch_face_landmarks', (req, res) => res.sendFile(path.join(viewsDir, 'batchFaceLandmarks.html')))
app.get('/batch_face_recognition', (req, res) => res.sendFile(path.join(viewsDir, 'batchFaceRecognition.html'))) app.get('/batch_face_recognition', (req, res) => res.sendFile(path.join(viewsDir, 'batchFaceRecognition.html')))
app.get('/demo', (req, res) => res.sendFile(path.join(viewsDir, 'demo.html'))) app.get('/demo', (req, res) => res.sendFile(path.join(viewsDir, 'demo.html')));
app.get('/all', (req, res) => res.sendFile(path.join(viewsDir, 'all.html')));
app.post('/fetch_external_image', async (req, res) => { app.post('/fetch_external_image', async (req, res) => {
const { imageUrl } = req.body const { imageUrl } = req.body
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>All of them</title>
<script src="js/Point.js"></script>
<script src="js/extract-colors.js"></script>
<script src="js/data.js"></script>
<script src="js/DOM.js"></script>
<style>
body {
margin: 16px;
padding: 0;
font-family: Verdana;
font-size:16px;
}
.cp {
width:16px;
height: 16px;
border: 2px solid #fff;
transition: all 0.3s ease;
position: relative;
}
.cp:hover {
width: 32px;
height: 32px;
margin: -8px;
z-index: 2;
}
.row.other .cp {
border-radius: 50%;
}
.row.active .cp {
width: 24px;
height: 24px;
margin: -4px;
z-index: 1;
}
.title {
font-size:32px;
padding: 16px 0 8px 0
}
.row {
display: inline-block;
/* float: left; */
}
.left {
position: absolute;
left: 0;
width: 50%;
top: 0;
height: 100%;
padding:16px;
box-sizing: border-box;
}
.right {
position: absolute;
right: 0;
width: 50%;
top: 0;
height: 100%;
padding:16px;
box-sizing: border-box;
}
.preview-img {
float: right;
width: 128px;
}
.preview-color {
width: 92px;
height: 92px;
float: left;
margin: 0 16px 0 0;
border-radius: 5px;
}
</style>
</head>
<body>
<script>
var list = ['brows','lips','blush','eyes'];
var lastEl;
var preview = function(item, el) {
lastEl && lastEl.classList.remove('active');
lastEl && (lastEl.childNodes[0].style.borderColor = '#fff');
(lastEl = el).classList.add('active');
var clr = item.hsv.slice();
clr[2]*=2;
lastEl.childNodes[0].style.borderColor = 'rgb('+hsvToRgb.apply(null,clr)+')';
[].slice.call(document.querySelectorAll('.other')).forEach(function(el) {
el.classList.remove('other');
});
[].slice.call(document.querySelectorAll('[data-id="'+item.pid+'"]')).forEach(function(el) {
el.classList.add('other');
});
var desc;
updateRight(
D.div({cls: 'title'}, item.title),
D.h('img', {cls: 'preview-img', src: item.img}),
D.div({cls: 'preview-color', style: {background: item.color}}),
D.div({cls: 'info'}, 'Product ID: '+ item.pid),
D.div({cls: 'info'}, 'Variant ID: '+ item.vid),
D.div({cls: 'info'}, 'SKU ID: '+ item.sku),
D.div({cls: 'info'}, 'Color name: '+ item.colorName),
D.div({cls: 'info'}, 'Color: '+ item.color),
desc = D.div({cls: 'description'})
);
desc.innerHTML = item.description;
}, updateRight;
D.div({cls: 'viewport', renderTo: document.body},
D.div({cls: 'left'},
list.map(function(name) {
return D.div({cls: 'block'},
D.div({cls: 'title'}, name[0].toUpperCase()+name.substr(1)),
(draw)=>{
getData(name, function(res) {
var list = [];
res.products.forEach(function(product) {
product.variants.forEach(function(variant) {
var color = variant.option2.substr(1),
r = parseInt(color[0]+color[1], 16),
g = parseInt(color[2]+color[3], 16),
b = parseInt(color[4]+color[4], 16);
list.push({
pid: product.id,
vid: variant.id,
description: product.body_html,
title: product.title,
color: variant.option2,
colorName: variant.option1,
img: variant.featured_image && variant.featured_image.src || (product.images[0] || {}).src,
sku: variant.option3,
hsv: rgbToHsv(r,g,b)
});
});
});
list.sort(function(a,b) {
return (a.hsv[0]-b.hsv[0])*10+(b.hsv[2]-a.hsv[2])/2+(a.hsv[1]-b.hsv[1])/2;
});
draw(list.map(function(item) {
return D.div({attr: {'data-id': item.pid}, cls: 'row', onClick: function(){preview(item, this)}},
D.div({cls: 'cp', style: {background: item.color}})
)
}))
});
}
)
})
),
D.div({cls: 'right'},
function(_) {
updateRight = _;
}
)
);
setTimeout(function() {
document.querySelector('.row').click();
}, 300);
</script>
</body>
</html>
\ No newline at end of file
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
<script src="js/kmean.js"></script> <script src="js/kmean.js"></script>
<script src="js/facemarks.js"></script> <script src="js/facemarks.js"></script>
<script src="js/extract-colors.js"></script> <script src="js/extract-colors.js"></script>
<script src="js/data.js"></script>
<style> <style>
.color-preview { .color-preview {
display: inline-block; display: inline-block;
...@@ -21,7 +22,68 @@ ...@@ -21,7 +22,68 @@
margin: 2px; margin: 2px;
text-shadow: #fff 0 0 6px; text-shadow: #fff 0 0 6px;
} }
.cp {
width:16px;
height: 16px;
border: 2px solid #fff;
transition: all 0.3s ease;
position: relative;
}
.row {
height: 32px;
}
.cp2 {
width: 10px;
height: 100%;
display: inline-block;
}
.cp1 {
width: 16px;
height: 100%;
padding: 0 2px;
display: inline-block;
margin-right: 2px;
}
.preview-img {
height: 32px;
margin: 0 8px;
}
.name {
display: inline-block;
font-family: Verdana;
font-size: 14px;
vertical-align: super;
}
.action {
padding: 1px 2px;
border-bottom: 1px dashed #006ed1;
color: #006ed1;
cursor: pointer;
}
.collapsed {
display: none;
}
.collapsed {
margin: 8px 0;
}
.matched.opened .collapsed {
display: block;
}
.matched {
padding: 8px 0;
}
.accuracy {
display: inline-block;
font-size: 12px;
color: #999;
font-family: monospace;
vertical-align: super;
margin: 0 16px;
}
</style> </style>
<script src="js/DOM.js"></script>
</head> </head>
<body> <body>
...@@ -84,8 +146,10 @@ window.s0 = 224; ...@@ -84,8 +146,10 @@ window.s0 = 224;
img.onload = function() { img.onload = function() {
//ctx.drawImage(img, 0, 0); //ctx.drawImage(img, 0, 0);
f();
}; };
img.src = url; img.src = url;
} }
...@@ -302,24 +366,25 @@ var videoEl = inputVideo; ...@@ -302,24 +366,25 @@ var videoEl = inputVideo;
extracting = -1; extracting = -1;
document.getElementById('colors').innerHTML = [ updateColors([
block( block(
'Lips', 'Lips',
extractor(ctx2, lips, 5) extractor('lips',ctx2, lips, 5)
), ),
block( block(
'Blush', 'Blush',
extractor(ctx2, cheek, 3) extractor('blush', ctx2, cheek, 3)
), ),
block( block(
'Brows', 'Brows',
extractor(ctx2, browsSearchArea, 2) extractor('brows', ctx2, browsSearchArea, 2)
), ),
block( block(
'Eyes', 'Eyes',
extractor(ctx2, eyes, 6, 1) extractor('eyes', ctx2, eyes, 6, 1)
) )
].join('\n'); ]);
...@@ -330,17 +395,25 @@ var videoEl = inputVideo; ...@@ -330,17 +395,25 @@ var videoEl = inputVideo;
//colors.innerHTML = block('Mouth',colors()); //colors.innerHTML = block('Mouth',colors());
}else{
return setTimeout(f, 300)
} }
//requestAnimationFrame(f); if(cb.checked)
setTimeout(f, 300) setTimeout(f, 300)
}; };
var extracting = 0; var extracting = 0;
var block = function(title, extracted) { var block = function(title, extracted) {
return '<div class="block"><h2>'+ title +'</h2><p>'+extracted.map(a=>a.html).join('\n')+'</p></div>' return D.div({cls: 'block'},
D.h('h2', {}, title),
D.h('p', {}, extracted)
);
}; };
var updateColors;
D.div({renderTo: document.getElementById('colors')}, function(_){updateColors = _});
var f0 = async function() { var f0 = async function() {
try{ try{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment