9
\$\begingroup\$

I wrote my Sierpinski Triangle fractal animation using HTML canvas with JavaScript: JsFiddle

What do you think about it? How I can optimize it, if you see a need for that?

Code:

requestAnimationFrame(update);
 
const canvas = document.getElementById("c");
const context = canvas.getContext('2d');
var iterations = 0; //how many iterations to perform in current frame, count of fractal func invokes grows exponentially and can be calculated from sum: E 3^k, k = 0 to iterations
const maxIterations = 8; //used when animating, it's better to set 'gradientAnimation' to false, when setting 'maxIterations' to bigger values 
const center = { x: canvas.width * 0.5, y: canvas.height * 0.5 };
const halfTriangleSide = 250;
//color animation
const gradientAnimation = true;
var t = 0;
var speed = 0.1;
//division animation
var divideAnim = true;
var divide = true; //loop flag
var mod = 0.0; //color modificator
function drawTriangle(A, B, C)
{
 context.beginPath();
 context.moveTo(A.x, A.y);
 context.lineTo(B.x, B.y);
 context.lineTo(C.x, C.y);
 context.lineTo(A.x, A.y);
 if(gradientAnimation)
 {
 context.fillStyle = 
 "rgb(" + 
 ((A.x + A.y) * 0.19 * mod) + "," + 
 ((B.x + B.y) * 0.15 * mod) + "," + 
 ((C.x + C.y) * 0.22 * mod) + 
 ")";
 }
 
 context.fill();
}
function fractal(center, halfSideLen, i)
{
 i++;
 var quaterSide = halfSideLen * 0.5;
 
 //calc new triangle coords
 var A = { 
 x: center.x - quaterSide, 
 y: center.y
 };
 
 var B = {
 x: center.x + quaterSide, 
 y: center.y
 };
 
 var C = {
 x: center.x, 
 y: center.y + halfSideLen 
 };
 
 drawTriangle(A, B, C);
 if(i < iterations)
 { 
 fractal({x: A.x, y: A.y + quaterSide}, quaterSide, i);
 fractal({x: B.x, y: B.y + quaterSide}, quaterSide, i);
 fractal({x: C.x, y: C.y - (halfSideLen + quaterSide)}, quaterSide, i);
 }
}
function update()
{
 context.clearRect(0, 0, canvas.width, canvas.height);
 
 //init coords
 var A = { 
 x: center.x - halfTriangleSide, 
 y: center.y + halfTriangleSide
 };
 
 var B = {
 x: center.x + halfTriangleSide, 
 y: center.y + halfTriangleSide
 };
 
 var C = {
 x: center.x, 
 y: center.y - halfTriangleSide 
 };
 
 context.fillStyle = "#F00";
 drawTriangle(A, B, C); 
 context.fillStyle = "#000";
 
 if(iterations != 0) fractal(center, halfTriangleSide, 0); 
 
 t += speed;
 if(t > Math.PI * 2)
 { 
 t = 0;
 
 if(divideAnim)
 {
 if(iterations == maxIterations) divide = false;
 else if(iterations == 0) divide = true;
 
 if(divide) iterations++;
 else iterations--;
 }
 }
 
 if(gradientAnimation)
 {
 mod = 1.25 - Math.sin(t) * 0.5;
 }
 
 requestAnimationFrame(update);
}
Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
asked Jul 27, 2018 at 19:55
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Good things:

  • const is used for variables that shouldn't be re-assigned
  • requestAnimationFrame() is used for animating
  • constants and global variables are declared at the top of the script.
  • only three functions are used

Suggestions

  • add a space after control structures like if for readability: this is recommended in many style guides (e.g. AirBnB, Google)
    Instead of

    if(gradientAnimation)
    

    Add a space:

    if (gradientAnimation)
    
  • Also recommended by some popular style guides: avoid var unless a global variable is needed. Default to using const to avoid accidental re-assignment (which seems to be a topic of this discussion on your other JS post). If re-assignment is needed then use let.

  • Use equality operators that don’t coerce types when not needed:

    Instead of:

    if(iterations == maxIterations)
    

    Use ===

     if (iterations === maxIterations)
    
  • A common convention in many languages (including C-based and others) is to have constants that truly never change named using ALL_CAPS - e.g. MAX_ITERATIONS instead of maxIterations, HALF_TRIANGLE_SIDE instead of halfTriangleSide, etc.

  • the lone i++ at the start of fractal() can be moved down to conditional after the call to drawTriangle() and converted to a pre-increment:

     if (++i < iterations)
    
  • Most of the (idiomatic) JS code and JS Style guides I have seen have opening braces on the same line as the function signature or control structure instead of a new line. Perhaps having them on a new line is common in another style guide (e.g. C++, C#, etc.).

answered Jul 8, 2020 at 19:13
\$\endgroup\$
2
  • \$\begingroup\$ In C# brackets starting blocks are always in a new line, maybe that's where it's coming from. \$\endgroup\$ Commented Jul 9, 2020 at 13:50
  • \$\begingroup\$ @potato- thanks for the insight - I have taken it into account as I updated that section \$\endgroup\$ Commented Jul 9, 2020 at 15:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.