gpt4 book ai didi

javascript - Web Worker 和 Canvas 数据

转载 作者:行者123 更新时间:2023-11-28 19:53:12 26 4
gpt4 key购买 nike

我看过很多关于网络 worker 的帖子和 <canvas>数据传递,我不确定我的场景是否可以实现。

我想创建一个小网站,供用户学习用 Javascript 编码。当用户单击按钮时,代码将在 Web Worker 中运行。为了帮助他们,我还创建了“打印”方法(基本上只是将文本添加到 <pre> 元素中。

// get code from user and prepend helper "functions"
var userCode = editor.getValue();
var codeWithMessages = "\n\
function print(data) { postMessage(\"\"+data); } \n\
function println(data) { postMessage(\"\"+data+\'\\n\'); } \n\
function alert(data) { postMessage('ALERT'+data); } \n\
\n" + userCode;
var codeWithMessagesAndExit = codeWithMessages + "\npostMessage('exit()');";
var blob = new Blob([codeWithMessagesAndExit], {type: 'application/javascript'});
// Obtain a blob URL reference to our worker 'file'.
var blobURL = window.URL.createObjectURL(blob);
outer.worker = new Worker(blobURL);

...
// handle messages by "printing" to the run-output element, or display
// a success message when finishing
outer.worker.addEventListener('message', function (event) {

if (event.data == "exit()") {
outer.worker.terminate();
outer.worker = null;

outer.codeRunStatus = outer.CODE_RUN_SUCCESS;
outer.errorMessage = null;
outer.outputFromLatestRun = $("#run-output").text();
$("#run-output").append("<span class='code-run-success'>\nKörning klar</span>");
enableButtons();
}
else if (event.data.indexOf("ALERT") == 0) {
alert(event.data.substring(5));
}
else {
$("#run-output").append(event.data);
}
}, false);
// start the worker
outer.worker.postMessage();

现在我想向页面添加 Canvas ,以便用户可以编写代码在其上绘图。

var canvas = document.getElementById("user-canvas");
var ctx = canvas.getContext("2d");
var imgData = ctx.getImageData(0,0,canvas.width,canvas.height);
// rest same as above
outer.worker.postMessage(imgData);

我不知道如何从这里继续。理想情况下,用户可以编写类似的内容

myCanvas.fillStyle = "rgb(200,0,0)";
myCanvas.fillRect (10, 10, 55, 50);

然后让事件监听器处理它,就像我对 print() 所做的那样功能。这可能吗?

最佳答案

无法从 WebWorker 访问 DOM。

我能看到的最好的方法是在 webworker 中重新定义这个对象,并定义一个协议(protocol)来传输每个方法的调用。但当您需要图像等其他对象时,它就不起作用了。

工作端:

var CanvasRenderingContext2D = function() {
this.fillStyle = "black";
this.strokeStyle = "black";
...
this.lineWidth = 1.0;
};

["fillRect", "strokeRect", "beginPath", ... "rotate", "stroke"].forEach(function(methodName) {
CanvasRenderingContext2D.prototype[methodName] = function() {
postMessage({called: methodName, args: arguments, currentObjectAttributes: this});
};
});

...

var myCanvas = new CanvasRenderingContext2D();
myCanvas.fillStyle = "rgb(200,0,0)";
myCanvas.fillRect(10, 10, 55, 50);

主页面:

var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
var worker = new Worker( ... );
worker.onMessage = function(event) {
var data = event.data;

// Refreshing context attributes
var attributes = data.currentObjectAttributes;
for(var k in attributes) {
context[k] = attributes[k];
}

// Calling method
var method = context[data.called];
method.apply(context, data.args);
};

编辑:

我尝试将它与您的代码集成(未测试)。为了集成它,我必须更改工作人员发送的消息的结构。

// get code from user and prepend helper "functions"
var userCode = editor.getValue();
var codeWithMessages = '\n\
function print (data) { postMessage(["print", data.toString()]); } \n\
function println(data) { postMessage(["print", data.toString() + "\\n"]); } \n\
function alert (data) { postMessage(["alert", data.toString()]); } \n\
var CanvasRenderingContext2D = function() { \n\
this.fillStyle = "black"; \n\
this.strokeStyle = "black"; \n\
/* ... */ \n\
this.lineWidth = 1.0; \n\
}; \n\
["fillRect", "strokeRect", "beginPath", /* ... */ "rotate", "stroke"].forEach(function(methodName) { \n\
CanvasRenderingContext2D.prototype[methodName] = function() { \n\
postMessage(["canvas", {called: methodName, args: Array.prototype.slice.call(arguments), currentObjectAttributes: this}]); \n\
}; \n\
});\n' + userCode;
var codeWithMessagesAndExit = codeWithMessages + "\npostMessage(['exit']);";
var blob = new Blob([codeWithMessagesAndExit], {type: 'application/javascript'});
// Obtain a blob URL reference to our worker 'file'.
var blobURL = window.URL.createObjectURL(blob);
outer.worker = new Worker(blobURL);

...

// Define your canvas ...
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");

// handle messages by "printing" to the run-output element, or display
// a success message when finishing
outer.worker.addEventListener('message', function (event) {
var method = event.data[0] || null;
var data = event.data[1] || null;

if(method == "canvas") {
// Refreshing context attributes
var attributes = data.currentObjectAttributes;
for(var k in attributes) {
context[k] = attributes[k];
}

// Calling method
var method = context[data.called];
method.apply(context, data.args);
} else if(method == "exit") {
outer.worker.terminate();
outer.worker = null;

outer.codeRunStatus = outer.CODE_RUN_SUCCESS;
outer.errorMessage = null;
outer.outputFromLatestRun = $("#run-output").text();
$("#run-output").append("<span class='code-run-success'>\nKörning klar</span>");
enableButtons();
} else if(method == "alert") {
alert(data);
} else if(method == "print") {
$("#run-output").append(data);
} else {
$("#run-output").append(event.data);
}
}, false);
// start the worker
outer.worker.postMessage();

关于javascript - Web Worker 和 Canvas 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23083313/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com