Skip to content

Instantly share code, notes, and snippets.

@stepheneb
Last active April 6, 2023 21:03

Revisions

  1. stepheneb revised this gist Apr 6, 2023. No changes.
  2. stepheneb revised this gist Apr 6, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -3,4 +3,4 @@

    [This example](blocks.roadtolarissa.com/1299659) benchmarks the time taken to animate in Canvas with each frame consisting of a 5000 segment line.

    *source: [gist.github.com/gists/1299659](https://gist.github.com/gists/1299659)*
    *source: [gist.github.com/stepheneb/1299659](https://gist.github.com/stepheneb/1299659)*
  3. stepheneb revised this gist Apr 6, 2023. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    ### Canvas Animate Path Benchmark


    [This example](http://bl.ocks.org/1299659) benchmarks the time taken to animate in Canvas with each frame consisting of a 5000 segment line.
    [This example](blocks.roadtolarissa.com/1299659) benchmarks the time taken to animate in Canvas with each frame consisting of a 5000 segment line.

    *source: [gist.github.com/gists/1299659](https://gist.github.com/gists/1299659)*
  4. stepheneb revised this gist Jan 14, 2020. 1 changed file with 0 additions and 0 deletions.
    Binary file added thumbnail.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  5. stepheneb renamed this gist Jan 7, 2020. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. stepheneb revised this gist Oct 21, 2011. 1 changed file with 198 additions and 96 deletions.
    294 changes: 198 additions & 96 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,114 +1,216 @@
    <!DOCTYPE html>
    <html>
    <head>
    <title>Canvas over SVG Bug</title>
    <style type="text/css">
    #chart { width:500px; height:460px; background-color: #f7f2c5; position: relative }
    #description { margin: 0px 30px; width:600px }
    circle { stroke: #ff0000; stroke-width: 4px; fill: #ffffff; fill-opacity: 0.2 }
    ul.hlist { margin: 5px }
    ul.hlist li { margin: 5px; display: inline-table; vertical-align: top; list-style-type: none }
    fieldset { margin: 10px 40px 10px 20px}
    </style>
    <title>Canvas Animate Path Benchmark</title>
    <style type="text/css">
    body { margin: 0px 10px; }
    h1 { font-size: 1.3em; line-height: 1.0em; }
    table { font-size: 0.8em; margin: 0px 10px; padding: 2px }
    th { text-align: center; font-weight: bold; padding: 0px 10px 0px 10px; }
    td { text-align: center; font-weight: normal; padding: 0px 10px 0px 10px; }
    ul.hlist { display: inline-block; list-style-type: none; margin: 0px; padding-left: 15px; }
    ul.hlist li { display: inline-table; vertical-align: top; list-style-type: none }
    #canvas { width: 400px; height: 400px; padding:0px;
    background-color: #eeeeee; color:gray; border: solid 1px #cccccc }
    </style>
    <script type="text/javascript">
    window.requestAnimFrame = (function() {
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
    return window.setTimeout(callback, 1000/60);
    };
    })();
    window.cancelRequestAnimFrame = (function() {
    return window.cancelCancelRequestAnimationFrame ||
    window.webkitCancelRequestAnimationFrame ||
    window.mozCancelRequestAnimationFrame ||
    window.oCancelRequestAnimationFrame ||
    window.msCancelRequestAnimationFrame ||
    window.clearTimeout;
    })();
    </script>
    </head>
    <div id="container">
    <h1 id="title">Canvas over SVG Bug</h1>
    <body>
    <h1>Canvas Animate Path Benchmark</h1>
    <p>Measure performance of canvas line drawing speed by repeatedly re-drawing a 5000 element line.</p>
    <ul class="hlist">
    <li><canvas id="canvas"></canvas></li>
    <li>
    <div id='chart'>
    <svg width="480" height="440">
    <g transform="translate(40,20)">
    <rect width="400" height="400" style="fill: #eeeeee; " pointer-events="all"></rect>
    <circle cx="200" cy="200" r="100"></circle>
    </g>
    </svg>
    </div>
    </li>
    <li>
    <div id="description">
    <form id="animate-controller">
    <fieldset>
    <legend>Canvas Controller</legend>
    <label><button type="button" id="create-canvas">Create Canvas</button></label>
    <label><button type="button" id="draw-canvas">Draw Into Canvas</button></label>
    <legend>Step</legend>
    <label><input type="radio" name="step" value="stop" checked> Stop</input></label>
    <label><input type="radio" name="step" value="step"> Step</input></label>
    <label><input type="radio" name="step" value="go"> Go</input></label>
    <label><input type="radio" name="step" value="reset"> Reset</input></label>
    </fieldset>
    <p>
    This page exposed a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=695959">
    Canvas-related bug in FireFox</a>. Initially there is a gray SVG document with a
    red circle. After clicking the <b>Create Canvas</b> button a Canvas object is created
    with a red border and a translucent green background. This Canvas object is layered
    above the SVG object and inset by 15px. When you then click the <b>Braw Into Canvas</b>
    button a blue line is drawn into the Canvas.
    </p>
    <p>
    On FireFox 7.0.1 and FireFox Nightly and IE9 when the ctx.stroke() function is called
    to complete the line the background of the canvas is erased and becomes transparent.
    </p>
    <p>
    This only replicates part of the problem described here:
    <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=695959">Canvas-related bug in FireFox</a>.
    When starting the model in this page <a href="http://stepheneb.github.com/avalanche2d-js/avalanche2d.html">
    Avalanche-JS Demo</a> no lines are drawn in the graph on the right while the model is running.
    This is the time that the Canvas object is being draw into.
    </p>
    </div>
    </form>
    <p>frame: <span id="frame"></span></p>
    <p>framerate: <span id="framerate"></span></p>
    <p><i>Animation will stop automatically after 250 frames.</i></p>
    </li>
    </ul>
    </div>
    <script type="text/javascript">

    window.onload=function() {

    var plot, canvas, ctx;
    var chart = document.getElementById("chart");

    function createCanvas() {
    plot = {}
    plot.rect = chart.children[0].getElementsByTagName("rect")[0]
    plot.width = plot.rect.width['baseVal'].value
    plot.height = plot.rect.height['baseVal'].value
    plot.left = plot.rect.getCTM().e
    plot.top = plot.rect.getCTM().f
    canvas = document.createElement('canvas');
    chart.appendChild(canvas);
    canvas.style.position = 'absolute'
    canvas.width = plot.width - 40;
    canvas.height = plot.height - 40;
    canvas.style.left = plot.left + 20 + 'px'
    canvas.style.top = plot.top + 20 + 'px'
    ctx = canvas.getContext( '2d' );
    <p id="user-agent"></p>
    <script type="text/javascript">
    window.onload=function() {

    var user_agent = document.getElementById("user-agent");
    user_agent.innerHTML = navigator.userAgent;

    var canvas = document.getElementById("canvas");
    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;

    var animateRequest;

    var animate_controller = document.getElementById("animate-controller");
    var animate_controller_inputs = animate_controller.getElementsByTagName("input")

    var frame = document.getElementById("frame");
    var framerate = document.getElementById("framerate");

    var animating;

    var start_time, step_time;
    var loop_start, loop_time, loop_elapsed;

    var half_width = canvas.width / 2;
    var half_height = canvas.height / 2;

    var xpos = half_width;
    var ypos = half_height;
    var pos;

    var path = [];

    var ctx = canvas.getContext('2d');
    ctx.globalCompositeOperation = "destination-atop";
    ctx.lineWidth = 1;
    ctx.fillStyle = "rgba(0,255,0, 0.1)";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    canvas.style.border = 'solid 1px red'
    canvas.style.zIndex = 100
    };

    function drawInCanvas() {
    ctx.strokeStyle = "rgba(0,24,255, 1.0)";
    ctx.beginPath();
    ctx.moveTo(20, 180);
    ctx.lineTo(340, 180);
    ctx.closePath();
    ctx.stroke();
    };
    ctx.strokeStyle = "rgba(255,65,0, 1.0)";

    var create_canvas = document.getElementById("create-canvas");
    var draw_canvas = document.getElementById("draw-canvas");

    function createCanvasButton () {
    createCanvas();
    };
    var i, j;

    create_canvas.onclick = createCanvasButton;
    var factor = 15;
    var factor_div_2 = factor / 2;
    var correction = 0.002;

    function drawCanvasButton () {
    drawInCanvas();
    };
    var transform_factor = 5;
    var transform_factor_div_2 = transform_factor / 2;
    var transform_correction = 0.00035;

    var count, max_count;
    var run_mode;

    function init() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    count = 0;
    max_count = 250;
    xpos = half_width;
    ypos = half_height;
    path[0] = [xpos, ypos];
    for (i=1; i < 5000; i++) {
    xpos += (factor * Math.random() - factor_div_2) + (half_width - xpos) * correction;
    ypos += (factor * Math.random() - factor_div_2) + (half_height - ypos) * correction;
    path[i] = [xpos, ypos];
    };
    };

    function drawPath() {
    ctx.beginPath();
    pos = path[0];
    ctx.moveTo(pos[0], pos[1]);
    for (var i=1; i < 5000; i++) {
    pos = path[i];
    ctx.lineTo(pos[0], pos[1]);
    };
    ctx.closePath();
    ctx.stroke();
    };

    function transformPath() {
    for (i=1; i < 5000; i++) {
    path[i][0] += (transform_factor * Math.random() - transform_factor_div_2) + (half_width - xpos) * -correction;
    path[i][1] += (transform_factor * Math.random() - transform_factor_div_2) + (half_height - ypos) * -correction;
    };
    };

    draw_canvas.onclick = drawCanvasButton;

    };
    </script>
    function animateController() {
    for(var i = 0; i < this.elements.length; i++)
    if (this.elements[i].checked) run_mode = this.elements[i].value;
    switch(run_mode) {
    case "stop":
    animateStop();
    break;
    case "step":
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    if (count < max_count) runAnimateStep();
    animate_controller_inputs[0].checked = true;
    break;
    case "go":
    start_time = +new Date();
    animating = true;
    if (count >= max_count) {
    init();
    drawPath();
    animateRequest = requestAnimFrame(animateLoop, canvas);
    } else {
    animateRequest = requestAnimFrame(animateLoop, canvas);
    };
    break;
    case "reset":
    animateStop();
    init();
    drawPath();
    break;
    }
    };

    function animateStop() {
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    animate_controller_inputs[0].checked = true;
    };

    function runAnimateStep() {
    count++;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    transformPath();
    drawPath();
    frame.innerHTML = count;
    step_time = +new Date();
    framerate.innerHTML = ~~(10000 / ((step_time - start_time) / count)) / 10;
    // see: http://jsperf.com/rounding-numbers-down
    // I'm also rendering with one digit to the right of the decimal point
    };

    function animateLoop(){
    if (count < max_count && animating) {
    loop_start = +new Date();
    animateRequest = requestAnimFrame(animateLoop, canvas);
    runAnimateStep();
    loop_time = +new Date()
    loop_elapsed = loop_time - loop_start;
    while (loop_elapsed < 15) {
    runAnimateStep();
    loop_time = +new Date()
    loop_elapsed = loop_time - loop_start;
    }
    } else {
    animateStop()
    }
    };

    animate_controller.onchange = animateController;

    init();
    drawPath();

    };
    </script>
    </body>
    </html>
  7. stepheneb revised this gist Oct 21, 2011. 1 changed file with 96 additions and 198 deletions.
    294 changes: 96 additions & 198 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -1,216 +1,114 @@
    <!DOCTYPE html>
    <html>
    <head>
    <title>Canvas Animate Path Benchmark</title>
    <style type="text/css">
    body { margin: 0px 10px; }
    h1 { font-size: 1.3em; line-height: 1.0em; }
    table { font-size: 0.8em; margin: 0px 10px; padding: 2px }
    th { text-align: center; font-weight: bold; padding: 0px 10px 0px 10px; }
    td { text-align: center; font-weight: normal; padding: 0px 10px 0px 10px; }
    ul.hlist { display: inline-block; list-style-type: none; margin: 0px; padding-left: 15px; }
    ul.hlist li { display: inline-table; vertical-align: top; list-style-type: none }
    #canvas { width: 400px; height: 400px; padding:0px;
    background-color: #eeeeee; color:gray; border: solid 1px #cccccc }
    </style>
    <script type="text/javascript">
    window.requestAnimFrame = (function() {
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
    return window.setTimeout(callback, 1000/60);
    };
    })();
    window.cancelRequestAnimFrame = (function() {
    return window.cancelCancelRequestAnimationFrame ||
    window.webkitCancelRequestAnimationFrame ||
    window.mozCancelRequestAnimationFrame ||
    window.oCancelRequestAnimationFrame ||
    window.msCancelRequestAnimationFrame ||
    window.clearTimeout;
    })();
    </script>
    <title>Canvas over SVG Bug</title>
    <style type="text/css">
    #chart { width:500px; height:460px; background-color: #f7f2c5; position: relative }
    #description { margin: 0px 30px; width:600px }
    circle { stroke: #ff0000; stroke-width: 4px; fill: #ffffff; fill-opacity: 0.2 }
    ul.hlist { margin: 5px }
    ul.hlist li { margin: 5px; display: inline-table; vertical-align: top; list-style-type: none }
    fieldset { margin: 10px 40px 10px 20px}
    </style>
    </head>
    <body>
    <h1>Canvas Animate Path Benchmark</h1>
    <p>Measure performance of canvas line drawing speed by repeatedly re-drawing a 5000 element line.</p>
    <div id="container">
    <h1 id="title">Canvas over SVG Bug</h1>
    <ul class="hlist">
    <li><canvas id="canvas"></canvas></li>
    <li>
    <form id="animate-controller">
    <div id='chart'>
    <svg width="480" height="440">
    <g transform="translate(40,20)">
    <rect width="400" height="400" style="fill: #eeeeee; " pointer-events="all"></rect>
    <circle cx="200" cy="200" r="100"></circle>
    </g>
    </svg>
    </div>
    </li>
    <li>
    <div id="description">
    <fieldset>
    <legend>Step</legend>
    <label><input type="radio" name="step" value="stop" checked> Stop</input></label>
    <label><input type="radio" name="step" value="step"> Step</input></label>
    <label><input type="radio" name="step" value="go"> Go</input></label>
    <label><input type="radio" name="step" value="reset"> Reset</input></label>
    <legend>Canvas Controller</legend>
    <label><button type="button" id="create-canvas">Create Canvas</button></label>
    <label><button type="button" id="draw-canvas">Draw Into Canvas</button></label>
    </fieldset>
    </form>
    <p>frame: <span id="frame"></span></p>
    <p>framerate: <span id="framerate"></span></p>
    <p><i>Animation will stop automatically after 250 frames.</i></p>
    <p>
    This page exposed a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=695959">
    Canvas-related bug in FireFox</a>. Initially there is a gray SVG document with a
    red circle. After clicking the <b>Create Canvas</b> button a Canvas object is created
    with a red border and a translucent green background. This Canvas object is layered
    above the SVG object and inset by 15px. When you then click the <b>Braw Into Canvas</b>
    button a blue line is drawn into the Canvas.
    </p>
    <p>
    On FireFox 7.0.1 and FireFox Nightly and IE9 when the ctx.stroke() function is called
    to complete the line the background of the canvas is erased and becomes transparent.
    </p>
    <p>
    This only replicates part of the problem described here:
    <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=695959">Canvas-related bug in FireFox</a>.
    When starting the model in this page <a href="http://stepheneb.github.com/avalanche2d-js/avalanche2d.html">
    Avalanche-JS Demo</a> no lines are drawn in the graph on the right while the model is running.
    This is the time that the Canvas object is being draw into.
    </p>
    </div>
    </li>
    </ul>
    <p id="user-agent"></p>
    <script type="text/javascript">
    window.onload=function() {

    var user_agent = document.getElementById("user-agent");
    user_agent.innerHTML = navigator.userAgent;

    var canvas = document.getElementById("canvas");
    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;

    var animateRequest;

    var animate_controller = document.getElementById("animate-controller");
    var animate_controller_inputs = animate_controller.getElementsByTagName("input")

    var frame = document.getElementById("frame");
    var framerate = document.getElementById("framerate");

    var animating;

    var start_time, step_time;
    var loop_start, loop_time, loop_elapsed;

    var half_width = canvas.width / 2;
    var half_height = canvas.height / 2;

    var xpos = half_width;
    var ypos = half_height;
    var pos;

    var path = [];

    var ctx = canvas.getContext('2d');
    </div>
    <script type="text/javascript">

    window.onload=function() {

    var plot, canvas, ctx;
    var chart = document.getElementById("chart");

    function createCanvas() {
    plot = {}
    plot.rect = chart.children[0].getElementsByTagName("rect")[0]
    plot.width = plot.rect.width['baseVal'].value
    plot.height = plot.rect.height['baseVal'].value
    plot.left = plot.rect.getCTM().e
    plot.top = plot.rect.getCTM().f
    canvas = document.createElement('canvas');
    chart.appendChild(canvas);
    canvas.style.position = 'absolute'
    canvas.width = plot.width - 40;
    canvas.height = plot.height - 40;
    canvas.style.left = plot.left + 20 + 'px'
    canvas.style.top = plot.top + 20 + 'px'
    ctx = canvas.getContext( '2d' );
    ctx.globalCompositeOperation = "destination-atop";
    ctx.lineWidth = 1;
    ctx.strokeStyle = "rgba(255,65,0, 1.0)";

    var i, j;

    var factor = 15;
    var factor_div_2 = factor / 2;
    var correction = 0.002;

    var transform_factor = 5;
    var transform_factor_div_2 = transform_factor / 2;
    var transform_correction = 0.00035;

    var count, max_count;
    var run_mode;

    function init() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    count = 0;
    max_count = 250;
    xpos = half_width;
    ypos = half_height;
    path[0] = [xpos, ypos];
    for (i=1; i < 5000; i++) {
    xpos += (factor * Math.random() - factor_div_2) + (half_width - xpos) * correction;
    ypos += (factor * Math.random() - factor_div_2) + (half_height - ypos) * correction;
    path[i] = [xpos, ypos];
    };
    };

    function drawPath() {
    ctx.beginPath();
    pos = path[0];
    ctx.moveTo(pos[0], pos[1]);
    for (var i=1; i < 5000; i++) {
    pos = path[i];
    ctx.lineTo(pos[0], pos[1]);
    };
    ctx.closePath();
    ctx.stroke();
    };

    function transformPath() {
    for (i=1; i < 5000; i++) {
    path[i][0] += (transform_factor * Math.random() - transform_factor_div_2) + (half_width - xpos) * -correction;
    path[i][1] += (transform_factor * Math.random() - transform_factor_div_2) + (half_height - ypos) * -correction;
    };
    };

    function animateController() {
    for(var i = 0; i < this.elements.length; i++)
    if (this.elements[i].checked) run_mode = this.elements[i].value;
    switch(run_mode) {
    case "stop":
    animateStop();
    break;
    case "step":
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    if (count < max_count) runAnimateStep();
    animate_controller_inputs[0].checked = true;
    break;
    case "go":
    start_time = +new Date();
    animating = true;
    if (count >= max_count) {
    init();
    drawPath();
    animateRequest = requestAnimFrame(animateLoop, canvas);
    } else {
    animateRequest = requestAnimFrame(animateLoop, canvas);
    };
    break;
    case "reset":
    animateStop();
    init();
    drawPath();
    break;
    }
    };

    function animateStop() {
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    animate_controller_inputs[0].checked = true;
    };

    function runAnimateStep() {
    count++;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    transformPath();
    drawPath();
    frame.innerHTML = count;
    step_time = +new Date();
    framerate.innerHTML = ~~(10000 / ((step_time - start_time) / count)) / 10;
    // see: http://jsperf.com/rounding-numbers-down
    // I'm also rendering with one digit to the right of the decimal point
    };
    ctx.fillStyle = "rgba(0,255,0, 0.1)";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    canvas.style.border = 'solid 1px red'
    canvas.style.zIndex = 100
    };

    function drawInCanvas() {
    ctx.strokeStyle = "rgba(0,24,255, 1.0)";
    ctx.beginPath();
    ctx.moveTo(20, 180);
    ctx.lineTo(340, 180);
    ctx.closePath();
    ctx.stroke();
    };

    function animateLoop(){
    if (count < max_count && animating) {
    loop_start = +new Date();
    animateRequest = requestAnimFrame(animateLoop, canvas);
    runAnimateStep();
    loop_time = +new Date()
    loop_elapsed = loop_time - loop_start;
    while (loop_elapsed < 15) {
    runAnimateStep();
    loop_time = +new Date()
    loop_elapsed = loop_time - loop_start;
    }
    } else {
    animateStop()
    }
    };

    animate_controller.onchange = animateController;
    var create_canvas = document.getElementById("create-canvas");
    var draw_canvas = document.getElementById("draw-canvas");

    function createCanvasButton () {
    createCanvas();
    };

    init();
    drawPath();
    create_canvas.onclick = createCanvasButton;

    function drawCanvasButton () {
    drawInCanvas();
    };
    </script>

    draw_canvas.onclick = drawCanvasButton;

    };
    </script>
    </body>
    </html>
  8. stepheneb revised this gist Oct 19, 2011. 1 changed file with 2 additions and 5 deletions.
    7 changes: 2 additions & 5 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -133,11 +133,8 @@ <h1>Canvas Animate Path Benchmark</h1>

    function transformPath() {
    for (i=1; i < 5000; i++) {
    xpos = path[i][0];
    ypos = path[i][1];
    xpos += (transform_factor * Math.random() - transform_factor_div_2) + (half_width - xpos) * -correction;
    ypos += (transform_factor * Math.random() - transform_factor_div_2) + (half_height - ypos) * -correction;
    path[i] = [xpos, ypos];
    path[i][0] += (transform_factor * Math.random() - transform_factor_div_2) + (half_width - xpos) * -correction;
    path[i][1] += (transform_factor * Math.random() - transform_factor_div_2) + (half_height - ypos) * -correction;
    };
    };

  9. stepheneb revised this gist Oct 19, 2011. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -106,6 +106,7 @@ <h1>Canvas Animate Path Benchmark</h1>
    var run_mode;

    function init() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    count = 0;
    max_count = 250;
    xpos = half_width;
    @@ -165,7 +166,6 @@ <h1>Canvas Animate Path Benchmark</h1>
    };
    break;
    case "reset":
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animateStop();
    init();
    drawPath();
    @@ -188,6 +188,7 @@ <h1>Canvas Animate Path Benchmark</h1>
    step_time = +new Date();
    framerate.innerHTML = ~~(10000 / ((step_time - start_time) / count)) / 10;
    // see: http://jsperf.com/rounding-numbers-down
    // I'm also rendering with one digit to the right of the decimal point
    };

    function animateLoop(){
    @@ -197,7 +198,7 @@ <h1>Canvas Animate Path Benchmark</h1>
    runAnimateStep();
    loop_time = +new Date()
    loop_elapsed = loop_time - loop_start;
    while (loop_elapsed < 4) {
    while (loop_elapsed < 15) {
    runAnimateStep();
    loop_time = +new Date()
    loop_elapsed = loop_time - loop_start;
  10. stepheneb revised this gist Oct 19, 2011. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    ### Canvas Animate Path Benchmark


    [This example](http://bl.ocks.org/1299659) benchmarks the time taken to animate in Canvas with each frame consisting of 5000 segment line..
    [This example](http://bl.ocks.org/1299659) benchmarks the time taken to animate in Canvas with each frame consisting of a 5000 segment line.

    *source: [gist.github.com/gists/1299659](https://gist.github.com/gists/1299659)*
  11. stepheneb revised this gist Oct 19, 2011. 1 changed file with 10 additions and 6 deletions.
    16 changes: 10 additions & 6 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,7 @@
    td { text-align: center; font-weight: normal; padding: 0px 10px 0px 10px; }
    ul.hlist { display: inline-block; list-style-type: none; margin: 0px; padding-left: 15px; }
    ul.hlist li { display: inline-table; vertical-align: top; list-style-type: none }
    #canvas { width: 500px; height: 500px; padding:0px;
    #canvas { width: 400px; height: 400px; padding:0px;
    background-color: #eeeeee; color:gray; border: solid 1px #cccccc }
    </style>
    <script type="text/javascript">
    @@ -114,7 +114,7 @@ <h1>Canvas Animate Path Benchmark</h1>
    for (i=1; i < 5000; i++) {
    xpos += (factor * Math.random() - factor_div_2) + (half_width - xpos) * correction;
    ypos += (factor * Math.random() - factor_div_2) + (half_height - ypos) * correction;
    path.push([xpos, ypos]);
    path[i] = [xpos, ypos];
    };
    };

    @@ -145,8 +145,7 @@ <h1>Canvas Animate Path Benchmark</h1>
    if (this.elements[i].checked) run_mode = this.elements[i].value;
    switch(run_mode) {
    case "stop":
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    animateStop();
    break;
    case "step":
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    @@ -167,13 +166,18 @@ <h1>Canvas Animate Path Benchmark</h1>
    break;
    case "reset":
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    animateStop();
    init();
    drawPath();
    animate_controller_inputs[0].checked = true;
    break;
    }
    };

    function animateStop() {
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    animate_controller_inputs[0].checked = true;
    };

    function runAnimateStep() {
    count++;
  12. stepheneb revised this gist Oct 19, 2011. 1 changed file with 6 additions and 1 deletion.
    7 changes: 6 additions & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1 +1,6 @@
    ### Canvas Animate Path Benchmark
    ### Canvas Animate Path Benchmark


    [This example](http://bl.ocks.org/1299659) benchmarks the time taken to animate in Canvas with each frame consisting of 5000 segment line..

    *source: [gist.github.com/gists/1299659](https://gist.github.com/gists/1299659)*
  13. stepheneb created this gist Oct 19, 2011.
    214 changes: 214 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,214 @@
    <!DOCTYPE html>
    <html>
    <head>
    <title>Canvas Animate Path Benchmark</title>
    <style type="text/css">
    body { margin: 0px 10px; }
    h1 { font-size: 1.3em; line-height: 1.0em; }
    table { font-size: 0.8em; margin: 0px 10px; padding: 2px }
    th { text-align: center; font-weight: bold; padding: 0px 10px 0px 10px; }
    td { text-align: center; font-weight: normal; padding: 0px 10px 0px 10px; }
    ul.hlist { display: inline-block; list-style-type: none; margin: 0px; padding-left: 15px; }
    ul.hlist li { display: inline-table; vertical-align: top; list-style-type: none }
    #canvas { width: 500px; height: 500px; padding:0px;
    background-color: #eeeeee; color:gray; border: solid 1px #cccccc }
    </style>
    <script type="text/javascript">
    window.requestAnimFrame = (function() {
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
    return window.setTimeout(callback, 1000/60);
    };
    })();
    window.cancelRequestAnimFrame = (function() {
    return window.cancelCancelRequestAnimationFrame ||
    window.webkitCancelRequestAnimationFrame ||
    window.mozCancelRequestAnimationFrame ||
    window.oCancelRequestAnimationFrame ||
    window.msCancelRequestAnimationFrame ||
    window.clearTimeout;
    })();
    </script>
    </head>
    <body>
    <h1>Canvas Animate Path Benchmark</h1>
    <p>Measure performance of canvas line drawing speed by repeatedly re-drawing a 5000 element line.</p>
    <ul class="hlist">
    <li><canvas id="canvas"></canvas></li>
    <li>
    <form id="animate-controller">
    <fieldset>
    <legend>Step</legend>
    <label><input type="radio" name="step" value="stop" checked> Stop</input></label>
    <label><input type="radio" name="step" value="step"> Step</input></label>
    <label><input type="radio" name="step" value="go"> Go</input></label>
    <label><input type="radio" name="step" value="reset"> Reset</input></label>
    </fieldset>
    </form>
    <p>frame: <span id="frame"></span></p>
    <p>framerate: <span id="framerate"></span></p>
    <p><i>Animation will stop automatically after 250 frames.</i></p>
    </li>
    </ul>
    <p id="user-agent"></p>
    <script type="text/javascript">
    window.onload=function() {

    var user_agent = document.getElementById("user-agent");
    user_agent.innerHTML = navigator.userAgent;

    var canvas = document.getElementById("canvas");
    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;

    var animateRequest;

    var animate_controller = document.getElementById("animate-controller");
    var animate_controller_inputs = animate_controller.getElementsByTagName("input")

    var frame = document.getElementById("frame");
    var framerate = document.getElementById("framerate");

    var animating;

    var start_time, step_time;
    var loop_start, loop_time, loop_elapsed;

    var half_width = canvas.width / 2;
    var half_height = canvas.height / 2;

    var xpos = half_width;
    var ypos = half_height;
    var pos;

    var path = [];

    var ctx = canvas.getContext('2d');
    ctx.globalCompositeOperation = "destination-atop";
    ctx.lineWidth = 1;
    ctx.strokeStyle = "rgba(255,65,0, 1.0)";

    var i, j;

    var factor = 15;
    var factor_div_2 = factor / 2;
    var correction = 0.002;

    var transform_factor = 5;
    var transform_factor_div_2 = transform_factor / 2;
    var transform_correction = 0.00035;

    var count, max_count;
    var run_mode;

    function init() {
    count = 0;
    max_count = 250;
    xpos = half_width;
    ypos = half_height;
    path[0] = [xpos, ypos];
    for (i=1; i < 5000; i++) {
    xpos += (factor * Math.random() - factor_div_2) + (half_width - xpos) * correction;
    ypos += (factor * Math.random() - factor_div_2) + (half_height - ypos) * correction;
    path.push([xpos, ypos]);
    };
    };

    function drawPath() {
    ctx.beginPath();
    pos = path[0];
    ctx.moveTo(pos[0], pos[1]);
    for (var i=1; i < 5000; i++) {
    pos = path[i];
    ctx.lineTo(pos[0], pos[1]);
    };
    ctx.closePath();
    ctx.stroke();
    };

    function transformPath() {
    for (i=1; i < 5000; i++) {
    xpos = path[i][0];
    ypos = path[i][1];
    xpos += (transform_factor * Math.random() - transform_factor_div_2) + (half_width - xpos) * -correction;
    ypos += (transform_factor * Math.random() - transform_factor_div_2) + (half_height - ypos) * -correction;
    path[i] = [xpos, ypos];
    };
    };

    function animateController() {
    for(var i = 0; i < this.elements.length; i++)
    if (this.elements[i].checked) run_mode = this.elements[i].value;
    switch(run_mode) {
    case "stop":
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    break;
    case "step":
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    if (count < max_count) runAnimateStep();
    animate_controller_inputs[0].checked = true;
    break;
    case "go":
    start_time = +new Date();
    animating = true;
    if (count >= max_count) {
    init();
    drawPath();
    animateRequest = requestAnimFrame(animateLoop, canvas);
    } else {
    animateRequest = requestAnimFrame(animateLoop, canvas);
    };
    break;
    case "reset":
    if (animateRequest) cancelRequestAnimFrame(animateRequest);
    animating = false;
    init();
    drawPath();
    animate_controller_inputs[0].checked = true;
    break;
    }
    };

    function runAnimateStep() {
    count++;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    transformPath();
    drawPath();
    frame.innerHTML = count;
    step_time = +new Date();
    framerate.innerHTML = ~~(10000 / ((step_time - start_time) / count)) / 10;
    // see: http://jsperf.com/rounding-numbers-down
    };

    function animateLoop(){
    if (count < max_count && animating) {
    loop_start = +new Date();
    animateRequest = requestAnimFrame(animateLoop, canvas);
    runAnimateStep();
    loop_time = +new Date()
    loop_elapsed = loop_time - loop_start;
    while (loop_elapsed < 4) {
    runAnimateStep();
    loop_time = +new Date()
    loop_elapsed = loop_time - loop_start;
    }
    } else {
    animateStop()
    }
    };

    animate_controller.onchange = animateController;

    init();
    drawPath();

    };
    </script>
    </body>
    </html>
    1 change: 1 addition & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    ### Canvas Animate Path Benchmark