Categorii
Programare

Explorarea CSS Paint API: efect de fragmentare a unei imagini *preluat de pe CSS-Tricks

Nu este nevoie să căutăm cu lupa după articole pe Internet despre acest subiect (deși nu este o idee rea să investigăm în detaliu) și nici să fim intimidați de el, dar îmi place subiectul și am zis că traduc un articol despre el, cu mici adaosuri din partea mea care sper să aducă avantaje cititorilor. Cu curaj înainte, căci vom acumula cunoștințe interesante și utile care ne dezvoltă abilitatea de a crea original!

Ce înțelegem prin efect de fragmentare a unei imagini? De exemplu, o imagine face tranziție la altă imagine prin pătrățele de dimensiuni egale peste ea cu nivele diverse de transparență care devin tot mai puțin transparente, toate convergând la vizibilitate 100% a imaginii finale. Puteți vedea mai jos elemente interactive înglobate în acest articol cu acest efect și altele similare, dar pentru a le vedea trebuie să folosești, cel puțin temporar, un navigator web care suportă CSS Paint API (în momentul scrierii acestui articol, acestea sunt: Chromium, Chrome și Edge).

Sunt multe site-uri pe Internet despre design și dezvoltare web, acesta fiind umil unul dintre ele, și, deși e departe de a fi vorba de un graf complet, este o artă aceea de a-ți alege sursele de informare și modelare a propriei experiențe de artist web.

Dintre multe site-uri cu design-uri web, un site pe care mi l-a recomandat un prieten bun acum mai mulți ani și care continuă să mă impresioneze, mai ales date fiind noutățile constante în domeniul design-ului și dezvoltării web în cazul tuturor navigatoarelor web, este CSS Tricks.

Îmi place mult cum se leagă între ele postările de pe acest minunat site. O optimizare ușoară și clară pentru motoarele de căutare, gen Google ori DuckDuckGo: punerea de link-uri la postări mai vechi din postări mai noi. Este un site bine cunoscut și cu explicații detaliate și interesante de la mai mulți autori. Realizat cu WordPress! (Dacă ai nevoie de un site WordPress, nu ezita să mă contactezi.)

Încep prin a traduce în stilul meu, cu imagini când se poate, un articol foarte bun și interesant de pe acest site.

Un API este un serviciu sau modul pe care programatorii îl pot folosi pentru a realiza ceva deosebit fără să reinventeze roata. Este ca un prelungitor în care introduci ștechere. O extensie a curentului electric.

Sunt multe de explorat la CSS Paint API (tradus aproximativ „API de pictare CSS”) și dacă dorești să aprofundez un anumit subiect te rog să îmi scrii mai jos în comentarii! Dar, în principal, este vorba de extinderea CSS prin JS, ca o prelungire a CSS. API-ul este de fapt o reutilizare a API-ului de context 2D al elementului HTML5 <canvas>. Este foarte flexibil fiindcă poți controla fiecare pixel în parte, cu o viteză de procesare foarte mare și, evident, cu accelerație hardware. CSS Paint API este parte din proiectul Houdini și în prezent este suportat doar de navigatoarele web Chromium, Chrome și Edge. Aștept cu bucurie să implementeze și cei de la Firefox acest standard!

Tradițional, CSS-ul este declarativ (la fel ca HTML: nu dai comenzi, ci descrii) și JS-ul imperativ (dai comenzi, nu descrii). Îmbinarea celor 2 este o minunăție datorită flexibilității absolute!

În acest articol explorăm crearea unei animații de fragmentare a unei imagini, de exemplu la trecerea cu mausul deasupra ei, sau într-o prezentare de diapozitive.

Acest lucru se poate realiza și fără Houdini și CSS Paint API! Dar un exercițiu minunat este acesta în orice caz și este mai flexibil pe termen lung decât folosirea de SCSS, o grămadă de <div>-uri și măști CSS. În plus, este și mai eficient. Și este creație originală în joc! Posibilitățile sunt practic infinite!

Ce se potrivește de minune cu CSS Paint API sunt variabilele CSS!

Aceasta este ceea ce dorim să realizăm în acest articol:

See the Pen houdini mask by Temani Afif (@t_afif) on CodePen.

