无法在paper.js中将`Symbol`用于`Group`。

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

Unable to use a `Symbol` for a `Group` with paper.js

问题

I have translated the code for you as requested. Here is the translated code:

<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.2/paper-full.min.js"></script>
    <style>
      canvas {
        width: 400px;
        height: 400px;
        border: black 3px solid;
      }
    </style>
  </head>
  <body>
    <script>
      function subm_index(M, x){
        if (x<0)
          return x+M;
        if(x >= M)
          return x-M;
        return x;
      }
      function update_concentrations(X, L, DA, DB, f, k){ 
        var sum_a, sum_b, x1, y1, t;
        var m = X.A.length;
        var n = X.A[0].length;
        var A = new Array(m);
        var B = new Array(m);
        for(var i = 0; i < m; i++){
          A[i] = new Array(n);
          B[i] = new Array(n);
        }        
        for(var x = 0; x < m; x++) {
          for(var y = 0; y < n; y++){
            sum_a = 0.0;
            sum_b = 0.0;
            for(var i = -1; i <= 1; i++){
              for(var j = -1; j <= 1; j++){
                x1 = subm_index(m, x - i);
                y1 = subm_index(n, y - j);
                sum_a = sum_a + L[i+1][j+1] * X.A[x1][y1];
                sum_b = sum_b + L[i+1][j+1] * X.B[x1][y1];
              }
            }
            t = X.A[x][y]*X.B[x][y]*X.B[x][y];
            A[x][y] = X.A[x][y] + DA*sum_a - t + f*(1-X.A[x][y]);
            B[x][y] = X.B[x][y] + DB*sum_b + t - (k+f)*X.B[x][y];
          }
        }
        return {A: A, B: B};
      }
      function iterate_Gray_Scott(X, L, DA, DB, f, k, n){
        for(var i = 0; i < n; i++){
          X = update_concentrations(X, L, DA, DB, f, k); 
        }
        return X;
      }
      var L = [[0.05, 0.2, 0.05], [0.2, -1, 0.2], [0.05, 0.2, 0.05]];
      var DA = 1;
      var DB = 0.5;
      var f = 0.0545;
      var k = 0.062;
    </script>

    <script type="text/paperscript" canvas="quad">
      var pixels = 50;
      var gridSize = 2;
      var rectSize = 2;
      var A = new Array(pixels);
      var B = new Array(pixels);
      var Paths = new Array(pixels);
      for(var i = 0; i < pixels; i++){
        A[i] = new Array(pixels);
        B[i] = new Array(pixels);
        Paths[i] = new Array(pixels);
        for(var j = 0; j < pixels; j++){
          A[i][j] = 1;
          B[i][j] = Math.random() < 0.99 ? 0 : 1;
        }
      }
      var X = {A: A, B: B};

      var nframes = 50;

      var XX = new Array(nframes);
      XX[0] = X;
      for(var frm = 1; frm < nframes; frm++){
        XX[frm] = iterate_Gray_Scott(XX[frm-1], L, DA, DB, f, k, frm);
      }
      
      var Rects = [];
      for(var x = 0; x < pixels; x++){
        for(var y = 0; y < pixels; y++){
          var rect = new Path.Rectangle(new Point(x, y) * gridSize, new Size(rectSize, rectSize));
          var color = {
            hue: 1,
            saturation: 1,
            brightness: 1
          };
          rect.fillColor = color;
          rect.visible = false;
          Rects.push(rect);
        }
      }

      group = new Group(Rects);

      symbolGroup = new Symbol(group);

      var Groups = new Array(nframes);
      for(var frm = 0; frm < nframes; frm++){
        Groups[frm] = symbolGroup.place(view.center);
        var k = 0;
        for(var x = 0; x < pixels; x++){
          for(var y = 0; y < pixels; y++){
            Groups[frm].definition.definition.children[k].fillColor = {
              hue: XX[frm].B[x][y] * 360,
              saturation: 1,
              brightness: 1
            };
            k = k+1;
          }
        } 
        XX[frm] = null; // to free some memory
      } 

      project.activeLayer.position = view.center;

      function onFrame(event){
        if(event.count < nframes){
          console.log(event.count);
          Groups[event.count].visible = true;
          if(event.count > 0){
            Groups[event.count-1].visible = false; // to free some memory
          }
        }
      }
    </script>

    <canvas id="quad" resize></canvas>
  </body>
