在画布中创建像动画一样的嘈杂杂波

Posted

技术标签:

【中文标题】在画布中创建像动画一样的嘈杂杂波【英文标题】:Creating noisy choatic wave like animations in canvas 【发布时间】:2014-03-28 04:14:56 【问题描述】:

我正在尝试在屏幕上实现混乱的波动,就好像您的计算机即将爆炸一样。在 Photoshop 中,这个概念是由噪声过滤器创建的,然后通过噪声推动一个滤波器以使其具有这种外观 我已经使用<canvas> 元素创建了噪声,但是有人对如何推动一个通过噪音或任何其他方式来获得这种预期的效果?

我有 4 个示例 jsfiddles 可以作为起点: 感谢Ken 提供这些示例:

really close starting point that i found

JSfiddle Color noise

JSFiddle bluescreen noise

JSFiddle flicker blue noise

JS:

var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d');
// a variant using fixed canvas size but strecthes the result.
// emulates interference/bad reception
// using a different "noise" algo
canvas.width = canvas.height = 256;

function resize() 
    canvas.style.width = window.innerWidth + 'px';
    canvas.style.height = window.innerHeight + 'px';

resize();
window.onresize = resize;

function noise(ctx) 

    var w = ctx.canvas.width,
        h = ctx.canvas.height,
        idata = ctx.getImageData(0, 0, w, h),
        buffer32 = new Uint32Array(idata.data.buffer),
        len = buffer32.length,
        i = 0,
        pr = 456 * Math.random(),
        prs = 716 * Math.random();;

    for(; i < len;) 
        buffer32[i++] = ((pr % 255)|0) << 24;
        pr += prs * 1.2;
    

    ctx.putImageData(idata, 0, 0);


var toggle = true;

// added toggle to get 30 FPS instead of 60 FPS
(function loop() 
    toggle = !toggle;
    if (toggle) 
        requestAnimationFrame(loop);
        return;
    
    noise(ctx);
    requestAnimationFrame(loop);
)();

HTML

<canvas id="canvas"></canvas>

CSS

html, body 
    background:#0000cc;
    margin:0;

#canvas 
    position:fixed;
    background:#0000dd;
    opacity: .2;

reference question

【问题讨论】:

你总是可以使用这样的东西:jsfiddle.net/m1erickson/DAShs 来生成波浪,你可以将它与 globalCompositeOperation = "source-in";获得静态的波浪 (developer.mozilla.org/samples/canvas-tutorial/…) 我正在阅读这篇文章...当谈到画布时,我是个大菜鸟。任何答案将不胜感激。 【参考方案1】:

要添加波浪,您可以使用以下代码扩展我在那里编写的噪声代码:

Live demo

// add a var to global/parent scope
var offset = 0;

// modify method like this:
function noise(ctx) 

    var w = ctx.canvas.width,
        h = ctx.canvas.height,
        idata = ctx.getImageData(0, 0, w, h),
        buffer32 = new Uint32Array(idata.data.buffer),
        len = buffer32.length,
        i = 0,
        pr = 456 * Math.random(),
        prs = 716 * Math.random();;

    for(; i < len;) 
        buffer32[i++] = (((pr % 255)|0) << 24) | 0x440000;
        pr += prs * 1.2;
    

    ctx.putImageData(idata, 0, 0);
    
    // wave (utilizes GPU in modern browsers)
    for(i = 0; i < w; i += 2) 
        var y = i * Math.sin((i + (offset++)) /100);
        ctx.drawImage(ctx.canvas, i,0, 1, h,  i, y, 1, h);
    

这里发生的是它首先渲染噪声,然后水平扫描画布并根据或多或少的随机正弦偏移来偏移它们。我们添加到全局变量以对其进行动画处理。

过去切片速度较慢,但​​在支持 GPU 硬件的现代浏览器中,它应该运行得非常快。

我在原始代码和这个版本中使用的所有值都是随机的。只需调整偏移量、大小等,看看是否能得到你想要的结果。

您可以通过更改“alpha”行的最后一部分来更改对比度:

0x440000

请注意,在 little-endian 机器(如 Intel CPU)的低级缓冲区中,颜色按 ABGR 排列。

更新

这是一个更丰富多彩的版本:

Demo (more colors)

唯一改变的是这一行:

buffer32[i++] = (((pr % 255)|0) << 24) | 0x770000 + (Math.random() * 16777216)|0;

(我相信它可以在很多方面进行改进,但只是玩弄它)。

看到有问题的新链接(起点) - 它与我想象的(基于发布的图像)有很大不同。你需要一种完全不同的方法。

希望这会有所帮助! :)

【讨论】:

啊,drawImage 用于一个 1 像素宽的矩形......我不得不创建随机图像,然后将其逐个像素转换到新位置:/ @Bergi 也应该可以。使用 32 位缓冲区,像素位移可以非常快。嗯..想象一下从上面看的波浪...... Ken 我早些时候试图找你问你一个修改后的问题,哈哈。但是你找到了我。你知道如何给流添加更多颜色吗? @MatthewHarwood 实际上我偶然看到了这个,只是看着 SO 的首页并发现了一个新的画布问题:) 对于颜色:只需操纵“alpha”行..让我回到洞穴并制作一个模组。 @MatthewHarwood 从洞穴回来,更新了答案

以上是关于在画布中创建像动画一样的嘈杂杂波的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中创建像指南针一样的“滑动视图”?

如何在 Flutter 中创建像这样的自定义可滑动标签栏?

iOS:如何在 iOS 中创建像墙或新闻源一样的 facebook

在原生android中创建像flutter一样的高度卡

如何在 android 中创建像 QuickPic 应用程序这样的裁剪工具?

如何在 Angular 中创建像 Facebook 帖子这样的照片网格?