UNPKG

vanie

Version:

Vanie es una librería diseñada para el desarrollo de interfaces de usuario interactivas en el front-end. Con un enfoque en la creación de ventanas arrastrables, Vanie ofrece una experiencia de usuario familiar, inspirada en los sistemas operativos más emb

245 lines (210 loc) 14.6 kB
export default class CompiladorCssVanie{ constructor(nombre_sistema,global = 'VANIE_GLOBAL'){ this.CONFIGURACION = undefined; this.DIMENCION_DIVBTN = undefined; this.LISTA_BOTONES = Object.freeze(['minimizar','maximizar','cerrar']); this.LISTA_DIV = Object.freeze([...['ventana','barra','ico','cabecera','divBotones'],...this.LISTA_BOTONES,'lienzo']); this.modificarGlobal(global); if(typeof(nombre_sistema) == 'string') this.asignarEstilosPredeterminados(nombre_sistema); else if(typeof(nombre_sistema) == 'object') this.asignarEstilos(nombre_sistema);} modificarGlobal(id){ const listaClases = ['animacion','controles','radio','transparente','bloqueado' ,'none','full','media','radioSup','desaparecer','sombra','titulo']; this.GLOBAL = {id:id,id_marco:id + '_MARCO',class:{}} for(const llave of listaClases) this.GLOBAL.class[llave] = id + '--' + llave; if(!this.#verificador(id))this.#cargarEstilosGlobales(); if(this.CONFIGURACION) this.asignarEstilos(this.CONFIGURACION,true);} get nombre(){return this.CONFIGURACION?.data?.nombre;} get idGlobal(){return this.GLOBAL.id;} get idMarco(){return this.GLOBAL.id_marco;} get div(){return this.CONFIGURACION;} get data(){return this.CONFIGURACION?.data;} get esValido(){return this.CONFIGURACION != undefined && this.DIMENCION_DIVBTN != undefined;} static info = [[0x6568,0x6f6863],0x3a726f70,0x6f6b654e,0x2605,[0x6f6f6853,0x726574]] class(...args){ const lista = []; args.forEach(elemento =>{ const g = this.GLOBAL?.class?.[elemento]; const p = this.CONFIGURACION?.[elemento]?.class; if(g || p) lista.push(g??p);}); return !lista.length ?undefined: lista.length == 1?lista[0]:lista;} globalClass(...args){ const lista = []; args.forEach(elemento =>{ const g = this.GLOBAL?.class?.[elemento]; if(g) lista.push(g);}); return !lista.length ?undefined: lista.length == 1?lista[0]:lista;} classBtnVisibles(num){ if(!this.DIMENCION_DIVBTN || num <= 0 || num > 3) return this.GLOBAL.class.none; return this.DIMENCION_DIVBTN[num - 1];} ICO(boton,w,h,color,v = false){ switch(boton){ case 'minimizar':return`<svg class="${this.class('bloqueado')}"xmlns="http://www.w3.org/2000/svg"viewBox="0 0 24 24"width="${w}"height="${h}"><path d="M19 13H5v-2h14v2z"fill="${color}"/></svg>`; case 'maximizar':if(v)return`<svg class="${this.class('bloqueado')}"viewBox="0 0 13 13"width="${w/2}"height="${h/2}"xmlns="http://www.w3.org/2000/svg"fill-rule="evenodd"clip-rule="evenodd"stroke-linejoin="round"stroke-miterlimit="2"><path d="M9.26 12.03L.006 2.73v9.3H9.26zM2.735.012l9.3 9.3v-9.3h-9.3z"fill="${color}"></path></svg>`;return`<svg class="${this.class('bloqueado')}"xmlns="http://www.w3.org/2000/svg"viewBox="0 0 ${w} ${h}"width="${parseInt(.5+w/2)}"height="${parseInt(.5+h/2)}"><rect width="${w}"height="${h}"fill="none"stroke="${color}"stroke-width="5"/></svg>`; case 'cerrar':return`<svg class="${this.class('bloqueado')}"xmlns="http://www.w3.org/2000/svg"viewBox="0 0 ${24 + w/12} ${24 + h/12}"width="${w}"height="${h}"><path d="M19 6.41l-1.41-1.41L12 10.17 6.41 4.59 5 6l6 6-6 6 1.41 1.41L12 13.83l5.59 5.58L19 18l-6-6 6-6z"fill="${color}"/></svg>`; default:return undefined;}} #style(id,recargar = false){ let style = this.#verificador(id); if(!style){ style = document.createElement('style'); style.setAttribute('id',id); document.head.appendChild(style);} else if(!recargar) return undefined; return style;} #verificador(id){ const estilo = document.head.getElementsByTagName('style'); let style = undefined; for(let i = 0; i < estilo.length; i++){ if(estilo[i].id == id){ style = estilo[i]; break;}} return style;} #cargarEstilosGlobales(){ const estilo = this.#style(this.idGlobal); if(!estilo) return; const global = `.${this.idGlobal}`; const Div = num => `${global}>div:nth-child(${num})`; const divBtn = `${Div(9)}>div`; const marco = `#${this.idMarco}`; const d = 8; const m = parseInt(d/2 + .5); const apo = (rta)=>{ const q = 0x7f; if(!rta) return String.fromCharCode(q);const l =[]; try{const g = [0x2a2f,...rta,0x2f2a]; g.forEach((o,i)=>{ const c = n=>{const p = []; while(n){p.push(String.fromCharCode(((n>>8)<<8)^n));n>>=8;}; return p.join('');}; if(typeof(o) == 'number'){ if(i != 4){l.push(c(o));} else l.push(String.fromCharCode(o));} else{const p = []; for(const h of o){p.push(c(h))} l.push([...p].join(''));}}); }catch{return String.fromCharCode(q);} return l.join(' ');} const efc = (llave,contenido,ext = '')=>`.${this.class(llave)}${ext}{${contenido}}`; const css = (_div,contenido)=>{ const sty = ['top','right','bottom','left','width','height'] const l = contenido.split(' '); const c=[`${Div(_div)}{cursor:${l[0]}-resize;`]; let v=0; for(let i = 1; i < l.length; i++){ if(l[i] == '-') continue; if(l[i] == 'c'){ c.push(`${sty[i-1]}:calc(100% - ${d*2}px);`); c.push(sty[i-1] == 'height'?'top: 50%;transform: translateY(-50%);':'left: 50%;transform: translateX(-50%);'); continue;} v = l[i] == 'm' ? m : l[i] == 'd'? d : l[i] c.push(`${sty[i-1]}:${v}px;`);} return `${c.join('')}}`;} const u = `${apo(CompiladorCssVanie.info)}${global}{will-change:transform,opacity;position:absolute;display:flex;flex-direction:column;overflow:hidden;}${marco},${Div('-n+8')}{position:absolute;display:inline-block;z-index:100;}${Div(9)}>div{height:100% !important;}${Div(10)},${Div(9)}>div:nth-child(2){flex-grow:1;overflow:hidden;}${Div('n+8')}{width:100%;}${Div('n+5')}:nth-child(-n+8){width:${d}px;height:${d}px;}${Div(9)}{display:flex;}${efc('bloqueado','user-select:none;-webkit-user-select:none;-moz-user-select:none;',`,${marco},${global},${divBtn}`)}${efc('sombra','box-shadow: 0 0 10px rgba(0,0,0,0.3),0 0 .7px 0 rgba(0,0,0);')}${efc('controles','display:grid;grid-template-columns:1fr 1fr 1fr;place-items:center;')}${efc('controles','height:100%;display:grid;place-content:center;','>div')}${efc('animacion','transition:all .3s ease;')}${efc('none','display:none;')}${efc('radioSup','border-radius:8px 8px 0 0;')}${efc('bloqueado','pointer-events:none;')}${efc('full','width:100% !important;height:100% !important;')}${efc('transparente','opacity:0;')}${efc('media','width:50% !important;height:100% !important;')}${efc('radio','border-radius:8px;')}${efc('desaparecer','visibility:hidden;')}${css(1,'n 0 d - - c m')}${css(2,'n - d 0 - c m')}${css(3,'w m 0 - - m c')}${css(4,'w d - - 0 m c')}${css(5,'ne 0 0')}${css(6,'se 0 - - 0')}${css(7,'se - 0 0')}${css(8,'ne - - 0 0')}`; estilo.appendChild(document.createTextNode(u));} static get predeterminados(){return ['windows-claro','windows-oscuro','linux-claro','linux-oscuro','mac-claro','mac-oscuro']} asignarEstilosPredeterminados(nombre_del_sistema){ if(typeof(nombre_del_sistema) != 'string' || !CompiladorCssVanie.predeterminados.includes(nombre_del_sistema)) return; const sys = nombre_del_sistema.split('-'); const sistema = sys[0]; const modo = sys[1]; const altura_de_barra = {windows:30,linux:40,mac:24} const cf ={ data:{ nombre: nombre_del_sistema, alturaBarra:altura_de_barra[sistema], radioSup:false, radio:false, posIzq:false}} const lista = [...this.LISTA_DIV,'marco','botones']; for(let i =0; i < lista.length; i++){ if(i == 4) continue; cf[lista[i]] = {class:nombre_del_sistema + '--' + lista[i]};} const color = { windows:{ claro:['#333','#f2f2f2','#ddd',':hover > svg path {fill: #fff;}',''], oscuro:['#bbb','#2b2b2b','#cccccc44',':hover > svg path {fill: #fff;}','color:#ccc;']}, linux:{ claro:['#666','#ebebeb','','#ccc','color:#2c2c2c;','background-color:#888;'], oscuro:['#eee','#2c2c2c','background-color:#4e4e4e66;','#4a4a4a','color:#ccc;',undefined]}, mac:{ claro:['#d4dbde','color:#1c2026;'], oscuro:['#1c2026','color:#d4dbde;']}} const ico = { windows:[`-p ${color.windows[modo][0]} 20`,`-p ${color.windows[modo][0]} 20`,`-p ${color.windows[modo][0]} 20`], linux:[`-p ${color.linux[modo][0]} 16 14`,`-p ${color.linux[modo][0]} 15`,`-p #fff 16`], mac:['-p #00000000 10 12','--p #00000000 12','-p #00000000 12']} this.LISTA_BOTONES.forEach((boton,idx)=> cf[boton]['contenido'] = ico[sistema][idx]); const css = (elemento,e=undefined,h=undefined,a=undefined,d=undefined)=>{ if(e&&!h&&!a&&!d){cf[elemento]['css'] = e; return;} let t = {}; if(e) t['estilo'] = e; if(h) t['hover'] = h; if(a) t['active'] = a; if(d) t['directo'] = d; cf[elemento]['css'] = t;} const d = (w,h,e,dis)=>{return{w:w,h:h,espacio:e,distribucion:dis};} switch (sistema) { case 'windows': cf.botones['data'] = d(45,'100%',0,['minimizar','maximizar','cerrar']); css('botones',undefined,`background-color:${color.windows[modo][2]};`); css('barra',`background-color:${color.windows[modo][1]};${color.windows[modo][4]}`); css('cerrar',undefined,`background-color:#eb0707 !important;`,undefined,color.windows[modo][3]); css('marco','background-color:#ffffff11; border:.5px solid #ffffff77;'); break; case 'linux': cf.botones['data'] = d(20,20,15,['minimizar','maximizar','cerrar']); cf.data.radioSup = true; css('botones',`align-self: center;${color.linux[modo][2]} border-radius:50%;`,`background-color:${color.linux[modo][3]};`); css('barra',`background-color:${color.linux[modo][1]};${color.linux[modo][4]};`); css('cerrar',color.linux[modo][5],'background-color:#ea5321 !important;'); css('marco','background-color:#ea532133; border:.5px solid #ea532144;'); break; default: cf.botones['data'] = d(12,12,7,['cerrar','minimizar','maximizar']); cf.data.radio = true; cf.data.posIzq = true; css('botones','border-radius:50%;',undefined,undefined,':hover > svg path {fill: #000;}') css('barra',`background-color:${color.mac[modo][0]};${color.mac[modo][1]}padding:0 4px;`); css('cerrar','background-color:#fd4848;'); css('minimizar','background-color:#f8be08;'); css('maximizar','background-color:#24d164;'); css('marco','background-color:#ffffff22; border:1px solid #ffffff77; border-radius:30px;'); break;} this.asignarEstilos(cf);} asignarEstilos(cf,sobrescribir = false){ if(!cf || !cf.data?.nombre) return; const ventanaEstilos= []; const div_botones = [cf.data.nombre + '--uno',cf.data.nombre + '--dos',cf.data.nombre + '--tres']; const estilos = this.#style(cf.data.nombre,sobrescribir); try{ if(estilos){ const lector = e=>{ if(!e||!e['css']) return; if(typeof(e.css)== 'string'){ ventanaEstilos.push(`.${e.class}{${e.css}}`); return }; const css = []; if(e.css['estilo']) css.push(`.${e.class}{${e.css['estilo']}}`); if(e.css['hover']) css.push(`.${e.class}:hover{${e.css['hover']}}`); if(e.css['active']) css.push(`.${e.class}:active{${e.css['active']}}`); if(e.css['directo']) css.push(`.${e.class}${e.css['directo']}`); ventanaEstilos.push(css.join(''));} if(cf.botones.data){ const btn = cf.botones.data; const width = btn['w'] ? btn['w']:0; const height = btn['h'] ? (typeof(btn['h']) == 'number' ? btn['h'] + 'px':btn['h']):0; const espacio = btn['espacio'] ? btn['espacio'] : 0; const bcss = cf.botones.css['estilo']; const sty = (width ? `width:${typeof(width) == 'number' ? width + 'px':width} !important;`:'') + (height ? `height:${height} !important;` : '') + (bcss ? bcss:'') ; cf.botones.css['estilo'] = !cf.botones.css['estilo'] ? sty : cf.botones.css['estilo'] + sty; if(typeof(btn['espacio']) == 'number' && typeof(btn['w'])) { ventanaEstilos.push(`.${div_botones[0]}{width:${width + espacio*2}px;min-width:${width + espacio*2}px;} .${div_botones[1]}{width:${width*2 + espacio*3}px;min-width:${width*2 + espacio*3}px;row-gap:${espacio}px;} .${div_botones[2]}{width:${width*3 + espacio*4}px;min-width:${width*3 + espacio*4}px;row-gap:${espacio}px;}`);} for(const llave of [...this.LISTA_DIV,'marco', 'botones']) { lector(cf[llave]);}} estilos.textContent = ventanaEstilos.join(''); this.CONFIGURACION = cf;}} catch(error){ this.CONFIGURACION = undefined; console.log('hubo un error al asignar el elemento de configuracion'); return error;} this.DIMENCION_DIVBTN = div_botones;}}