PageSourceSearch

https://yopagomenos.co/assets/controllers/progreso_scroll_controller-26d094b9.js

js yopagomenos.co collected 2026-10-09 22:56:38 UTC 3,606 bytes, 68 lines download raw bytes

1import { Controller } from "@hotwired/stimulus"
2
3// Barra de progreso de lectura que recorre los cuatro bordes de la pantalla: nace en el centro
4// del borde superior y baja simétrica por los dos lados (un brazo horario, otro antihorario)
5// hasta juntarse en el centro del borde inferior, para hacer visible que la propuesta sigue
6// hacia abajo y que el final (donde vive el CTA) se alcanza.
7//
8// La meta NO es el fondo de la página sino el elemento marcado con [data-progreso-scroll-meta]
9// (el CTA final): el marco se completa cuando este entra entero en pantalla — lo que hay
10// detrás (opiniones, FAQ) es refuerzo, no camino. Sin ese marcador (p. ej. propuesta caducada,
11// sin CTA final), cae al alto total del documento.
12//
13// El target es un <rect> SVG a pantalla completa con pathLength="1": el perímetro va de 0 a 1
14// empezando en la esquina superior izquierda y en sentido horario. Pintar el avance es un
15// único tramo de longitud `avance` centrado en el punto medio del borde superior (que está
16// en t = (W/2) / (2W+2H), NO en una constante: pathLength reparte por longitud real, así el
17// recorrido va a velocidad uniforme por los cuatro lados). El tramo se coloca con
18// stroke-dashoffset y el patrón "avance, 1-avance" tiene periodo 1, con lo que el brazo que
19// va hacia la izquierda envuelve por t=0 sin corte. El color sale de la variable CSS --avance
20// (azul → esmeralda vía color-mix en la vista): la punta llega verde al final, el mismo
21// esmeralda que la página usa para "ahorro/hecho". Mejora progresiva: el contenedor llega con
22// `hidden` y es este controller quien lo enseña — sin JS no queda una pista vacía pintada
23// alrededor.
24export default class extends Controller {
25  static targets = ["barra"]
26
27  connect() {
28    this.frame = null
29    this.programar = this.programar.bind(this)
30    window.addEventListener("scroll", this.programar, { passive: true })
31    window.addEventListener("resize", this.programar, { passive: true })
32    // removeAttribute y no `.hidden = false`: el elemento es un <svg> y SVGElement no tiene la
33    // propiedad IDL `hidden` (solo HTMLElement); la asignación crearía un expando sin efecto.
34    this.element.removeAttribute("hidden")
35    this.actualizar()
36  }
37
38  disconnect() {
39    window.removeEventListener("scroll", this.programar)
40    window.removeEventListener("resize", this.programar)
41    if (this.frame) cancelAnimationFrame(this.frame)
42  }
43
44  // Coalescer a un frame: scroll dispara muchas veces por gesto y con pintar una vez basta.
45  programar() {
46    this.frame ??= requestAnimationFrame(() => {
47      this.frame = null
48      this.actualizar()
49    })
50  }
51
52  actualizar() {
53    const meta = document.querySelector("[data-progreso-scroll-meta]")
54    const total = meta
55      ? window.scrollY + meta.getBoundingClientRect().bottom - window.innerHeight
56      : document.documentElement.scrollHeight - window.innerHeight
57    const avance = total > 0 ? Math.min(Math.max(window.scrollY / total, 0), 1) : 1
58    // El punto medio del borde superior en unidades de perímetro. Se mide el svg (no el
59    // viewport): con viewport-fit=cover el marco va entre los safe-area-inset y es más bajo
60    // que la pantalla.
61    const { width: ancho, height: alto } = this.element.getBoundingClientRect()
62    const centroArriba = (ancho / 2) / (2 * (ancho + alto))
63    const inicio = centroArriba - avance / 2
64    this.barraTarget.setAttribute("stroke-dasharray", `${avance} ${1 - avance}`)
65    this.barraTarget.setAttribute("stroke-dashoffset", `${-inicio}`)
66    this.barraTarget.style.setProperty("--avance", avance)
67  }
68}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.