Przejdź do treści
<code>pen.pl

Tkacki konfigurator próbki

Interfejs

Podgląd

Ładowanie podglądu…

Konfigurator materiału z widocznym splotem, doborem włókna i gęstości osnowy.

0,0 / 5 Brak ocen

Kod źródłowy

Licencja MIT — także do użytku komercyjnego. Zachowaj informacje o autorze i licencji.

HTML
<main class='loom' data-state='idle'>
  <header><div><span>PRACOWNIA TKACKA</span><h1>Próbka materiału</h1></div><p>Wybierz splot, włókno i gęstość. Podgląd pokazuje rytm osnowy i wątku.</p></header>
  <div class='loom-grid'>
    <section class='swatch-panel' aria-label='Podgląd splotu'>
      <div class='swatch' id='weave-swatch' aria-hidden='true'>
        <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
      </div>
      <dl><div><dt>Splot</dt><dd id='weave-label'>Płócienny</dd></div><div><dt>Gęstość</dt><dd><span id='weave-density-label'>12</span> nitek/cm</dd></div></dl>
    </section>
    <form id='weave-form' novalidate>
      <div class='two'>
        <div class='field'><label for='weave-name'>Nazwa próbki</label><input id='weave-name' name='sample_name' required autocomplete='off' aria-describedby='weave-name-error'><span class='error' id='weave-name-error'></span></div>
        <div class='field'><label for='weave-density'>Gęstość osnowy</label><input id='weave-density' name='density' type='number' required min='8' max='32' value='12' inputmode='numeric' aria-describedby='weave-density-error'><span class='error' id='weave-density-error'></span></div>
      </div>
      <div class='field'><label for='weave-type'>Rodzaj splotu</label><select id='weave-type' name='weave' required aria-describedby='weave-type-error'><option value='plain'>Płócienny</option><option value='twill'>Skośny</option><option value='basket'>Koszykowy</option></select><span class='error' id='weave-type-error'></span></div>
      <fieldset aria-describedby='weave-fibre-error'><legend>Włókno</legend><label><input type='radio' name='fibre' value='cotton'> Bawełna</label><label><input id='weave-linen' type='radio' name='fibre' value='linen'> Len</label><label><input type='radio' name='fibre' value='wool'> Wełna</label><span class='error' id='weave-fibre-error'></span></fieldset>
      <div class='actions'><button class='primary' id='weave-save' type='submit'>Zapisz próbkę</button><button type='reset'>Rozpocznij od nowa</button><button type='button' disabled>Krosno zajęte</button></div>
      <p class='status' id='weave-status' role='status' aria-live='polite'>Próbka czeka na ustawienia.</p>
    </form>
  </div>