Cu nu mai mult de 5 declarații CSS obținem o animație destul de frumoasă de acoperire cu cursorul mausului, sau cu stilusul pe o tabletă.

Ce este Paint API?

„(To) paint” înseamnă, din limba engleză, „a picta”. Tablouri, pereți, chiar digital. Paint API este parte din proiectul Houdini. Da, „Houdini”, termenul ciudat despre care vorbesc foarte mulți cu zâmbetul pe buze. Multe articole acoperă deja aspectul teoretic al lui, deci nu te voi mai plictisi cu mai multă teorie. Dacă trebuie să însumez în puține cuvinte, aș spune: este viitorul CSS-ului. Paint API (și celelalte API-uri care stau sub umbrela Houdini) ne permit să extindem CSS cu propriile noastre funcționalități. Nu mai trebuie să așteptăm lansarea de noi facilități CSS în navigatoarele web deoarece le putem face noi înșine!

Din specificație: Un API pentru permiterea dezvoltatorilor web să definească o imagine CSS personalizată cu JavaScript, care va răspunde la schimbări de stil și dimensiune.

Și de la cel care explică: API-ul CSS Paint este dezvoltat pentru a îmbunătăți caracterul extensibil al CSS. Mai precis acest API permite dezvoltatorilor să scrie o funcție de pictare pentru ca să pictăm direct în fundalul, bordura, sau conținutul unui element.

Cred că ideea este destul de clară. Putem picta orice ne dorim. Să începem cu o demonstrație de bază a colorării de fundal:

  1. Adăugăm „pictorul” folosind CSS.paintWorklet.addModule('fisierul_meu_js').
  2. Înregistrăm o nouă metodă de pictare numită draw.
  3. Înăuntru, creăm o funcție paint() în care facem toată munca. Și ia ghicește? Totul e ca lucrul cu <canvas>. Acel ctx este contextul 2D, și pur și simplu am folosit câteva bine cunoscute funcții pentru a picta un dreptunghi roșu acoperind întreaga suprafață.

Aceasta ar putea părea complex la prima vedere, dar observi că structura principală este aceeași întotdeauna: cei trei pași de mai sus sunt partea „copy/paste” pe care o repeți pentru fiecare proiect. Creația reală este codul pe care îl scriem în funcția paint().

Hai să adăugăm o variabilă:

Așa cum poți vedea, logica este destul de simplă. Definim getter-ul inputProperties cu variabilele noastre ca o listă. Adăugăm properties ca al treilea parametru la paint() și mai târziu obținem variabila noastră folosind properties.get().

Asta este tot! Acum avem tot ce ne trebuie pentru a construi efectul nostru complex de fragmentare.

Construirea măștii

Poate te întrebi de ce folosim API-ul de pictare pentru a crea un efect de fragmentare. Am spus că este o unealtă de a picta imagini deci cum ne va permite să fragmentăm o imagine?

În articolul precedent, am realizat efectul folosind diferite straturi-măști unde fiecare este un pătrat definit cu un gradient (ține minte că un gradient este doar o imagine) deci am obținut un fel de matrice și trucul a fost să ajustăm canalul alfa al fiecăruia individual.

De această dată, în loc să folosim mai multe gradient-uri vom defini o singură imagine personalizată pentru masca noastră și acea imagine personalizată va fi gestionată de API-ul nostru de pictare.

Un exemplu!

În cel de mai sus, am creat o imagine având o culoare opacă acoperind partea stângă și o culoare semitransparentă acoperind partea dreaptă. Aplicând această imagine ca o mască ne dă rezultatul logic al unei imagini pe jumătate transparente.

Acum tot ce trebuie este să împărțim imaginea în mai multe părți. Hai să definim două variabile și să actualizăm codul nostru:

See the Pen Mask houdini #2 by Temani Afif (@t_afif) on CodePen.

Partea relevantă a codului este următoarea:

const n = properties.get('--f-n');
const m = properties.get('--f-m');

const w = size.width/n;
const h = size.height/m;

for(var i=0;i<n;i++) {
  for(var j=0;j<m;j++) {
    ctx.fillStyle = 'rgba(0,0,0,'+(Math.random())+')';    
    ctx.fillRect(i*w, j*h, w, h);
}
}

