css 如何在JS中创建具有数千个属性的线性渐变

fcg9iug3  于 2023-01-10  发布在  其他
关注(0)|答案(1)|浏览(119)

我正在做一个非常低效的重画工具,它获取画布上的每个像素,并获取其颜色值,然后将这些数据插入到一个单独div上的线性渐变CSS属性中。我希望线性渐变创建一个不褪色的效果,其中每个像素都有一个单独的颜色。我也不知道线性渐变将如何与我的像素颜色值对齐,因为它会逐个读取每一行。

我的其他值,如百分比和数据是任意的,因为我已经计算出来了

var data=(img_ctx.getImageData(x,y,1,1).data);
        draw.style.background+=" ,linear-gradient(0deg, "+Math.floor(percent)+"%, rgba("+data+")";

我刚得到了一个没有背景样式属性的div,我添加了逗号来允许多种颜色,我只是不确定如何使用线性渐变来解决这个问题。

ovfsdjhp

ovfsdjhp1#

线性渐变只有一个轴,并且在垂直方向填充容器。换句话说,你只能控制一个颜色在轴上的宽度,这样就不可能在大于1px的div中创建1px x 1px的颜色。
因此,实现重绘的唯一方法是创建一个高度为1px的div堆栈(或宽度为1px的列)。
然后,您可以通过为每个颜色添加两个停止点来沿主轴将颜色包含在1px内,以指示主轴的起点和终点。

const scale = 0.1;

const canvas = document.querySelector('canvas');

const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = onload;

fetch('https://i.kym-cdn.com/entries/icons/original/000/006/428/637738.jpg')
  .then((res) => res.blob())
  .then((blob) => (img.src = URL.createObjectURL(blob)));

function onload() {
  const w = img.width * scale;
  const h = img.height * scale;
  canvas.width = w;
  canvas.height = h;
  canvas.style.width = w.toString() + 'px';
  canvas.style.height = h.toString() + 'px';

  ctx.drawImage(img, 0, 0, w, h);

  const pixelData = Array.from(ctx.getImageData(0, 0, w, h).data);

  for (let row = 0; row < h; row++) {
    const rowDiv = document.createElement('div');
    rowDiv.style.width = w.toString() + 'px';
    rowDiv.style.height = '1px';

    const rowStart = row * w * 4;
    let background = 'linear-gradient(to right,';
    for (let col = 0; col < w; col++) {
      const pixelStart = rowStart + col * 4;
      background +=
        'rgba(' +
        pixelData[pixelStart] +
        ',' +
        pixelData[pixelStart + 1] +
        ',' +
        pixelData[pixelStart + 2] +
        ',' +
        pixelData[pixelStart + 3] +
        ')' + col + 'px ' + (col + 1) + 'px,';
    }
    rowDiv.style.background = background.slice(0, -1) + ')';
    document.body.append(rowDiv);
  }
}
<h1>Canvas</h1>
<canvas></canvas>

<h1>Gradients</h1>

但是在这一点上,你可能只是为每个像素创建一个div。

相关问题