</html>

Please note that this is a direct translation of your code, and any issues or bugs in the original code will be present in this translation as well. If you encounter any issues or need further assistance with this code, please let me know.

英文:

I want to do an animation of a reaction-diffusion system with paper.js.

Here is a code which generates just one image:

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

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

&lt;html&gt;
&lt;head&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.2/paper-full.min.js&quot;&gt;&lt;/script&gt;
&lt;style&gt;
canvas {
width: 400px;
height: 400px;
border: black 3px solid;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script&gt;
function subm_index(M, x){
if (x&lt;0)
return x+M;
if(x &gt;= M)
return x-M;
return x;
}
function update_concentrations(X, L, DA, DB, f, k){ 
var sum_a, sum_b, x1, y1, t;
var m = X.A.length;
var n = X.A[0].length;
var A = new Array(m);
var B = new Array(m);
for(var i = 0; i &lt; m; i++){
A[i] = new Array(n);
B[i] = new Array(n);
}        
for(var x = 0; x &lt; m; x++) {
for(var y = 0; y &lt; n; y++){
sum_a = 0.0;
sum_b = 0.0;
for(var i = -1; i &lt;= 1; i++){
for(var j = -1; j &lt;= 1; j++){
x1 = subm_index(m, x - i);
y1 = subm_index(n, y - j);
sum_a = sum_a + L[i+1][j+1] * X.A[x1][y1];
sum_b = sum_b + L[i+1][j+1] * X.B[x1][y1];
}
}
t = X.A[x][y]*X.B[x][y]*X.B[x][y];
A[x][y] = X.A[x][y] + DA*sum_a - t + f*(1-X.A[x][y]);
B[x][y] = X.B[x][y] + DB*sum_b + t - (k+f)*X.B[x][y];
}
}
return {A: A, B: B};
}
function iterate_Gray_Scott(X, L, DA, DB, f, k, n){
for(var i = 0; i &lt; n; i++){
X = update_concentrations(X, L, DA, DB, f, k); 
}
return X;
}
var L = [[0.05, 0.2, 0.05], [0.2, -1, 0.2], [0.05, 0.2, 0.05]];
var DA = 1;
var DB = 0.5;
var f = 0.0545;
var k = 0.062;
&lt;/script&gt;
&lt;script type=&quot;text/paperscript&quot; canvas=&quot;quad&quot;&gt;
var pixels = 200;
var gridSize = 2;
var rectSize = 2;
var A = new Array(pixels);
var B = new Array(pixels);
for(var i = 0; i &lt; pixels; i++){
A[i] = new Array(pixels);
B[i] = new Array(pixels);
for(var j = 0; j &lt; pixels; j++){
A[i][j] = 1;
B[i][j] = Math.random() &lt; 0.98 ? 0 : 1;
}
}
var X = {A: A, B: B};
X = iterate_Gray_Scott(X, L, DA, DB, f, k, 1000);
for(var y = 0; y &lt; pixels; y++){
for(var x = 0; x &lt; pixels; x++){
var color = {
hue: X.B[x][y] * 360,
saturation: 1,
brightness: 1
};
var path = new Path.Rectangle(new Point(x, y) * gridSize, new Size(rectSize, rectSize));
path.fillColor = color;
}
}
project.activeLayer.position = view.center;
&lt;/script&gt;
&lt;canvas id=&quot;quad&quot; resize&gt;&lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

Now, here is a code which generates the animation:

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

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

&lt;html&gt;
&lt;head&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.2/paper-full.min.js&quot;&gt;&lt;/script&gt;
&lt;style&gt;
canvas {
width: 400px;
height: 400px;
border: black 3px solid;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script&gt;
function subm_index(M, x){
if (x&lt;0)
return x+M;
if(x &gt;= M)
return x-M;
return x;
}
function update_concentrations(X, L, DA, DB, f, k){ 
var sum_a, sum_b, x1, y1, t;
var m = X.A.length;
var n = X.A[0].length;
var A = new Array(m);
var B = new Array(m);
for(var i = 0; i &lt; m; i++){
A[i] = new Array(n);
B[i] = new Array(n);
}        
for(var x = 0; x &lt; m; x++) {
for(var y = 0; y &lt; n; y++){
sum_a = 0.0;
sum_b = 0.0;
for(var i = -1; i &lt;= 1; i++){
for(var j = -1; j &lt;= 1; j++){
x1 = subm_index(m, x - i);
y1 = subm_index(n, y - j);
sum_a = sum_a + L[i+1][j+1] * X.A[x1][y1];
sum_b = sum_b + L[i+1][j+1] * X.B[x1][y1];
}
}
t = X.A[x][y]*X.B[x][y]*X.B[x][y];
A[x][y] = X.A[x][y] + DA*sum_a - t + f*(1-X.A[x][y]);
B[x][y] = X.B[x][y] + DB*sum_b + t - (k+f)*X.B[x][y];
}
}
return {A: A, B: B};
}
function iterate_Gray_Scott(X, L, DA, DB, f, k, n){
for(var i = 0; i &lt; n; i++){
X = update_concentrations(X, L, DA, DB, f, k); 
}
return X;
}
var L = [[0.05, 0.2, 0.05], [0.2, -1, 0.2], [0.05, 0.2, 0.05]];
var DA = 1;
var DB = 0.5;
var f = 0.0545;
var k = 0.062;
&lt;/script&gt;
&lt;script type=&quot;text/paperscript&quot; canvas=&quot;quad&quot;&gt;
var pixels = 200;
var gridSize = 2;
var rectSize = 2;
var A = new Array(pixels);
var B = new Array(pixels);
var Paths = new Array(pixels);
for(var i = 0; i &lt; pixels; i++){
A[i] = new Array(pixels);
B[i] = new Array(pixels);
Paths[i] = new Array(pixels);
for(var j = 0; j &lt; pixels; j++){
A[i][j] = 1;
B[i][j] = Math.random() &lt; 0.99 ? 0 : 1;
}
}
var X = {A: A, B: B};
for(var y = 0; y &lt; pixels; y++){
for(var x = 0; x &lt; pixels; x++){
var color = {
hue: X.B[x][y] * 360,
saturation: 1,
brightness: 1
};
Paths[x][y] = new Path.Rectangle(new Point(x, y) * gridSize, new Size(rectSize, rectSize));
Paths[x][y].fillColor = color;
}
}
var nframes = 100;
var XX = new Array(nframes);
XX[0] = X;
for(var frm = 1; frm &lt; nframes; frm++){
XX[frm] = iterate_Gray_Scott(XX[frm-1], L, DA, DB, f, k, frm);
}
project.activeLayer.position = view.center;
function onFrame(event){
console.log(event.count);
if(event.count &lt; nframes){
for(var y = 0; y &lt; pixels; y++){
for(var x = 0; x &lt; pixels; x++){
var color = {
hue: XX[event.count].B[x][y] * 360,
saturation: 1,
brightness: 1
};
Paths[x][y].fillColor = color;
}
}
}
}
&lt;/script&gt;
&lt;canvas id=&quot;quad&quot; resize&gt;&lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

It works but the animation is not fluid enough. This is due to the double loop in onFrame, which consumes some time.

So I firstly tried to create an array containing nframes Group elements, each group containing pixels*pixels Rectangle elements. But this generated an out-of-memory.

So I tried to use a Symbol to save some memory. The code is below but it does not work, there is not a single image appearing.

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

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

&lt;html&gt;
&lt;head&gt;
&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.2/paper-full.min.js&quot;&gt;&lt;/script&gt;
&lt;style&gt;
canvas {
width: 400px;
height: 400px;
border: black 3px solid;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script&gt;
function subm_index(M, x){
if (x&lt;0)
return x+M;
if(x &gt;= M)
return x-M;
return x;
}
function update_concentrations(X, L, DA, DB, f, k){ 
var sum_a, sum_b, x1, y1, t;
var m = X.A.length;
var n = X.A[0].length;
var A = new Array(m);
var B = new Array(m);
for(var i = 0; i &lt; m; i++){
A[i] = new Array(n);
B[i] = new Array(n);
}        
for(var x = 0; x &lt; m; x++) {
for(var y = 0; y &lt; n; y++){
sum_a = 0.0;
sum_b = 0.0;
for(var i = -1; i &lt;= 1; i++){
for(var j = -1; j &lt;= 1; j++){
x1 = subm_index(m, x - i);
y1 = subm_index(n, y - j);
sum_a = sum_a + L[i+1][j+1] * X.A[x1][y1];
sum_b = sum_b + L[i+1][j+1] * X.B[x1][y1];
}
}
t = X.A[x][y]*X.B[x][y]*X.B[x][y];
A[x][y] = X.A[x][y] + DA*sum_a - t + f*(1-X.A[x][y]);
B[x][y] = X.B[x][y] + DB*sum_b + t - (k+f)*X.B[x][y];
}
}
return {A: A, B: B};
}
function iterate_Gray_Scott(X, L, DA, DB, f, k, n){
for(var i = 0; i &lt; n; i++){
X = update_concentrations(X, L, DA, DB, f, k); 
}
return X;
}
var L = [[0.05, 0.2, 0.05], [0.2, -1, 0.2], [0.05, 0.2, 0.05]];
var DA = 1;
var DB = 0.5;
var f = 0.0545;
var k = 0.062;
&lt;/script&gt;
&lt;script type=&quot;text/paperscript&quot; canvas=&quot;quad&quot;&gt;
var pixels = 50;
var gridSize = 2;
var rectSize = 2;
var A = new Array(pixels);
var B = new Array(pixels);
var Paths = new Array(pixels);
for(var i = 0; i &lt; pixels; i++){
A[i] = new Array(pixels);
B[i] = new Array(pixels);
Paths[i] = new Array(pixels);
for(var j = 0; j &lt; pixels; j++){
A[i][j] = 1;
B[i][j] = Math.random() &lt; 0.99 ? 0 : 1;
}
}
var X = {A: A, B: B};
var nframes = 50;
var XX = new Array(nframes);
XX[0] = X;
for(var frm = 1; frm &lt; nframes; frm++){
XX[frm] = iterate_Gray_Scott(XX[frm-1], L, DA, DB, f, k, frm);
}
var Rects = [];
for(var x = 0; x &lt; pixels; x++){
for(var y = 0; y &lt; pixels; y++){
var rect = new Path.Rectangle(new Point(x, y) * gridSize, new Size(rectSize, rectSize));
var color = {
hue: 1,
saturation: 1,
brightness: 1
};
rect.fillColor = color;
rect.visible = false;
Rects.push(rect);
}
}
group = new Group(Rects);
symbolGroup = new Symbol(group);
var Groups = new Array(nframes);
for(var frm = 0; frm &lt; nframes; frm++){
Groups[frm] = symbolGroup.place(view.center);
var k = 0;
for(var x = 0; x &lt; pixels; x++){
for(var y = 0; y &lt; pixels; y++){
Groups[frm].definition.definition.children[k].fillColor = {
hue: XX[frm].B[x][y] * 360,
saturation: 1,
brightness: 1
};
k = k+1;
}
} 
XX[frm] = null; // to free some memory
} 
project.activeLayer.position = view.center;
function onFrame(event){
if(event.count &lt; nframes){
console.log(event.count);
Groups[event.count].visible = true;
if(event.count &gt; 0){
Groups[event.count-1].visible = false; // to free some memory
}
}
}
&lt;/script&gt;
&lt;canvas id=&quot;quad&quot; resize&gt;&lt;/canvas&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

Can you help me to fix this last code?

答案1

得分: 2

在这段文本中,以下是已翻译的部分:

"Syntactically, I think there's a small issue here:"(从句法角度来看,我认为这里有一个小问题:)

"Groups[frm].definition.definition.children[k].fillColor"(Groups[frm].definition.definition.children[k].fillColor)

"changing fill color of Rect"(更改矩形的填充颜色)

"accessing children of group"(访问组的子元素)

"should be item*"(应该是item*)

"SymbolDefinition"(SymbolDefinition)

"array of placed symbols"(放置的符号数组)

"* [SymbolDefinition.item] http://paperjs.org/reference/symboldefinition/"(* [SymbolDefinition.item] http://paperjs.org/reference/symboldefinition/

"But I wouldn't spend a lot of time trying to get Symbols to render anyway."(但我不会花太多时间尝试渲染符号。)

"Reading about Symbols, it seems that making changes to the definition of a SymbolDefinition will update all placed instances as they point to a common source."(阅读有关符号的信息,似乎对SymbolDefinition的定义进行更改会更新所有已放置的实例,因为它们指向共同的源。)

"As a technique to speed up your operations I think this will backfire."(作为加速操作的技巧,我认为这将适得其反。)

"You are still making the same number of fill operations as you were with the 2D array."(你仍然执行与2D数组相同数量的填充操作。)

"An alternative approach is to use a sort of pseudo double-buffering. Do your fill operations on a set of rectangles that are not on screen, then cache that group to bitmap and display that."(另一种方法是使用一种伪双缓冲方法。在屏幕外的一组矩形上执行填充操作,然后将该组缓存为位图并显示。)

"Each refresh will avoid unnecessary draw operations and will happen as a unit. Caching as bitmap will speed up the pixel rendering as well."(每次刷新都会避免不必要的绘制操作,并作为一个单位进行。将其缓存为位图也会加速像素渲染。)

"Paper.js doesn't seem to give you an obvious way to implement this, but you could probably use 2 layers to accomplish it."(Paper.js似乎没有提供明显的实现方法,但你可能可以使用两个图层来完成。)

"Since only 1 layer will be 'active' at a time, you could draw your rectangles on one, cache it as bitmap, then activate. Then draw the next set of rectangles on the 2nd layer, cache it as bitmap, and activate."(因为一次只有一个图层会处于“活动”状态,你可以在一个图层上绘制矩形,将其缓存为位图,然后激活。然后在第二个图层上绘制下一组矩形,将其缓存为位图,然后激活。)

"Toggling back and forth might get you the performance enhancement you need."(来回切换可能会帮助你获得所需的性能提升。)

"Alternatively, there's a thing called PaperScope which you might be able to leverage for the same technique."(或者,还有一种叫做PaperScope的东西,你可能可以利用它来实现相同的技术。)

"PaperScope uses a second canvas element. You'll need to manually activate them as you toggle in the same way as layers."(PaperScope使用第二个画布元素。你需要像在图层中切换一样手动激活它们。)

1: http://paperjs.org/reference/paperscope/1: http://paperjs.org/reference/paperscope/

英文:

Syntactically, I think there's a small issue here:

Groups[frm].definition.definition.children[k].fillColor
|           |          |          |           ^ changing fill color of Rect
|           |          |          ^ accessing children of group
|           |          ^ should be item*
|           ^ SymbolDefinition
^ array of placed symbols

* [SymbolDefinition.item] http://paperjs.org/reference/symboldefinition/

But I wouldn't spend a lot of time trying to get Symbols to render anyway.

Reading about Symbols, it seems that making changes to the definition of a SymbolDefinition will update all placed instances as they point to a common source. As a technique to speed up your operations I think this will backfire. You are still making the same number of fill operations as you were with the 2D array.

An alternative approach is to use a sort of pseudo double-buffering. Do your fill operations on a set of rectangles that are not on screen, then cache that group to bitmap and display that. Each refresh will avoid unnecessary draw operations and will happen as a unit. Caching as bitmap will speed up the pixel rendering as well.

Paper.js doesn't seem to give you an obvious way to implement this, but you could probably use 2 layers to accomplish it. Since only 1 layer will be "active" at a time, you could draw your rectangles on one, cache it as bitmap, then activate. Then draw the next set of rectangles on the 2nd layer, cache it as bitmap, and activate. Toggling back and forth might get you the performance enhancement you need.

Alternatively, there's a thing called PaperScope which you might be able to leverage for the same technique. PaperScope uses a second canvas element. You'll need to manually activate them as you toggle in the same way as layers.

答案2

得分: 2

以下是翻译好的部分:

如果你追求性能,我认为在这种情况下,你应该摆脱Paper.js,因为它会给渲染部分增加额外的开销。
作为替代,你可以直接使用Canvas API来渲染你的绘图。
以下是一个基于你的代码的快速示例,展示了如何使用它。

<!DOCTYPE html>
<html>
<head>
    <style>
        canvas {
            width: 400px;
            height: 400px;
        }
    </style>
</head>
<body>
<canvas></canvas>

<script>
    // 代码部分请参考原文
</script>

</body>
</html>

另一个改进的想法可能是将当前的数据源映射到一组准备好的ImageData数组,然后在Canvas中加载它们,而不是遍历像素。

英文:

If you are aiming for performance, I that that in this case, you should get rid of Paper.js which adds an overhead to the rendering part.
As a replacement, you can directly work with the Canvas API to render your drawing.
Here is a quick example, based on your code, showing how you could use it.

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

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

&lt;html&gt;
&lt;head&gt;
&lt;style&gt;
canvas {
width  : 400px;
height : 400px;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;canvas&gt;&lt;/canvas&gt;
&lt;script&gt;
function subm_index(M, x) {
if (x &lt; 0) {
return x + M;
}
if (x &gt;= M) {
return x - M;
}
return x;
}
function update_concentrations(X, L, DA, DB, f, k) {
var sum_a, sum_b, x1, y1, t;
var m = X.A.length;
var n = X.A[0].length;
var A = new Array(m);
var B = new Array(m);
for (var i = 0; i &lt; m; i++) {
A[i] = new Array(n);
B[i] = new Array(n);
}
for (var x = 0; x &lt; m; x++) {
for (var y = 0; y &lt; n; y++) {
sum_a = 0.0;
sum_b = 0.0;
for (var i = -1; i &lt;= 1; i++) {
for (var j = -1; j &lt;= 1; j++) {
x1 = subm_index(m, x - i);
y1 = subm_index(n, y - j);
sum_a = sum_a + L[i + 1][j + 1] * X.A[x1][y1];
sum_b = sum_b + L[i + 1][j + 1] * X.B[x1][y1];
}
}
t = X.A[x][y] * X.B[x][y] * X.B[x][y];
A[x][y] = X.A[x][y] + DA * sum_a - t + f * (1 - X.A[x][y]);
B[x][y] = X.B[x][y] + DB * sum_b + t - (k + f) * X.B[x][y];
}
}
return { A: A, B: B };
}
function iterate_Gray_Scott(X, L, DA, DB, f, k, n) {
for (var i = 0; i &lt; n; i++) {
X = update_concentrations(X, L, DA, DB, f, k);
}
return X;
}
var L = [[0.05, 0.2, 0.05], [0.2, -1, 0.2], [0.05, 0.2, 0.05]];
var DA = 1;
var DB = 0.5;
var f = 0.0545;
var k = 0.062;
var pixels = 200;
var gridSize = 2;
var rectSize = 2;
var A = new Array(pixels);
var B = new Array(pixels);
var Paths = new Array(pixels);
for (var i = 0; i &lt; pixels; i++) {
A[i] = new Array(pixels);
B[i] = new Array(pixels);
Paths[i] = new Array(pixels);
for (var j = 0; j &lt; pixels; j++) {
A[i][j] = 1;
B[i][j] = Math.random() &lt; 0.99 ? 0 : 1;
}
}
var X = { A: A, B: B };
var nframes = 50;
var XX = new Array(nframes);
XX[0] = X;
for (var frm = 1; frm &lt; nframes; frm++) {
XX[frm] = iterate_Gray_Scott(XX[frm - 1], L, DA, DB, f, k, frm);
}
//
// New code
//
// Get a reference to the canvas element. 
const canvas = document.querySelector(&#39;canvas&#39;);
// Make sure that canvas internal size fits its display size. 
canvas.width = 400;
canvas.height = 400;
// Get canvas context to be able to draw directly on it. 
const ctx = canvas.getContext(&#39;2d&#39;);
// Counter used to swicth between frames.
let currentFrame = 0;
// Launch the animation.
animate();
function animate() {
// Draw current frame.
draw();
// Update frame counter (make it loop after last frame).
currentFrame = currentFrame &lt; nframes - 1 ? currentFrame + 1 : 0;
// Do a recursive call to render next frame.
requestAnimationFrame(animate);
}
function draw() {
// For each pixel...
for (var y = 0; y &lt; pixels; y++) {
for (var x = 0; x &lt; pixels; x++) {
// ...get the color...
const hue = Math.round(XX[currentFrame].B[x][y] * 360);
const color = `hsl(${hue}, 100%, 50%)`;
// ...use it as canvas fill color...
ctx.fillStyle = color;
// ...and draw a scaled rectangle.
ctx.fillRect(x * gridSize, y * gridSize, gridSize, gridSize);
}
}
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

Another improvement idea could be to map your current data source to an array of prepared ImageData that you will later load in the canvas rather than looping over the pixels.

huangapple
  • 本文由 发表于 2020年1月6日 16:49:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/59609072.html
匿名

发表评论

匿名网友

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

确定