PageSourceSearch

https://www.pica.cl/assets/js/card-accent.js?v=1783094846

js pica.cl collected 2026-09-25 01:39:37 UTC 2,927 bytes, 79 lines download raw bytes

1/**
2 * card-accent.js — color AUTOMÁTICO: extrae el tono dominante de la portada y
3 * tematiza el cuerpo de la tarjeta (variables --accent/--accent-text + clase
4 * .news-card--themed, cuyo estilo vive en news-accent.css).
5 * Salta las tarjetas con color manual (ya tematizadas por el servidor).
6 * Maneja CORS: si getImageData falla, reintenta con crossOrigin='anonymous'.
7 * Mismo origen, sin dependencias.
8 */
9(function () {
10  'use strict';
11
12  function sample(img) {
13    var w = 20, h = 20;
14    var c = document.createElement('canvas');
15    c.width = w; c.height = h;
16    var ctx = c.getContext('2d');
17    try {
18      ctx.drawImage(img, 0, 0, w, h);
19      var d = ctx.getImageData(0, 0, w, h).data;
20      var r = 0, g = 0, b = 0, n = 0;
21      for (var i = 0; i < d.length; i += 4) {
22        if (d[i + 3] < 125) continue;
23        var mx = Math.max(d[i], d[i + 1], d[i + 2]);
24        var mn = Math.min(d[i], d[i + 1], d[i + 2]);
25        if (mx > 244 && mn > 244) continue;   // casi-blanco
26        if (mx < 12) continue;                 // casi-negro
27        r += d[i]; g += d[i + 1]; b += d[i + 2]; n++;
28      }
29      if (!n) return null;
30      return [Math.round(r / n), Math.round(g / n), Math.round(b / n)];
31    } catch (e) {
32      return null;  // CORS o canvas tainted
33    }
34  }
35
36  function apply(card, rgb) {
37    var lum = 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
38    card.style.setProperty('--accent', 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')');
39    card.style.setProperty('--accent-text', lum > 150 ? '#1a1208' : '#ffffff');
40    card.style.setProperty('--accent-shadow', 'rgba(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ',.5)');
41    card.classList.add('news-card--themed');
42  }
43
44  /**
45   * Intenta samplear la imagen. Si falla (CORS), recarga con crossOrigin.
46   */
47  function tryApply(card, img) {
48    var rgb = sample(img);
49    if (rgb) { apply(card, rgb); return; }
50
51    // Reintento con crossOrigin='anonymous' (una sola vez)
52    if (img.dataset.accentRetried) return;
53    img.dataset.accentRetried = '1';
54    var clone = new Image();
55    clone.crossOrigin = 'anonymous';
56    clone.onload = function () {
57      var rgb2 = sample(clone);
58      if (rgb2) apply(card, rgb2);
59    };
60    // Añadir un cache-buster mínimo si la URL no tiene query
61    clone.src = img.src;
62  }
63
64  function run() {
65    document.querySelectorAll('.news-card').forEach(function (card) {
66      // El servidor ya tematizó las de color manual.
67      if (card.getAttribute('data-accent') === 'manual' || card.classList.contains('news-card--themed')) return;
68      var img = card.querySelector('img.news-card-img-bg');
69      if (!img) return;
70      var go = function () { tryApply(card, img); };
71      if (img.complete && img.naturalWidth) go();
72      else img.addEventListener('load', go);
73    });
74  }
75
76  if (document.readyState !== 'loading') run();
77  else document.addEventListener('DOMContentLoaded', run);
78})();
79

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.