</main>
CSS
*{box-sizing:border-box}html,body{margin:0;min-width:280px}body{min-height:100vh;padding:clamp(12px,3vw,28px);background:#dfd0a9;color:#2b291f;font:16px/1.5 Georgia,serif}.loom{width:min(100%,950px);margin:auto;border:3px solid #26375d;background:#efe3c1;box-shadow:8px 8px 0 #9b3b32}.loom header{display:flex;justify-content:space-between;gap:30px;align-items:end;padding:20px 24px;border-bottom:3px solid #26375d}.loom header span{font:700 12px Arial,sans-serif;letter-spacing:.09em}.loom h1{margin:3px 0 0;font-size:clamp(31px,5vw,55px);line-height:1;letter-spacing:-.04em}.loom header p{max-width:37ch;margin:0;font-size:14px}.loom-grid{display:grid;grid-template-columns:minmax(250px,.9fr) minmax(0,1.2fr);gap:25px;padding:24px}.swatch-panel{border-right:2px solid #26375d;padding-right:24px}.swatch{aspect-ratio:1.35;display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(4,1fr);gap:3px;background:#26375d;padding:7px;border:5px solid #efe3c1;outline:2px solid #26375d}.swatch i{background:#b7473c;box-shadow:inset 8px 0 0 #d0a536,inset -5px 0 0 #2e4779}.swatch i:nth-child(3n),.swatch i:nth-child(3n+1){background:#d0a536;box-shadow:inset 0 8px 0 #2e4779,inset 0 -5px 0 #b7473c}.swatch[data-weave=twill] i:nth-child(even){transform:translateY(7px);background:#2e4779}.swatch[data-weave=basket] i:nth-child(4n+1),.swatch[data-weave=basket] i:nth-child(4n+2){background:#b7473c}.swatch-panel dl{margin:18px 0 0}.swatch-panel dl div{display:flex;justify-content:space-between;gap:12px;border-bottom:1px solid #82775b;padding:6px 0}.swatch-panel dt{font:700 12px Arial,sans-serif}.swatch-panel dd{margin:0;font-weight:700}.two{display:grid;grid-template-columns:1fr 1fr;gap:12px}.field{margin-bottom:13px}label,legend{font-weight:700}label{display:block;margin-bottom:5px}input:not([type=radio]),select{width:100%;min-height:44px;border:2px solid #26375d;border-radius:0;background:#fff8df;color:#2b291f;padding:8px 10px}button,input,select{font:inherit}button{min-height:44px;border:2px solid #26375d;border-radius:0;background:#fff8df;color:#26375d;padding:8px 13px;font-weight:700;cursor:pointer}button.primary{background:#26375d;color:#fff8df}button:disabled{cursor:not-allowed;color:#746c57;border-color:#857d69;background:#d8cba8}button:focus-visible,input:focus-visible,select:focus-visible{outline:4px solid #b7473c;outline-offset:3px}fieldset{margin:0 0 14px;padding:8px 11px;border:2px solid #26375d}fieldset label{display:inline-flex;align-items:center;gap:7px;min-height:44px;margin:0 15px 2px 0}input[type=radio]{width:22px;height:22px;accent-color:#9b3b32}.error{display:block;min-height:17px;font:12px Arial,sans-serif;color:#9b261e}[aria-invalid=true]{border-color:#a92c24!important}.actions{display:flex;gap:8px;flex-wrap:wrap}.status{min-height:24px;margin:11px 0 0;font-weight:700}.loom[data-state=success] .swatch{outline-color:#9b3b32}.loom[data-state=success] .swatch i{animation:thread-settle .45s ease-out}@keyframes thread-settle{0%{transform:translateY(-6px)}100%{transform:translateY(0)}}@media(max-width:650px){body{padding:8px}.loom header{display:block;padding:18px}.loom header p{margin-top:12px}.loom-grid{grid-template-columns:1fr;padding:18px}.swatch-panel{border-right:0;border-bottom:2px solid #26375d;padding:0 0 18px}.swatch{max-height:240px}.two{grid-template-columns:1fr}.actions button{flex:1 1 145px}}@media(max-width:340px){.loom-grid,.loom header{padding:13px}.loom h1{font-size:32px}.actions{display:grid}.actions button{width:100%}fieldset label{display:flex;margin-right:0}}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
JavaScript
(()=>{const form=$('#weave-form'),loom=$('.loom'),status=$('#weave-status'),names={plain:'Płócienny',twill:'Skośny',basket:'Koszykowy'};function mark(el,message){$(el).attr('aria-invalid','true');$('#'+el.id+'-error').text(message)}function clear(el){$(el).removeAttr('aria-invalid');if(el.id)$('#'+el.id+'-error').text('')}form.on('input change','input,select',function(){clear(this);if(this.name==='fibre')$('#weave-fibre-error').text('')});$('#weave-type').on('change',function(){$('#weave-swatch').attr('data-weave',this.value);$('#weave-label').text(names[this.value])});$('#weave-density').on('input',function(){$('#weave-density-label').text(this.value||'0')});form.on('submit',function(event){event.preventDefault();form.find('[aria-invalid]').removeAttr('aria-invalid');form.find('.error').text('');let first=null,name=$('#weave-name')[0],density=$('#weave-density')[0];if(!name.value.trim()){mark(name,'Nadaj próbce nazwę.');first=first||name}if(!density.validity.valid){mark(density,'Podaj gęstość od 8 do 32.');first=first||density}if(!form.find('[name=fibre]:checked').length){$('#weave-fibre-error').text('Wybierz włókno.');first=first||form.find('[name=fibre]')[0]}if(first){loom.attr('data-state','error');status.text('Sprawdź ustawienia próbki.');first.focus();return}loom.attr('data-state','success');const fibre=form.find('[name=fibre]:checked').parent().text().trim();status.text('Próbka zapisana: '+name.value.trim()+', '+fibre.toLowerCase()+'.')});form.on('reset',()=>setTimeout(()=>{form.find('[aria-invalid]').removeAttr('aria-invalid');form.find('.error').text('');loom.attr('data-state','idle');$('#weave-swatch').attr('data-weave','plain');$('#weave-label').text('Płócienny');$('#weave-density-label').text('12');status.text('Przywrócono splot płócienny.')},0));const activate=event=>{event.preventDefault();form.triggerHandler('submit')};$('#weave-save').on('click',activate);form.on('keydown','input:not([type=radio]):not([type=range])',event=>{if(event.key==='Enter')activate(event)})})();
Biblioteki

JavaScript

Edytuj swój pen

Podaj adres e-mail użyty przy zapisie. Wyślemy link do edycji.

Link jest ważny przez 30 minut.