N și M definesc dimensiunea matricei noastre de dreptunghiuri. W și H sunt dimensiunea fiecărui dreptunghi. Apoi avem un ciclu de bază FOR care umple fiecare dreptunghi cu o culoare aleatorie transparentă.

Cu puțin JavaScript, obținem o mască personalizată pe care o putem controla ușor prin ajustarea variabilelor CSS:

Acum, dorim să controlăm canalul alfa astfel încât să creăm efectul de decolorare al fiecărui dreptunghi și să construim efectul de fragmentare.

Hai să introducem o a treia variabilă pe care o folosim pentru canalul alfa pe care de asemenea o schimbăm la acoperire.

Am definit o proprietate CSS personalizată cu tipul <number> pe care îl trecem de la 1 la 0, și aceeași proprietate este folosită pentru definirea canalului alfa al dreptunghiurilor noastre. Nimic deosebit nu se va întâmpla la acoperire deoarece toate dreptunghiurile noastre se vor decolora în exact același fel.

Ne trebuie un truc (gen iepurele din pălărie) pentru a preveni decolorarea tuturor dreptunghiurilor în același timp, să creăm în loc o întârziere între ele. Aici este o ilustrație care explică ideea pe care o voi folosi:

Figura de mai sus prezintă animația alfa pentru două dreptunghiuri. Mai întâi definim o variabilă L care ar trebui să fie mai mare sau egală cu 1 apoi pentru fiecare dreptunghi din matricea noastră (mai precis, pentru fiecare canal alfa) realizăm o tranziție între X și Y unde X - Y = L deci avem aceeași durată per ansamblu pentru toate canalele alfa. X ar trebui să fie mai mare sau egal cu 1 și Y mai mic sau egal cu 0.

Stai puțin, valoarea alfa ar trebui să fie în intervalul [1, 0], corect?

Da, așa este! Și toate trucurile pe care lucrăm se bazează pe asta. Mai sus, alfa se animează de la 8 la -2, ceea ce înseamnă că avem o culoare opacă în intervalul [8, 1], o culoare transparentă în [0, -2] și o animație în intervalul [1, 0]. Cu alte cuvinte, oricare valoare mai mare decât 1 va avea același efect ca 1, și oricare valoare mai mică decât 0 va avea același efect ca 0.

Animația din [1, 0] nu va avea loc în același moment pentru toate dreptunghiurile noastre. Dreptunghiul 2 va ajunge la [1, 0] înainte ca dreptunghiul 1 să ajungă. Aplicăm aceasta la toate canalele alfa și obținem animațiile noastre întârziate.

În codul nostru vom actualiza aceasta:

rgba(0,0,0,'+(o)+')

să fie aceasta:

rgba(0,0,0,'+((Math.random()*(l-1) + 1) - (1-o)*l)+')

L este variabila ilustrată anterior, și o este valoarea variabilei noastre CSS care trece de la 1 la 0.

Când o = 1, avem (Math.random()*(l-1) + 1). Considerând faptul că funcția random() ne dă o valoare din intervalul [0, 1], valoarea finală va fi în intervalul [L, 1].

Când o = 0, avem (Math.random()*(l-1) + 1 - l) și o valoare în intervalul[0, 1-L].

L este variabila noastră pentru controlarea întârzierii.

Hai să vedem asta în acțiune:

Ne apropiem. Avem un efect frumos de fragmentare dar nu acela pe care l-am văzut la începutul articolului. Acesta nu este atât de lin.

Defectul este legat de funcția random(). Am văzut că fiecare canal alfa trebuie să se animeze între X și Y, deci logic aceste valori trebuie să rămână aceleași. Dar funcția paint() este apelată de multe ori în timpul tranziției, deci de fiecare dată funcția random() ne dă valori diferite X și Y pentru fiecare canal alfa; de aceea și efectul „aleatoriu” pe care îl obținem.

Pentru a rezolva asta trebuie să găsim o cale să stocăm valoarea generată, de exemplu într-o variabilă, astfel încât ea este întotdeauna aceeași pentru fiecare apel al funcției paint(). Hai să considerăm o funcție pseudo-aleatoare, o funcție care generează întotdeauna aceeași secvență de valori. În alte cuvinte, vrem să controlăm sămânța.

