<andres-carmona />

TIL #9: ownerDocument.defaultView
First published on
on html, javascript, typescript

Aunque me considero un programador con experiencia y llevo mas de 15 anos desarrollando, me sorprendio no conocer la propiedad ownerDocument.defaultView.

Basicamente devuelve el objeto window (o null) asociado a un nodo DOM especifico.

Se puede usar para adjuntar listeners de forma segura al window correcto desde un componente que se renderiza fuera de la ventana principal (por ejemplo, usando portales).

function ThemeProvider({ children }) {
  const [theme, setTheme] = useState("light");
  const ref = useRef(null);

  useEffect(() => {
    const win = ref.current?.ownerDocument.defaultView || window;

    const toggle = (e) => {
      if (e.metaKey && e.key === "d") {
        e.preventDefault();
        setTheme((t) => (t === "dark" ? "light" : "dark"));
      }
    };

    win.addEventListener("keydown", toggle);

    return () => win.removeEventListener("keydown", toggle);
  }, []);

  return (
    <div ref={ref} className={theme}>
      {children}
    </div>
  );
}

Del mismo articulo tambien aprendi sobre useId y cache.

Referencia: https://shud.in/thoughts/build-bulletproof-react-components, gran articulo.


TIL #8: El efecto Fresnel
First published on
on threejs, glsl, webgl, effects

Estoy viendo algunas lecciones pendientes de shaders en el curso de Three.js Journey, y hoy aprendi sobre el efecto Fresnel en Three.js.

Se usa para lograr un render mas realista de materiales al simular como la luz interactua con superficies en diferentes angulos.

El efecto Fresnel hace que las superficies reflejen mas luz en angulos rasantes, lo que aumenta el realismo en materiales como agua, vidrio y metales.

Se puede usar para efectos como:

  • Vidrio/Agua: Simular reflejos realistas en superficies transparentes.
  • Efectos fantasma/energia: Crear un brillo interno o externo que enfatiza la silueta.
  • Resaltar objetos: Una alternativa de bajo costo a efectos de outline para elementos interactivos.

Aqui va una implementacion simplificada del curso de Three.js Journey para crear un efecto holografico:

// Vertex shader.
varying vec3 vPosition;
varying vec3 vNormal;

void main() {
  vec4 modelPosition = modelMatrix * vec4(position, 1.0);
  vec4 modelNormal = modelMatrix * vec4(normal, 0.0);

  gl_Position = projectionMatrix * viewMatrix * modelPosition;

  vPosition = modelPosition.xyz;
  vNormal = modelNormal.xyz;
}
// Fragment shader.
varying vec3 vPosition;
varying vec3 vNormal;

void main() {
  vec3 normal = normalize(vNormal);

  if(!gl_FrontFacing) {
    normal = -normal;
  }

  // Fresnel effect
  vec3 viewDirection = normalize(vPosition - cameraPosition);
  float fresnel = dot(viewDirection, normal) + 1.0;
  fresnel = pow(fresnel, 2.0);

  // Final output
  gl_FragColor = vec4(vec3(0.0, 1.0, 1.0), fresnel);
}

TIL #7: Filtros SVG
First published on
on css, html, svg, effects, filters

Los filtros SVG te permiten crear efectos visuales complejos directamente dentro de tus graficos SVG usando distintos primitives. Puedes aplicar blur, manipulacion de color y distorsiones personalizadas.

Filtros SVG

<p class="ripple-text">Filtros SVG</p>

<svg style="position: absolute; width: 0px; height: 0px; pointer-events: none;">
  <filter id="water-ripple">
    <feTurbulence
      type="fractalNoise"
      baseFrequency="0.05"
      numOctaves="2"
      result="ripple"
    >
      <animate
        attributeName="baseFrequency"
        dur="10s"
        values="0.02;0.05;0.02"
        repeatCount="indefinite"
      ></animate>
    </feTurbulence>
    <feDisplacementMap
      in="SourceGraphic"
      in2="ripple"
      scale="5"
    ></feDisplacementMap>
  </filter>
</svg>
.ripple-text {
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: bold;
  text-align: center;
  filter: url(#water-ripple);
}

TIL #6: Favicons SVG
First published on
on css, html, svg, icons
<svg xmlns="http://w3.org/2000/svg" viewBox="0 0 100 100">
  <text y=".9em" font-size="90">👾</text>
</svg>

Referencia:

Mas sobre SVG favicons y como mantener favicons sin perder la cordura:


TIL #5: comando :source % en vim
First published on
on cli, command, vim, nvim

El comando :source % en Vim recarga el archivo de configuracion (por ejemplo ~/.vimrc) en la sesion actual, aplicando los cambios que hiciste. :source ejecuta los comandos VimScript contenidos en un archivo y % es el atajo para el archivo actualmente abierto en el buffer.

:source %

TIL #4: CSS content-visibility para mejorar performance
First published on
on css, html, performance

content-visiblity Without Jittery Scrollbars

/* Diferir el render del segundo articulo en adelante */
body > main > *+* {
  content-visibility: auto;
}
<script type="module">
  let observer = new IntersectionObserver(
    (entries, o) => {
      entries.forEach((entry) => {
        let el = entry.target;
        // No esta actualmente dentro del area de interseccion.
        if (entry.intersectionRatio == 0) {
          return;
        }
        // Fuerza el render para elementos dentro del area de scroll
        // que aun no hayan sido marcados.
        if (!el.markedVisible) {
          el.attributeStyleMap.set(
            "content-visibility",
            "visible"
          );
          el.markedVisible = true;
        }
      });
    },
    // Define un margen de render de 50px arriba
    // y 100px debajo del area principal.
    { rootMargin: "50px 0px 100px 0px" }
  );

  let els =
    document.querySelectorAll("body > main > *+*");
  els.forEach((el) => { observer.observe(el); });
</script>

TIL #3: Configuracion minima para view transitions
First published on
on html, css, view transitions

La configuracion minima para habilitar view transitions nativas en tu sitio con HTML y CSS:

<meta name="view-transition" content="same-origin" />
@view-transition {
  navigation: auto;
}

Ref URL: https://www.amitmerchant.com/bare-minimum-view-transitions/


TIL #2: Animar elemento details
First published on
on css, html, css-animations

https://developer.chrome.com/docs/css-ui/animate-to-height-auto#animate_the_details_element

@supports (interpolate-size: allow-keywords) {
    :root {
        interpolate-size: allow-keywords;
    }
    
    details {
        transition: height 0.5s ease;
        height: 2.5rem;
        
        &[open] {
            height: auto;
            overflow: clip; /* Recorta el contenido mientras anima */
        }
    }
}

TIL #1: valueAsNumber y valueAsDate en inputs
First published on
on html, inputs, forms

Puedes transformar automaticamente valores de inputs a numero y fecha usando valueAsNumber y valueAsDate en los objetos de input.

// Siempre devuelve NaN porque valueAsNumber no existe en inputs de texto
<input type="text" onChange={e => console.log(e.target.valueAsNumber)} />

// Devuelve el valor como entero o flotante
// dependiendo del atributo step del input
<input type="number" onChange={e => console.log(e.target.valueAsNumber)} />

// Devuelve la fecha como timestamp UNIX, ej. new Date().getTime()
<input type="date" onChange={e => console.log(e.target.valueAsNumber)} />

// Devuelve la fecha como objeto Date de JS
<input type="date" onChange={e => console.log(e.target.valueAsDate)} />

Ref URL: https://devlog.willcodefor.beer/pages/use-valueasnumber-and-valueasdate-on-inputs/