【问题标题】:HTML Canvas - color transition between shapes ( shapes not overlapping)HTML Canvas - 形状之间的颜色过渡(形状不重叠)
【发布时间】:2020-12-29 18:24:48
【问题描述】:

图像是我期待使用 html 画布实现的,不使用模糊或阴影

问题: 有没有办法从图像的左侧部分实现图像的右侧部分?

问题的解决办法是(基础图)here

var canvas = document.createElement('canvas'),
d = canvas.width = canvas.height = 400,
sq_size = d / 10,
ctx = canvas.getContext('2d');
document.body.appendChild(canvas); 

var color=["rgb(10,110,10)", "rgb(81,169,255)","rgb(81,239,255)", 
"rgb(81,255,202)", 
"rgb(81,255,132)","rgb(99,255,81)","rgb(169,255,81)", 
"rgb(239,255,81)", "rgb(255,202,81)","rgb(255,132,81)"];

var x=0, len=color.length;
for(var i=0; i < d; i++){
  while(x < d) {
    var c = Math.floor(Math.random() * len);
    
    ctx.fillStyle = color[c];
    ctx.fillRect(x,i,sq_size,sq_size);
    x = x + sq_size;
  }
  x = 0;
  i = i+sq_size;
}

【问题讨论】:

  • 您已更改问题“应该使用数百万的数据集。” 数百万什么?与其在接受答案后更改问题,不如提出一个新问题。
  • @Blindman67 对答案进行了编辑。它被拒绝了。该解决方案有效。我不接受它,因为渲染时间在更大的数据集上显着增加。
  • 我拒绝了编辑,因为它不正确答案是 O(1) 而不是 O(2*n),因为您的编辑声称。您的编辑应该是评论。答案只画了 2 张图片。

标签: javascript html5-canvas


【解决方案1】:

在不实施模糊的情况下可以获得的最接近的值。

您可以使用图像平滑ctx.imageSmoothingEnabled 来模糊分辨率非常低的图像。然后使用ctx.globalAlpha混合模糊和未模糊的图像

示例

pixelSize 控制模糊量。值 1 是最大数量,并且随着该值变大而变小。必须是整数值,例如 1, 2, 3, 4, ...

笔记结果会因使用的设备和浏览器/版本而异。

requestAnimationFrame(animationLoop);
const size = canvas.width;
const ctx = canvas.getContext('2d');
var mix = 123; // amount to transition 
const transitionTime = 2; // seconds per transition
const swatches = [0,1,2];
const pixelSize = 2;
// eCurve p = 1 linear curve [default p = 2] is quadratic curve p = 3 cubic curve and so on.
const eCurve = (v, p = 2) =>  v < 0 ? 0 : v > 1 ? 1 : v ** p / (v ** p + (1 - v) ** p);
const cols = [
   [10, 110, 10], [81, 169, 255], [81, 239, 255], [81, 255, 202], [81, 255, 132], 
   [99, 255, 81], [169, 255, 81], [239, 255, 81], [255,202, 81], [255,132,81]
];
const img = document.createElement("canvas");
img.height = img.width = swatches.length * pixelSize;
const imgCtx = img.getContext('2d');
function randomSwatch() {
    swatches.forEach(y => { swatches.forEach(x => {
          imgCtx.fillStyle = "rgb("+cols[Math.random() * cols.length | 0].join(",")+")";
          imgCtx.fillRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize);
     }); });
}
function animationLoop() {
     mix = (mix >= 4 ? (randomSwatch(), 0) : mix) + 1 / (transitionTime * 60);
     ctx.globalAlpha = 1;
     ctx.imageSmoothingEnabled = false;
     ctx.drawImage(img, 0, 0, size, size);
     ctx.imageSmoothingEnabled = true;
     const a = mix % 2;
     ctx.globalAlpha = eCurve(a > 1 ? 2 - a : a, 3);
     ctx.drawImage(img, 0, 0, size, size);
     requestAnimationFrame(animationLoop);
}
&lt;canvas id="canvas" height="300" width="300"&gt;&lt;/canvas&gt;

【讨论】:

    【解决方案2】:

    这个解决方案最适合我。符合我的大型数据集。 不是 O(1),我也不可能认为它可以,甚至是 O(n)(小玩笑)。

    P.s:代码可以进一步优化。

    小提琴here

    var canvas = document.createElement('canvas'),
    d = canvas.width = canvas.height = 250,
    sq_size = d / 5,
    ctx = canvas.getContext('2d');
    document.body.appendChild(canvas);
    canvas.setAttribute('id','cav');
    
    var color=["rgb(10,110,10)", "rgb(81,169,255)","rgb(81,239,255)", "rgb(81,255,202)", "rgb(81,255,132)","rgb(99,255,81)","rgb(169,255,81)", "rgb(239,255,81)", "rgb(255,202,81)","rgb(255,132,81)"];
    
    var x=0, len=color.length;
    var prevcolorh;
    var colorobj = {};
    for(var i=0; i < d;){
        colorobj[i] = {};
        while(x < d) {
            var c = Math.floor(Math.random() * len);
            colorobj[i][x] = color[c];
        
            var gradient = ctx.createLinearGradient(x, 0, x+sq_size, 0);
        
            var a = (prevcolorh !== undefined) ? prevcolorh : colorobj[i][x];
        
            gradient.addColorStop(0, a);
            gradient.addColorStop(1, colorobj[i][x]);
        
            prevcolorh = colorobj[i][x];
        
            ctx.fillStyle = gradient;
            ctx.fillRect(x, i, d, d);
        
            x = x + sq_size;
        }
        x = 0;
        i = i+sq_size;
    }
    
    var rgbs = {};
    for(var i=0; i<d; i+=sq_size) {
        var imgd = ctx.getImageData(0, i+(sq_size/2), d, sq_size);
        rgbs[i] = {};
        var arr = [];
    
        for (var j = 0, c = 0, n = imgd.data.length; j < n; j += 4, c++) {
            if(j > 0 && j < d*4) {
             arr.push([imgd.data[j],imgd.data[j+1],imgd.data[j+2],imgd.data[+3]]);
            }
        }
        rgbs[i] = arr;
    }
    
    for(var k in rgbs) {
        for(var i=0; i<rgbs[k].length; i++) {
            if(rgbs[parseInt(k)+sq_size] !== undefined) {
                var gradient2 = ctx.createLinearGradient(0, parseInt(k)+(sq_size/2), 0, parseInt(k)+(sq_size/2) + sq_size);
    
                gradient2.addColorStop(0, 'rgba('+rgbs[k][i].join(',')+')');
                gradient2.addColorStop(1, 'rgba('+rgbs[parseInt(k)+sq_size][i].join(',')+')');
            
                ctx.fillStyle = gradient2;
                ctx.fillRect(i, parseInt(k)+(3*sq_size/4), 1, sq_size/2);
             
          }
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-07
      • 2017-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 2016-08-21
      • 1970-01-01
      相关资源
      最近更新 更多