Commit 27206f99 by Иван Кубота

motherofgod

parent 04f2d6f8
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -35,6 +35,7 @@ app.get('/batch_face_landmarks', (req, res) => res.sendFile(path.join(viewsDir,
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('/demo2', (req, res) => res.sendFile(path.join(viewsDir, 'demo2.html')));
app.get('/colors', (req, res) => res.sendFile(path.join(viewsDir, 'colors.html')));
app.get('/all', (req, res) => res.sendFile(path.join(viewsDir, 'all.html')));
app.get('/tryon', (req, res) => res.sendFile(path.join(viewsDir, 'tryon.html')));
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Try-on</title>
<script src="js/data.js"></script>
<script src="js/Observer.js"></script>
<script src="js/Store.js"></script>
<script src="js/DOM.js"></script>
<script src="js/colors.js"></script>
<script src="js/Point.js"></script>
<script src="js/kmean.js"></script>
<style>
a {
color: #395772;
text-decoration: none;
}
.cmp-collapse.collapsed .cmp-collapse-content {
display: none;
}
.cmp-collapse-title:before {
content: '▼';
margin: 0 4px 0 0;
}
.cmp-collapse.collapsed .cmp-collapse-title:before {
content: '▲';
}
.cmp-collapse-title {
cursor: pointer;
font-weight: bold;
margin: 32px 0 0 0;
}
.cmp-collapse-content {
padding-left: 16px;
}
.slider-background {
background: #104361;
height: 2px;
position: absolute;
left: 8px;
top: 7px;
right: 8px;
}
.slider {
position: relative;
height: 32px;
}
.sw_sm.matched {
border: 1px solid #000;
}
.sw_sm {
width: 10px;
height: 10px;
display: inline-block;
margin: 1px;
border: 1px solid #fff;
padding: 1px;
}
.sw_sm div {
width: 100%;
height: 100%;
}
.slider-start {
position: absolute;
left:0;
}
.slider-start:before {
content: '';
height: 6px;
top: 5px;
left: 5px;
position: absolute;
background: #104361;
width: 6px;
border-radius: 50%;
z-index: 2;
}
.slider-end {
position: absolute;
right:0;
}
.slider-end:before {
content: '';
height: 6px;
top: 5px;
right: 5px;
position: absolute;
background: #104361;
width: 6px;
border-radius: 50%;
z-index: 2;
}
.slider-end__label {
position: absolute;
text-align: center;
left: 0;
font-family: Tahoma;
top: -3px;
}
.slider-start__label {
position: absolute;
text-align: center;
right: 4px;
font-family: Tahoma;
top: -3px;
}
.slider-drag {
width: 12px;
height: 12px;
margin-left: 2px;
top: 2px;
border: 2px solid #104361;
box-sizing: border-box;
cursor: pointer;
position: absolute;
z-index: 1;
border-radius: 50%;
background: #fff;
}
.grhm {
width: 50%;
left:25%;
position: relative;
}
.slider-zone {
position: absolute;
left: 8px;
right: 8px;
height: 8px;
top: 4px;
}
.slider-hover-val {
position: absolute;
top: -28px;
transform: translate(-40%);
font-family: Tahoma;
}
#colorsCount {
margin:32px
}
.colorSwatch {
width: 32px;
height: 32px;
float: left;
margin: 1px 1px 0 0;
border: 1px solid #666;
border-radius: 4px;
}
.colorSwatch.active:before {
content: '✓';
font-size: 24px;
text-align: center;
margin: auto;
display: block;
color: #fff;
padding-top: 4px;
text-shadow: #000 0px -2px 2px;
}
.colorSwatch.active {
position: relative;
margin: -4px;
width: 41px;
height: 41px;
border-radius: 25px;
}
.vendor.disabled {
color: #aaa
}
</style>
</head>
<body>
<script>
var Transform = ( function(){
'use strict';
var hookAndConvert = function( fn ){
return function( hook, a ){
var type = typeof hook;
var notObject = type !== 'object';
var isHook = !notObject && ( 'hook' in hook );
if( isHook ){
type = 'function';
notObject = true;
}
if( notObject ){
if( type === 'function' ){
var last, val;
if( isHook ){
return {
hook: function( draw ){
return hook.hook( function( arg ){
val = fn( arg, a );
if( last === val )
return;
return draw( last = val );
} );
}
};
}else{
return function( draw ){
return hook( function( arg ){
val = fn( arg, a );
if( last === val )
return;
return draw( last = val );
} );
};
}
}
}else{
return hook;
}
}
};
var Transform = {
toFixed: hookAndConvert( function( val, digits ){
return ( val - 0 ).toFixed( digits );
} )
};
return Transform;
} )();
window.T = Transform;
const slice = [].slice;
const Component = function( cfg ){
var original = cfg;
var _ctor = function( cfg, children ){
if( !( this instanceof _ctor ) ){
return new _ctor( cfg, children );
}
this.store = new Store();
this._apply( cfg );
arguments.length > 1 && this._children.call( this, slice.call( arguments, 1 ) );
this.__un = new D.Unsubscribe();
original.ctor && original.ctor.apply( this );
};
_ctor.prototype = Object.assign( Object.create( Component.prototype ), cfg );
_ctor.constructor = _ctor;
return _ctor;
};
Component.prototype = {
prop: {},
_children: function( children ){
this.children = children;
},
_apply: function( cfg ){
var prop = this.prop;
for( var key in cfg ){
var val = cfg[ key ];
if( key in prop ){
if( val instanceof Store.StoreBinding || val instanceof Store.HookPrototype ){
this[ key ] = val;
}else{
this[ key ] = new Store.Value[ prop[ key ].type.name ]( val );
}
}else{
this[ key ] = val;
}
}
for( key in prop ){
if( !( key in cfg ) ){
var property = prop[ key ];
if( !property.optional ){
this[ key ] = new Store.Value[ property.type.name ]();
if( property.default ){
this[ key ].set( property.default );
}
}
}
}
},
'~destroy': function(){
var pointer = this.dom.parentNode;
if( !pointer ){
pointer = this.dom;
}
var allHooked = [].slice.call( pointer.querySelectorAll( '[data-hooked]' ) );
for( var i = 0, _i = allHooked.length; i < _i; i++ ){
var un = allHooked[ i ].__un;
if( !un )
continue;
var uns = allHooked[ i ].__un;
for( var j = 0, _j = uns.length; j < _j; j++ ){
var unSubscribe = uns[ j ];
unSubscribe();
}
delete allHooked[ i ].__un;
}
if( this.dom.parentNode ){
pointer.removeChild( this.dom );
}
this.dom = void 0;
this.__un.un();
for( var key in this )
this.hasOwnProperty( key ) && delete this[ key ];
},
sub: function(){
var un = this.store.sub.apply( this.store, arguments );
this.__un.add( un );
}
};
var Property = function( type ){
this.name = type;
};
Property.prototype = {
set: function( val ){
return val;
},
get: function( val ){
return val;
},
compare: function( val1, val2 ){
return val1 === val2;
}
};
Component.Property = {
Any: new Property( 'Any' )
};
var Slider = new Component( {
ctor: function( cfg ){
Object.assign( this, cfg );
this.createDOM();
this.initBinding();
this.initEvents();
this.afterInit && this.afterInit();
},
prop: {
from: { type: Number },
to: { type: Number },
value: { type: Number, default: 0 },
step: { type: Number, optional: true },
},
createDOM: function(){
this.dom = D.div( { cls: 'slider' },
D.div( { cls: 'slider-background' } ),
this.zoneEl = D.div( { cls: 'slider-zone' } ),
D.div( { cls: 'slider-start' },
D.div( { cls: 'slider-start__label' }, T.toFixed( this.from, 0 ) ),
),
D.div( { cls: 'slider-end' },
D.div( { cls: 'slider-end__label' }, T.toFixed( this.to, 0 ) )
),
this.dragEl = D.div( { cls: 'slider-drag', style: { left: '0px' } } )
);
this._updateUI = this._updateUI.bind( this );
this.afterDOM && this.afterDOM();
},
initEvents: function(){
var _self = this;
D.mouse.down( this.dom, function( e ){
var pos = new Point( e.clientX, e.clientY );
_self.getBound();
_self.calculateValue( pos );
_self.updateUI();
var update = D.AnimationFrame( function( pos ){
_self.calculateValue( pos );
_self.updateUI();
} );
var un = D.mouse.move( document, function( e ){
e.preventDefault();
e.stopPropagation();
pos.x = e.clientX;
pos.y = e.clientY;
update( pos );
}, true );
D.overlay.show();
//un.add( D.mouse.up(_self.dom, un) );
un.add( function(){
D.overlay.hide();
} );
un.add( D.mouse.up( window, un ) );
} );
},
getBound: function(){
var bound = this.zoneEl.getBoundingClientRect();
this.bound = {
left: bound.left,
top: bound.top,
height: bound.height,
width: bound.width
};
},
calculateValue: function( pos ){
var bound = this.bound;
var val = Math.min( Math.max( 0, pos.x - bound.left ), bound.width );
this.setValue( this.from.get() + ( val / bound.width * ( this.delta ) ) );
},
afterAddToDOM: function(){
this.getBound();
this.updateUI();
},
bound: null,
_updateRequested: false,
_updateUI: function(){
this._updateRequested = false;
this.dragEl.style.left = ( this.value.get() - this.from.get() ) / ( this.delta ) * this.bound.width + 'px';
},
updateUI: function(){
if( this.bound ){
if( !this._updateRequested ){
this._updateRequested = true;
requestAnimationFrame( this._updateUI )
}
}
},
initBinding: function(){
var _self = this;
this.sub( [ this.value, this.from, this.to ], function( val, from, to ){
_self.delta = to - from;
_self.setValue( val );
_self.updateUI();
} );
},
lastValue: null,
setValue: function( val, silent ){
var inVal = val;
val = Math.min( this.to.get(), Math.max( this.from.get(), val ) );
if( 'step' in this ){
var step = this.step.get();
val = Math.round( val / step ) * step;
}
if( val !== this.lastValue || inVal !== val ){
this.lastValue = val;
if( !silent ) this.value.set( val );
}
}
} );
var Radio = new Component( {
ctor: function(){
this.createDOM();
this.initBinding();
this.afterInit && this.afterInit();
},
prop: {
value: { type: Component.Property.Any, default: false },
group: { type: Component.Property.Any, default: false }
},
createDOM: function(){
var val = this.value,
group = this.group,
el = this.dom = this.inputEl = D.h( 'input', {
attr: { type: 'radio' },
cls: 'picker-button__field',
onchange: function(){
if( el.checked ){
group.set( val.get() )
}
}
} );
this.afterDOM && this.afterDOM();
},
initBinding: function(){
var _self = this;
this.sub( [ this.value, this.group ], function( val, group ){
_self.inputEl.checked = val === group;
} );
}
} );
var Collapse = new Component({
name: 'Collapse',
ctor: function(cfg) {
Object.assign(this, cfg);
this.createDOM();
this.afterInit && this.afterInit();
},
prop: {
value: {type: Boolean, default: false},
label: {type: String, default: 'Collapse'},
},
createDOM: function() {
var val = this.value,
el = this.dom = this.inputEl = D.h('div', {
cls: D.cls('cmp-collapse', {
collapsed: val
})
},
D.div({cls: 'cmp-collapse-title', onclick: function(){ val.set(!val.get())}}, this.label),
D.div({cls: 'cmp-collapse-content'}, this.children)
);
this.afterDOM && this.afterDOM();
}
});
</script>
<script src="js/prs.js"></script>
<base href="https://www.mirrormirror.love/">
<div id="tags" style="display: none"></div>
<div style="display:flex">
<div style="width:320px; flex:none">
<div id="cooltags"></div>
<div id="colorsCount"></div>
<div id="BrandCollapse"></div>
<div id="yep"></div>
<div style="clear:both"></div>
<div id="yep2" style="padding-top: 32px;display: none"></div>
<div style="clear:both"></div>
<!-- style="display: none"-->
<div id="yep3" style="padding-top: 32px"></div>
<div style="clear:both"></div>
</div>
<div style="margin: 0 32px;width:100%">
<div id="colorogrammaSwitches"></div>
<canvas id="c0" width="580" height="580"></canvas>
<div id="productList" style="display: flex;flex-wrap: wrap;"></div>
</div>
</div>
<script>
function matchingProductsFormat(p, index) {
var product = p.product;
// If the variants doesn't have Image src
if (product.variants[index].featured_image == null) {
product.variants[index].featured_image = {};
product.variants[index].featured_image.src =
"https://cdn.shopify.com/s/files/1/0275/8036/6900/files/2_Main_Vertical_Transparent.png?v=1575867010";
}
var out_put = "";
out_put = `<div style="width:240px">
<div class="grid-product__content">
<a class="grid-product__link " href="/products/${product.handle}" target="_blank">
<div class="grid-product__image-mask">
<img width="160" src="${product.variants[index].featured_image.src});">
</div>
<div class="grid-product__meta">
<div class="grid-product__title grid-product__title--body">${product.title}</div>
<div class="grid-product__vendor">${product.vendor}</div>
<div class="grid-product__price">$${product.variants[index].price}
</div>
</div>
</a>
<!-- ============= add custom button ( quick view, love, add to cart ) =============-->
<div class="quick-product__menus quick-product__btn cssgrid w-100">
<div aria-expanded class="quick-product__btn js-modal-open-quick-modal-${product.id} d-flex quick-product__icon-bg quick-product__view" data-product-id="${product.id}">
<a href="/products/${product.handle}" target="_blank" class="w-100 h-100">
<span class="quick-product__label d-flex align-self-center quick-try-on w-100 h-100"></span>
</a>
</div>
</div>
<!-- ============= end of custom button =============-->
</div>
<div class="grid-product__colors grid-product__colors--${product.id}">
<div id="color_squares_container-${product.id}" class="d-flex">
${p.variants.map(v=>`<div class="sw_sm${v.matched?' matched':''}"><div style="background:${v.v.option2}"></div></div>`).join('')}
</div>
</div>
</div>
</div>`;
return out_put;
}
var colors = [];
var coolTags = ['Lips', 'Lipstick', 'Blush', 'Eyes', 'Eyeliner'];
var tags = prs.products.reduce( function( store, p ){
p.tags.forEach( t => {
if( t[ 0 ].toUpperCase() === t[ 0 ] )
store[ t ] = true
} );
return store;
}, {} );
var s = new Store({
colorCount: 24, possibleCollapse: true, BrandCollapse: false,
brand: [],
colors: []
});
D.div( {
renderTo: document.getElementById( 'tags' )
}, Object.keys( tags ).map( a => D.span( { style: { padding: '10px' } }, a ) ) );
D.appendChild(document.getElementById('colorsCount'),new Slider({
from: 16,
to: 36,
value: s.bind('colorCount'),
step: 1,
afterInit: function(){
//console.log(this.value)
D.div( { renderTo: this.dragEl, cls: 'slider-hover-val' }, T.toFixed( this.value, 0 ) );
}
}));
D.div( {
renderTo: document.getElementById( 'cooltags' )
}, coolTags.map( tag =>
D.div( { style: { display: 'inline-block' } },
D.h( 'label', { cls: 'field' },
new Radio( {
value: tag,
group: s.bind( 'tag' )
} ),
tag
)
) ) );
D.div( {
renderTo: document.getElementById( 'colorogrammaSwitches' )
}, ['PRODUCTS', 'COLOROGRAMMA'].map( tag =>
D.div( { style: { display: 'inline-block' } },
D.h( 'label', { cls: 'field' },
new Radio( {
value: tag,
group: s.bind( 'colorogramma' )
} ),
tag
)
) ) );
s.sub(['colorogramma'], function(colorogramma) {
var pl = document.getElementById('productList').style,
cl = document.getElementById('c0').style;
if(colorogramma==='PRODUCTS'){
cl.display = 'none';
pl.display = 'flex';
}else{
pl.display = 'none';
cl.display = 'block';
}
});
var toggle = function(key, val) {
var arr = s.get(key);
if(arr.indexOf(val) > -1){
var spliced = arr.slice(0);
spliced.splice(arr.indexOf(val), 1);
s.set(key, spliced);
}else{
s.set(key, arr.slice(0).concat(val));
}
}
s.sub(['tag', 'colorCount', 'brand', 'colors'], Store.debounce(function(tag, maxColors, brand, selectedColors) {
colors = [];
var vendors = prs.products.reduce((s,p)=>{
if(p.tags.indexOf( tag ) === -1)
return s;
if(p.variants.filter(v=>{
if( v.option2 ){
var r = HEX2RGB( v.option2 );
if( !isNaN( r[ 0 ] ) ){
return true;
}
}
return false
}).length>0)
p.vendor && (s[p.vendor] || (s[p.vendor] = [])).push(p);
return s;
}, {})
var allVendors = Object.keys(vendors);
var allBrandsDeselected = allVendors.filter(v=>brand.indexOf(v)===-1).length === allVendors.length;
var products = prs.products
.filter( function( pr ){
return (pr.tags.indexOf( tag ) > -1) && (
allBrandsDeselected ? true : brand.indexOf(pr.vendor)>-1
);
return pr.tags.indexOf( 'Eyes' ) > -1
return pr.tags.indexOf( 'Lips' ) > -1
return true;
} )
.map( function( pr ){
pr.variants.forEach( function( v ){
if( v.option2 ){
var r = HEX2RGB( v.option2 )[ 0 ];
if( !isNaN( r ) ){
colors.push( v.option2 )
}
}
} )
return pr;
} );
D.replaceChildren(document.getElementById( 'yep' ), new Collapse({
label: 'All possible colors (debug)',
value: s.bind('possibleCollapse')
}, D.div( {},
colors.map( function( c ){
return D.div( {
style: {
background: c,
width: '16px',
height: '16px',
float: 'left',
margin: '0',
border: '1px inset'
}
} )
} )
)));
var t = +new Date();
var means = new KMeans();
var result = {
means: means,
clusters: means.cluster( colors.map( c =>
rgbToLab.apply( null, HEX2RGB( c ) )
), 10, labDistance )
};
console.log( +new Date() - t )
D.replaceChildren(document.getElementById( 'yep2' ), D.div( {},
result.clusters.map( function( c ){
c = { color: c }
var l = 0, a = 0, b = 0;
for( var i = 0, _i = c.color.length; i < _i; i++ ){
var colorElement = c.color[ i ];
l += colorElement[ 0 ];
a += colorElement[ 1 ];
b += colorElement[ 2 ];
}
return [
l / c.color.length,
a / c.color.length,
b / c.color.length
];
//c.color.sort( colorSort )[ 0 ];//result.means.centroids.slice().sort(distanceToHSV(c.color[0]))[0];
} ).map( function( c ){
var rgb = labToRgb.apply( null, c );
return D.div( {
style: {
background: 'rgb(' + rgb + ')',
width: '48px',
height: '48px',
float: 'left',
margin: '1px 1px 0 0',
border: '1px solid #666',
borderRadius: '4px'
}
} )
} )
));
var c = document.getElementById( 'c0' ),
ctx = c.getContext( '2d' );
ctx.clearRect(0,0,c.clientWidth, c.clientHeight);
var testItems = [];
for( var j = 0.05; j < 0.95; j += 0.1 ){
var dots = 300 * 2 * 3.141592 / 100 * j * 3, step = 6.28 / dots;
for( var i = 0; i < 6; i += step ){
var p = new Point( 250 * j, 0 ).rotate( i ).add( 250, 250 );
var clr = hsvToRgb( i / 6.28, j < 0.5 ? j * 2 : 1, j > 0.5 ? ( ( 1 - j ) ) * 2 : 1 );
var item = {
rgb: clr,
lab: rgbToLab.apply( null, clr ),
p: p,
matched: 0,
colors: []
};
testItems.push( item );
}
}
for(var i = 0; i <= 256; i+=256/6){
var clr = [i,i,i];
var p = new Point( 290 , 0 ).rotate( i/256*6.28/4 ).add( 250, 250 );
testItems.push( {
rgb: clr,
lab: rgbToLab.apply( null, clr ),
p: p,
matched: 0,
colors: []
} );
}
var labColors = colors.map( c =>
( { lab: rgbToLab.apply( null, HEX2RGB( c ) ), used: [] } )
);
//debugger
for( var i = 0, _i = labColors.length; i < _i; i++ ){
var labColor = labColors[ i ];
var closest = 100, closestItem = false;
for( var j = 0, _j = testItems.length; j < _j; j++ ){
var testItem = testItems[ j ];
var distance = labDistance( labColor.lab, testItem.lab );
if( distance < closest ){
/*if( distance < 5 && closestItem ){
closestItem.matched += 4
labColor.used.push( closestItem );
closestItem.colors.push( labColor );
}*/
closest = distance;
closestItem = testItem;
}
}
if( closestItem ){
closestItem.matched++;
labColor.used.push( closestItem );
closestItem.colors.push( labColor );
}
}
var filteredItems = []
for( var j = 0, _j = testItems.length; j < _j; j++ ){
var testItem = testItems[ j ];
if( testItem.matched === 0 )
continue;
filteredItems.push( testItem );
}
ctx.strokeStyle = '#777';
for( var j = 0, _j = filteredItems.length; j < _j; j++ ){
var testItem = filteredItems[ j ];
var clr = testItem.rgb,
p = testItem.p;
ctx.fillStyle = 'rgb(' + clr.map( a => a | 0 ) + ')'
ctx.beginPath();
ctx.arc( p.x, p.y, Math.min( Math.max( testItem.matched, 2 ), 8 ) * 2.5, 0, 6.28 )
ctx.fill();
ctx.beginPath();
ctx.arc( p.x, p.y, Math.min( Math.max( testItem.matched, 2 ), 8 ) * 2.2, 0, 6.28 )
ctx.stroke();
}
console.log( filteredItems.length )
//debugger
var ff /*= filteredItems.filter( function( item ){
return !item.colors.every( ( clr ) => clr.used.length > 1 )
} )*/
var removed = {};
var sectors = [], angle = 15, thresh = 10;
ff = filteredItems.filter((f,m)=>{
var uniq = filteredItems.filter((f2, k)=>{
if(k in removed)
return 0;
var uniq = (labDistance(f2.lab,f.lab)|0)<thresh?1:0
return uniq;
}).length === 1
if(!uniq){
removed[m] = true;
}
return uniq;
})
var megaFilter = [],
other = [];
for(var i = 0; i < 360; i+=angle){
sectors.push([]);
}
for( var i = 0, _i = ff.length; i < _i; i++ ){
var filteredItem = ff[ i ],
hsv = rgbToHsv.apply(null, filteredItem.rgb);
filteredItem.hsv = hsv;
sectors[(hsv[0]*360/angle)|0].push(filteredItem);
}
sectors.forEach(function(sector) {
if(sector.length === 1){
megaFilter.push(sector[0]);
}else if(sector.length === 2){
if(labDistance(sector[0].lab,sector[1].lab)<14){
var middle = {hsv: [
(sector[0].hsv[0]+sector[1].hsv[0])/2,
(sector[0].hsv[1]+sector[1].hsv[1])/2,
(sector[0].hsv[2]+sector[1].hsv[2])/2
]
};
middle.rgb = hsvToRgb.apply(null, middle.hsv);
middle.p = sector[0].p.middle(sector[1].p);
middle.matched = 3;
megaFilter.push(middle);
}else{
other.push(sector);
}
}else{
other.push(sector);
}
});
var means2 = new KMeans();
if(other.length){
var otherPoints = [].concat.apply([], other);
var result = {
means: means2,
clusters: means2.cluster( otherPoints.map( c =>c.lab),
Math.min(maxColors - megaFilter.length, otherPoints.length), labDistance )
};
result.clusters.map( function( c ){
var l = 0, a = 0, b = 0;
for( var i = 0, _i = c.length; i < _i; i++ ){
var colorElement = c[ i ];
l+=colorElement[0];
a+=colorElement[1];
b+=colorElement[2];
}
return [
l/c.length,
a/c.length,
b/c.length
];
//c.color.sort( colorSort )[ 0 ];//result.means.centroids.slice().sort(distanceToHSV(c.color[0]))[0];
} ).forEach(function(lab) {
megaFilter.push({
lab: lab,
rgb: labToRgb.apply(null, lab),
hsv: rgbToHsv.apply(null,labToRgb.apply(null, lab))
})
});
}
megaFilter.sort((a,b)=>{
return ( a.hsv[ 0 ] - b.hsv[ 0 ] ) * 50 + ( b.hsv[ 2 ] - a.hsv[ 2 ] ) * 35 + ( a.hsv[ 1 ] - b.hsv[ 1 ] ) * 2;
})
var somethingSelected = false;
D.replaceChildren(document.getElementById( 'yep3' ),D.div( {},
megaFilter.map( function( c ){
var txt = c.rgb.map(c=>c|0).join(',');
var isSelected = selectedColors.indexOf(txt)>-1;
somethingSelected = somethingSelected || isSelected;
return D.div( {
cls: 'colorSwatch'+(isSelected ? ' active': ''),
onclick: ()=>{
console.log(txt)
toggle('colors', txt)
},
style: {
background: 'rgb(' + txt + ')',
}
} )
} )
));
/*
ctx.strokeStyle = '#fff';
for( var j = 0, _j = megaFilter.length; j < _j; j++ ){
var testItem = megaFilter[ j ];
var clr = testItem.rgb,
p = testItem.p;
ctx.fillStyle = 'rgb(' + clr.map( a => a | 0 ) + ')'
ctx.fillRect( p.x-4, p.y-4, 8,8 )
}*/
var searchResults = [];
D.replaceChildren(document.getElementById( 'BrandCollapse' ), new Collapse({
label: 'Brand',
value: s.bind('BrandCollapse')
}, D.div( {},
Object.keys(vendors).map(v=>{
var variantExist = true;
if(somethingSelected){
variantExist = false
var products = vendors[v];
//outer:
for( var i = 0, _i = products.length; i < _i; i++ ){
var product = products[ i ],
variants = product.variants;
var subM = false;
var matchHash = {};
for( var j = 0, _j = variants.length; j < _j; j++ ){
var variant = variants[ j ];
var clr = variant.option2;
var r = HEX2RGB( clr );
if( isNaN( r[ 0 ] ) ){
continue;
}
for( var k = 0, _k = selectedColors.length; k < _k; k++ ){
const selected = selectedColors[ k ].split(',').map(Number);
if(labDistance(rgbToLab.apply(null, r), rgbToLab.apply(null, selected))<15){
variantExist = true
matchHash[variant.id] = true;
subM = true;
break;
}
}
}
if(subM){
searchResults.push( {
product: product,
variants: product.variants.map( v => ( {
matched: v.id in matchHash,
v: v
} ) )
} )
}
}
}else{
vendors[v].forEach(p=>{
searchResults.push({product: p, variants: p.variants.map(v=>({matched: false, v: v}))})
});
}
return D.div(
{cls: 'vendor'+(variantExist?'': ' disabled')},
D.h( 'label', { cls: 'field' },
D.h('input', {
prop: {
type: 'checkbox',
checked: brand.indexOf(v)>-1,
disabled: !variantExist
},
onchange: (e)=>{
toggle('brand', v)
}
} ),
v
)
);
})
)));
searchResults.sort((a,b)=>a.product.title<b.product.title?-1:1);
document.getElementById('productList').innerHTML = searchResults.map((p)=>{
return matchingProductsFormat(p,0)
}).join('');
/*D.replaceChildren(document.getElementById('productList'),
)*/
console.log( ff.length )
console.log( megaFilter.length )
}, 100));
s.set('tag', 'Lips')
s.set('colorogramma', 'PRODUCTS')
//debugger
</script>
</body>
</html>
\ No newline at end of file
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