Din nefericire, nu putem face asta cu funcția inclusă în JavaScript, random(), deci ca oricare dezvoltator bun, hai să alegem una de pe Stack Overflow.

const mask = 0xffffffff;
const seed = 30; /* actualizează asta pentru a schimba secvența generată */
let m_w  = (123456789 + seed) & mask;
let m_z  = (987654321 - seed) & mask;

let random =  function() {
  m_z = (36969 * (m_z & 65535) + (m_z >>> 16)) & mask;
  m_w = (18000 * (m_w & 65535) + (m_w >>> 16)) & mask;
  var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
  result /= 4294967296;
  return result;
}

Și rezultatul devine:

Avem efectul nostru de fragmentare fără cod complex:

  • un ciclu de bază îmbricat pentru a crea dreptunghiuri N x M
  • o formulă deșteaptă pentru canalul alfa pentru a crea întârzierea tranziției
  • o funcție random() pregătită luată de pe Web

Asta este tot! Tot ce trebuie să facem este să aplicăm proprietatea mask oricărui element și să ajustăm variabilele CSS. -webkit-mask funcționează astfel: când un pixel din mască are opacitatea 1, pixelul corespunzător din fundal se afișează. Când pixelul din mască are opacitatea 0, pixelul corespunzător din fundal nu se afișează. Între 0 și 1 există desigur niveluri intermediare ale aceluiași efect.

Lupta cu golurile!

Dacă te joci cu demonstrațiile de mai sus vei observa, în unele cazuri particulare, goluri ciudate între dreptunghiuri (în cazul meu, când schimb în CodePen zoom-ul la 0.25x).

Pentru a le evita, putem extinde suprafața fiecărui dreptunghi cu un mic decalaj.

Înlocuim asta:

ctx.fillRect(i*w, j*h, w, h);

…cu asta:

ctx.fillRect(i*w-.5, j*h-.5, w+.5, h+.5);

Aceasta creează o mică suprapunere între dreptunghiuri care compensează golurile dintre ele. Nu există nici o logică anume pentru valoarea 0.5 pe care am folosit-o. Poți folosi mai mari sau mai mici bazat pe cazul tău de utilizare.

Dorești mai multe forme?

Poate fi ce este mai sus extins să considere mai mult decât forme dreptunghiulare? Sigur că se poate! Hai să nu uităm că putem folosi Canvas pentru a picta oricare formă — spre deosebire de formele realizate cu CSS pur în care avem nevoie uneori de coduri ciudate. Hai să încercăm să construim acel efect de fragmentare triunghiulară.

După ce am căutat pe web, am găsit ceva numit triangularea Delaunay. Nu voi intra în teoria avansată din spatele ei, dar este un algoritm pentru o mulțime de puncte pentru a picta triunghiuri conectate cu proprietăți specifice. Sunt multe implementări gata de a fi folosite ale ei, dar vom folosi Delaunator deoarece se presupune că este cel mai rapid din mulțime.

Mai întâi definim o mulțime de puncte (vom folosi random() aici) apoi vom rula Delaunator pentru a genera triunghiurile pentru noi. În acest caz, avem nevoie doar de o variabilă care definește numărul de puncte.

const n = properties.get('--f-n');
const o = properties.get('--f-o');
const w = size.width;
const h = size.height;
const l = 7; 

var dots = [[0,0],[0,w],[h,0],[w,h]]; /* întotdeauna includem colțurile */
/* generăm N puncte aleatorii în suprafața elementului */
for (var i = 0; i < n; i++) {
  dots.push([random() * w, random() * h]);
}
/**/
/* apelăm Delaunator pentru a genera triunghiurile */
var delaunay = Delaunator.from(dots);
var triangles = delaunay.triangles;
/**/
for (var i = 0; i < triangles.length; i += 3) { /* trecem prin punctele triunghiurilor */
  /* desenăm calea triunghiurilor */
  ctx.beginPath();
  ctx.moveTo(dots[triangles[i]][0]    , dots[triangles[i]][1]);
  ctx.lineTo(dots[triangles[i + 1]][0], dots[triangles[i + 1]][1]);
  ctx.lineTo(dots[triangles[i + 2]][0], dots[triangles[i + 2]][1]);  
  ctx.closePath();
  /**/
  var alpha = (random()*(l-1) + 1) - (1-o)*l; /* the alpha value */
  /* umplem suprafața triunghiurilor cu o culoare semitransparentă */
  ctx.fillStyle = 'rgba(0,0,0,'+alpha+')';
  /* considerăm conturul pentru a umple golurile */
  ctx.strokeStyle = 'rgba(0,0,0,'+alpha+')';
  ctx.stroke();
  ctx.fill();
} 

