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

huangapple go评论81阅读模式
英文:

How to create linear gradient with thousands of properties in JS

问题

我正在制作一个效率低下的重新绘制工具,它会获取画布上每个像素的颜色值,并将该数据插入到一个单独的div的线性渐变CSS属性中。我希望线性渐变可以创建一个不会褪色的效果,每个像素都会有一个单独的颜色。我也不知道线性渐变如何与我的像素颜色值对齐,因为它是逐行读取的。

**我的其他值,如百分比和数据,是任意的,因为我已经解决了这个问题**

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


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

I'm making a really in-efficient redrawing tool that takes each pixel of a canvas and takes it's color values and plugs that data into a linear gradient CSS property on a separate div. I want the linear gradient to create a non-fading effect where every pixel is going to have a separate color. I also don't know how the linear gradient will align with my pixel-color values since it reads every line one by one.

My other values like percent and data are arbitrary because I already have that figured out

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

I just got a div that has no style properties for background, and I added the comma to allow multiple colors, I'm just not sure how to use linear gradient well enough to figure this out.

答案1

得分: 1

线性渐变只有一个单一轴,并在垂直方向上填充其容器。换句话说,你只能控制沿着该轴的颜色宽度,这使得在大于1像素的div中创建一个1像素 x 1像素的颜色变得不可能。

因此,实现重绘的唯一方法是创建一个高度为1像素的div堆栈(或者宽度为1像素的列)。

然后,通过为每种颜色添加两个停止点来将颜色限制在主轴上的1像素位置,分别指示开始和结束。

英文:

Linear gradients have only a single axis and fill their container in the perpendicular direction. In other words, you can only control the width of a color along that axis, making it impossible to create a 1px x 1px color within a div larger than 1px.

So the only way to achieve the redraw is to create a stack of divs with 1px of height (or columns with 1px width).

You can then contain the colors to 1px along the main axis by adding two stops for each color indicating the start and end along the main axis.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const scale = 0.1;

const canvas = document.querySelector(&#39;canvas&#39;);

const ctx = canvas.getContext(&#39;2d&#39;);
const img = new Image();
img.onload = onload;

fetch(&#39;https://i.kym-cdn.com/entries/icons/original/000/006/428/637738.jpg&#39;)
  .then((res) =&gt; res.blob())
  .then((blob) =&gt; (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() + &#39;px&#39;;
  canvas.style.height = h.toString() + &#39;px&#39;;

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

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

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

    const rowStart = row * w * 4;
    let background = &#39;linear-gradient(to right,&#39;;
    for (let col = 0; col &lt; w; col++) {
      const pixelStart = rowStart + col * 4;
      background +=
        &#39;rgba(&#39; +
        pixelData[pixelStart] +
        &#39;,&#39; +
        pixelData[pixelStart + 1] +
        &#39;,&#39; +
        pixelData[pixelStart + 2] +
        &#39;,&#39; +
        pixelData[pixelStart + 3] +
        &#39;)&#39; + col + &#39;px &#39; + (col + 1) + &#39;px,&#39;;
    }
    rowDiv.style.background = background.slice(0, -1) + &#39;)&#39;;
    document.body.append(rowDiv);
  }
}

<!-- language: lang-html -->

&lt;h1&gt;Canvas&lt;/h1&gt;
&lt;canvas&gt;&lt;/canvas&gt;

&lt;h1&gt;Gradients&lt;/h1&gt;

<!-- end snippet -->

But at this point you might as well just make a div for every pixel.

huangapple
  • 本文由 发表于 2023年1月9日 09:48:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75052533.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定