javascript 使用Web Workers进行异步画布绘制

kadbb459  于 2023-06-28  发布在  Java
关注(0)|答案(3)|浏览(178)

所以,我正在制作一个相对简单的HTML5 Canvas绘图Web应用程序。基本上,您可以选择您的颜色,然后在500 x500画布上绘制。这将是一个主题为“涂鸦”墙,所以我试图创造一个涂鸦效果的绘图,很像喷雾工具在微软油漆的昔日。
请随意查看here
为了促进这种效果,我使用了web worker来回调鼠标事件并异步绘制到画布上。我现在的简单实现是,在任何鼠标事件上,在事件坐标周围随机绘制5个像素。
我想做的是,从mousedown事件到mouseup事件连续绘制这些像素,同时更新mousemove事件的坐标。根据我有限的JavaScript知识,我想这可能涉及到setTimeout(),但我不确定如何操作它来实现我想要的。
免责声明:这是一个学校项目的一部分,因此我试图避免使用jQuery、 AJAX 和其他类似的框架;我的目标是做一个尽可能纯粹的JavaScript/HTML5 Web应用程序。
先谢谢你了。

muk1a3rh

muk1a3rh1#

使用计时器(不需要工作人员):

var mouseX = 0,
    mouseY = 0,
    mouseDown = false;

    function ev_canvas( ev ) {
        if (ev.offsetX || ev.offsetX == 0) { //opera
            mouseX = ev.offsetX;
            mouxeY = ev.offsetY;
        } else if (ev.layerX || ev.layerX == 0) { //firefox
            var canvasOffset = document.getElementById("graffiti_wall").getBoundingClientRect();
            mouseX = ev.layerX - canvasOffset.left;
            mouseY = ev.layerY - canvasOffset.top;
        }

        if ( ev.type == 'mousedown' ) {
            mouseDown = true;
        }
        else if ( ev.type == 'mouseup' ) {
            mouseDown = false;
        }
    }

    function draw_spray() {
        if( !mouseDown ) {
            //Don't do anything since the mouse is not pressed down
            return;
        }
        //Draw something at the last known location
        context.strokeRect( mouseX, mouseY, 1, 1 );
    }

    //Call draw_spray function continuously every 16 milliseconds
    window.setInterval( draw_spray, 16 );
elcex8rz

elcex8rz2#

如果你想使用WebWorker(例如更复杂的绘图算法),我可以想到以下设置:

  • onmousedown,生成一个新的worker,并在其上注册一个处理程序,在画布上绘制对象
  • onmouseup(和-leave等),终止工作线程
  • onmousemove,如果存在工作进程,则确定鼠标坐标并将其发送到工作进程中

在工人

  • 监听新的鼠标坐标
  • 启动一个超时间隔,不断触发绘制事件(取决于当前坐标和一个聪明的算法)

但我认为对于一个简单的涂鸦工具来说,Worker的开销太大了。使用简单的解决方案,而无需像@Esailija演示的Worker。
如果你有一个更复杂的应用程序,可以很好地利用工人,你不会真的产卵他们对mousedown和终止他们。相反,您可以为单一类型的工具示例化单个Workers,并向它们触发开始处理和结束处理事件。

bvjxkvbb

bvjxkvbb3#

在web worker中绘制SVG并将其传递给其父对象并将SVG附加到DOM是可能的。

示例

/**
 * Web Worker
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */
var workerURL = URL.createObjectURL(new Blob(['(',
  function() {
    onmessage = function( event ) {
      if (event.data === 'generateSVG') {
        // Generate the SVG content
        const svgContent = '<svg width="200" height="200"><circle cx="100" cy="100" r="50" fill="red" /></svg>';
        // Send the SVG content back to the parent page
        postMessage(svgContent);
      }
    };
  }.toString(), ')()' ], { type: 'application/javascript' }));

/**
 * Main Script
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */
// Init Worker
worker = new Worker( workerURL );

// Listen for Worker
worker.addEventListener('message', function(event) {
  if(event.data !== undefined) {
    console.log( 'Worker Response: ', event.data );
  }
}, false);

// Listen for messages from the web worker
worker.onmessage = function (event) {
  const svgData = event.data;
  // Display the SVG in the HTML page
  document.getElementById('svg-container').innerHTML = svgData;
};

// Start the web worker
worker.postMessage('generateSVG');
<html>
  <body>
    <div id="svg-container"></div>
  </body>
</html>

相关问题