Nu mai am de adăugat nimic la comentariile din codul de mai sus. Pur și simplu am folosit ceva JS de bază și chestii Canvas și totuși avem un efect destul de frumos.

Putem face chiar mai multe forme! Tot ce trebuie să facem este să găsim un algoritm pentru ele.

Nu pot trece mai departe fără să fac forma de hexagon!

See the Pen houdini mask – hexagon by Temani Afif (@t_afif) on CodePen.

Am luat codul din acest articol scris de Izan Pérez Cosano. Variabila noastră este acum R care va defini dimensiunea unui hexagon.

Ce urmează?

Acum că ne-am construit efectul de fragmentare, hai să ne concentrăm pe CSS. Observi că efectul este atât de simplu ca schimbarea valorii opacity (sau valoarea oricărei proprietăți cu care lucrăm) a unui element în starea lui de hover (acoperire cu mausul sau stilusul).

Animarea opacității

img {
  opacity:1;
  transition:opacity 1s;
}

img:hover {
  opacity:0;
}

Efectul de fragmentare

img {
  -webkit-mask: paint(fragmentation);
  --f-o:1;
  transition:--f-o 1s;
}

img:hover {
  --f-o:0;
}

Aceasta înseamnă că putem ușor integra acest fel de efect pentru a crea animații mai complexe. Aici sunt o mulțime de idei!

Galerie de imagini responsive

Altă versiune a aceleiași galerii:

Efect de zgomot

Ecran de încărcare

Efect de acoperire a unui card

Încheiere

Și toate acestea sunt doar vârful aisbergului a ceea ce poate fi realizat cu Paint API. Voi încheia cu două puncte importante:

  • API-ul Paint este 90% <canvas>, deci cu cât știi mai multe despre <canvas>, cu atât poți face lucruri mai interesante. Canvas este folosit mult, ceea ce înseamnă că este multă documentație și scrieri multe despre ele care să te aducă la viteză. Hei, este unul chiar aici, pe CSS-Tricks!
  • API-ul Paint ne scutește de toată complexitatea din partea CSS a lucrurilor. Nu trebuie să avem de a face cu coduri complexe și ciudate pentru a picta lucruri frumoase. Aceasta face codul CSS cu atât mai ușor de menținut, fără să menționez că este mai puțin vulnerabil la erori.

Acest articol a fost 90% preluat și tradus din:

care face parte din seria: Explorând CSS Paint API (în engleză):

Categorii
Programare

Magazin online al Lupilor Carpatini

Am realizat acest site cu WordPress și WooCommerce pentru oameni buni, frumoși, serioși, care doresc o Românie mai bună și mai frumoasă pentru noi și pentru viitoarele generații.

Îmi face plăcere să lucrez cu ei. Sunt punctuali și plini de înțelepciune.

Nu merge în fața mea, s-ar putea să nu te urmez. Să nu mergi în spatele meu, s-ar putea să nu te ghidez. Mergi alături de mine ca frate!

Lupii sunt animale care reprezintă noblețe și seriozitate, unitate în luptă! Carpații sunt munți ai României sau ai Daciei! Un magazin online pentru lupii apărători ai Daciei este binevenit! Banii câștigați revin fundației Lupilor Carpatini care luptă pentru viitorul țării noastre!

Vă recomand să vizitați site-ul și să vedeți ce produse au la vânzare!

Categorii
Programare

Limita flexibilității JSX în React

Această limită constă în funcții anonime care autoapelează și execută un bloc întreg de instrucțiuni (sau mai multe incorporate în el).

<div>
  {((y) => {
    const x = 5 + 5 + y;
    return x;
  })(10)}
</div>

În interiorul funcției de mai sus, funcție care primește un parametru y cu valoarea 10 și returnează valoarea finală 5 + 5 + 10, poate fi pusă orice structură logică JavaScript. Această bucată de cod afișează textul „20” (fără ghilimele) în interiorul unui <div>.

Acest fel de funcție se numește IIFE (https://developer.mozilla.org/en-US/docs/Glossary/IIFE).

Dacă în schimb punem {5+5+z} unde z este o variabilă declarată cu var, este posibil să se afișeze doar ultima valoare a lui z în caz că al nostru cod este, de exemplu, într-un ciclu for cu contorul z . Problema nu apare când se folosește let în loc de var . Mai multe informații găsiți aici: https://developer.mozilla.org/en-US/docs/Glossary/IIFE#for_loop_with_var_before_es6 .

{(() => {
  const a = [];
  for (var i = 0; i < 5; ++i) {
    a.push(
      <button
        onClick={() => {
          alert(i); // afișează mereu 5
        }}
      >
        Butonul {i + 1}
      </button>
    );
  }
  return a;
})()}

Corectat, codul arată astfel:

{(() => {
  const a = [];
  for (let i = 0; i < 5; ++i) {
    a.push(
      <button
        onClick={() => {
          alert(i); // afișează numerele de la 0 inclusiv la 4 inclusiv
        }}
      >
        Butonul {i + 1}
      </button>
    );
  }
  return a;
})()}

În fine, astfel de expresii pot fi folosite și în interiorul valorii unui prop:

<div
  style={{
    fontSize: ((y) => {
      const x = 5 + 5 + y;
      return x;
    })(1)
  }}
>
  Micul meu div
</div>

Cutie de nisip cu cod: https://codesandbox.io/s/hungry-breeze-qlyi6?file=/src/App.tsx .

Dacă aveți întrebări sau feedback, nu ezitați să scrieți în comentarii mai jos. Toate gândurile bune!

Categorii
Programare

Cum pot avea un al treilea server în Razzle?

În acest articol voi prezenta una din căile de a face un al treilea server într-un proiect Razzle. Mai exact, un server care poate fi HTTP sau WS (WebSockets) sau oricare script Node.js, care poate fi simplu JS sau care se compilează din TS (TypeScript), cu aceleași path alias-uri ca cele pentru serverul principal și care poate folosi sintaxa de importuri din ES6.

  1. Rulează comanda asta (adaptează la yarn dacă e cazul):
npm i --save razzle-start-server-webpack-plugin

2. Adaugă asta în fișierul razzle.config.js la început:

const StartServerPlugin = require("razzle-start-server-webpack-plugin");

3. Adaugă asta în fișierul razzle.config.js ca metodă a lui module.exports:

modifyWebpackConfig(opts) {
  const config = opts.webpackConfig;
  const options = opts.options.webpackOptions;

  if (opts.env.target === 'node') {
    config.entry.secondserver = ['./a/b/c.ts'];

    if (opts.env.dev) {
      config.entry.secondserver.unshift(
        `${require.resolve('webpack/hot/poll')}?300`
      );

      // Pretty format server errors
      config.entry.secondserver.unshift(
        require.resolve('razzle-dev-utils/prettyNodeErrors')
      );

      config.plugins.push(
        new StartServerPlugin(
          Object.assign(options.startServerOptions, {
            entryName: 'secondserver',
            verbose: true,
            debug: true,
            nodeArgs: [],
            killOnExist: true,
            killOnError: true,
            signal: 'SIGTERM'
          })
        )
      );
    }
  }

  return config;
}

unde ./a/b/c.ts este o cale relativă (poate funcționează și cu o cale absolută) la punctul de intrare (entrypoint) în server care poate fi fie .js, fie .ts, fie .tsx (despre .tsx nu știu cât de util este fiindcă n-am folosit JSX în acest al doilea server până acum, dar se compilează ca .ts cel puțin).

4. Pentru ca pasul următor să funcționeze, instalează:

npm i --save-dev concurrently

5. Pentru a putea rula în mediu de dezvoltare acest server e suficient să execuți npm start. Pentru producție mai este o schimbare necesară. În fișierul package.json modifică script-ul următor astfel:

"start:prod": "NODE_ENV=production concurrently \"node build/server.js\" \"node build/secondserver.js\""

Acum pe producție se poate rula cu comanda npm run start:prod.

Notă: noul server folosește același tsconfig.json care e folosit de celălalt server și poate include fișiere (de exemplu, de tip TypeScript) incluse de celălalt server.

Aveți întrebări sau feedback constructiv? Vă rog să scrieți mai jos în comentarii. Mulțumesc.

Categorii
Programare

Script Fish de afișare a unui comentariu TODO aleator

Pentru a lucra mai uniform pe un proiect, am creat acest script mic.

#!/usr/bin/env fish

# This script prints a random TODO or FIXME comment from the project's code.

set VALS (find . -type f \( -name "*.tsx" -o -name "*.ts" -o -name "*.js" -o -name "*.sh" -o -name "*.json" -o -name ".prettierignore" -o -name ".env.*" \) -not -path "./build/*" -not -path "./cache/*" -not -path "./node_modules/*" -print)

for val in $VALS
  set LOCAL_OUTPUT (grep --color=always -ni -HE "(TODO|FIXME):" $val)

  for val2 in $LOCAL_OUTPUT
    set -ga FINAL_OUTPUT $val2
  end
end

random choice $FINAL_OUTPUT
  • acesta este un script fish, nu bash
  • el ignoră fișierele care nu au una dintre extensiile tsx, ts, js, sh, json, prettierignore și nu sunt fișiere .env, sau nu sunt în directoarele build, cache sau node_modules
  • afișarea este colorată
  • se afișează și numele fișierului, și linia pe care s-a găsit comentariul și comentariul găsit este început cu font aldin
  • căutarea este indiferentă la deosebirea între litere mari și mici
  • suportă TODO dar și FIXME și este ușor de implementat suport pentru alte tipuri de comentarii
  • acest script trebuie rulat din dosarul rădăcină al proiectului (cel care conține node_modules, de exemplu)

Imagine

Categorii
Programare

Portofoliu în lucru

(Lucruri noi sunt în pregătire și cred că voi pune cândva datele de pe Patreon pe blogul prezent.)

  1. Lupii Carpatini Store
  2. https://silviubogan.ro – acesta este site-ul (și blogul) prezent (vechiul blog este aici și în viitor voi copia conținutul aici, pe noul site)
  3. Tutoriale video de Unity în limba română
  4. Timed Silver
  5. SilverEdu Memory Game
  6. SilverEdu Number Snake
  7. qt-mathemakid (legătură la articol Patreon) – software educațional de matematică pentru copiii din clasa a VI-a
  8. qt-file-manager
  9. qt-unelte-dex
  10. Folder Index
  11. qt-cli-folder-index
  12. web-darmaths
  13. qt-crystaldev
  14. web-edu-chimie
  15. qt-analiza-text
  16. qt-generare-orar
  17. web-generare-orar
  18. simulare-postulatele-lui-einstein
  19. qt-acidlink
  20. simulare-efectul-compton
  21. qt-timeout
  22. cs-powerpoint-presentation-resource-extactor
  23. cs-systemuptime
  24. cs-winforms-schimbarea-bazei-intr-un-spatiu-vectorial
  25. rb-humble-bug

Alte link-uri ale prezenței mele online

Mici diplome obținute după terminarea liceului

Această imagine are atributul alt gol; numele fișierului este a8cf2-cert-1014-2443670.jpg
Această imagine are atributul alt gol; numele fișierului este ceb09-cert-1023-2443670.jpg
Această imagine are atributul alt gol; numele fișierului este 0927c-cert-1059-2443670.jpg
Această imagine are atributul alt gol; numele fișierului este 81975-15672718_1815521342054130_1844429403550903196_n.jpg
Categorii
Programare

Trei tutoriale video gratuite de Unity în limba română

Acest articol a fost publicat de mine în engleză, în data de 19.01.2020, pe primul meu blog WordPress, articol cu titlul „Unity video tutorials in Romanian” și cu etichetele tutorial și unity. Acest articol este mai finisat, fiindcă dată fiind și nevoia traducerii în română, mi-am permis să-l retușez.


Pe calea mea de a învăța Unity, am realizat câteva tutoriale gratuite și le-am pus pe YouTube.

Tutorial Unity pentru crearea unei animații de glisare
Tutorial Unity pentru crearea unui indicator de sănătate
Tutorial Unity pentru crearea unui ecran cu numărătoare inversă
Categorii
Programare

Ce face hook-ul useCallback și de ce este foarte bun uneori

Pe scurt, este vorba de optimizarea aplicației React.

Pentru cei care nu știu ce este React, React este un cadru de lucru pe aplicații web. Dacă aveți întrebări despre React, vă răspund în limita timpului disponibil.

Revin:

  1. useCallback nu este pentru ca funcția (primită ca parametru de către useCallback) să nu fie recreată. Ea este recreată. Din câte știu nu s-a inventat procesarea unei funcții în stil leneș (s-ar numi lazily defined functions? nu cred că ar fi folositoare o astfel de facilitate)
  2. useCallback este pentru când referința unui gestionar de eveniment (sau altă funcție) trebuie să fie constantă (de-a lungul mai multor randări), de exemplu:
<Button onClick={myCallback}>Click me</Button>

Acest cod rerandează instanța componentei Button la fiecare schimbare a referinței myCallback. Dacă myCallback este realizat cu useCallback, el este mai eficient.

Este în discuție referința care ajunge la codul de randare. Schimbarea ei duce la rerandare care posibil nu este destul de eficientă în multe cazuri.

Excepția este când componenta, care mai sus se numește Button, conține și o funcție componentShouldUpdate din ciclul de viață al componentelor React ce specifică de exemplu proprietăți la a lor modificare să nu producă rerandare.

Cunoașteți o alternativă pentru componentShouldUpdate în cazul componentelor React de tip funcție?


Aveți întrebări sau sugestii sau vorbe bune? Vă rog să le scrieți în comentarii.

Categorii
Programare

Ce să faci când starea inițială a store-ului Redux nu este configurată în SSR bine?

Cel mai probabil este o problemă foarte mică. Voi vorbi despre ea mai jos.

Când hydrate nu funcționează împreună cu SSR astfel încât apelurile la dispatch făcute la montarea componentelor nu sunt executate deloc pe client, chiar dacă la apăsarea unor link-uri din aplicație unele sunt, atunci încearcă să rezolvi erorile din consola DevTools cu nepotriviri între HTML-ul realizat prin SSR și cel de pe client. Această verificare este valabilă doar în mediu de development, nu și de producție, deci nu afectează performanța aplicației. hydrate doar asociază ascultătorii de evenimente la componentele primite în HTML-ul din SSR, spre deosebire de render.

Categorii
Programare

Mică tehnică de depanare ușoară de TypeScript în Chromium DevTools

Eu folosesc Chromium pentru lucru, nu Chrome. Motivul este că Chromium este OSS. Dar ar trebui să funcționeze cele spuse mai jos și la Google Chrome.

Suportul pentru TypeScript în DevTools este limitat la source maps (cele existente și pentru SCSS), dar ele nu sunt, în formatul prezent disponibile pentru o depanare TypeScript cel puțin la fel de bună ca a JavaScript din unele privințe.

Mă refer la cutiuța de text informativ. Ea apare deasupra unei variabile pentru a-i afișa conținutul și plutește până la un alt eveniment.

Deci, să presupunem că sunt în mijlocul unei sesiuni de depanare și am intrat în modul rupere, eventual am pus și step in, over, out, next etc. Dacă am un cod de felul acesta:

și duc mausul deasupra variabilei Categories, se comportă ca și cum ar fi un comentariu acolo, privind înspre reacția evenimentului mausului. Nu există mesaj informativ pentru Categories, deși în contextul în care se află depanarea, în scopul variabilei Categories, se află poziția de depanare.

Vedem în condiția clauzei condiționale if un lucru important. Este vorba de o instrucțiune relativ complexă care accesează mai multe variabile.

Putem evita această lipsă de informații, care se prelungește și în consola DevTools. Vom crea variabile sau constante temporare, fiecare pe rândul ei, deasupra condiției if. Apoi, restartând sesiunea de depanare (VS Code-ul, tab-ul, server-ul, browser-ul, în funcție de alți factori care și cum), DevTools astfel arată:

Nu ezitați să-mi scrieți comentarii, sugestii, idei, orice feedback!

Toate gândurile bune!