locked
A puzzle about canvas tag. RRS feed

  • Question

  • Hi, 

    I have a trouble when drawing some simple shapes using canvas in Metro App. The code I test is from the website: Canvas Tutorial.

    My Html code:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>App1</title>
    
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.1.0/css/ui-light.css" rel="stylesheet" />
        <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
        <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
    
        <!-- App1 references -->
        <link href="/css/default.css" rel="stylesheet" />
        <script src="/js/default.js"></script>  
    </head>
    <body>
            <canvas id ="canvas"></canvas>
        
    </body>
    </html>

    My default.js:

    // For an introduction to the Blank template, see the following documentation:
    // http://go.microsoft.com/fwlink/?LinkId=232509
    (function () {
        "use strict";
    
        WinJS.Binding.optimizeBindingReferences = true;
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll().then(function () {
                    draw();
                }));
            }
        };
    
        app.oncheckpoint = function (args) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
    
        app.start();
    
    })();

    The draw function is like this:

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
      ctx.fillRect(0,0,150,150);
      ctx.translate(75,75);
     
      // Create a circular clipping path
      ctx.beginPath();
      ctx.arc(0,0,60,0,Math.PI*2,true);
      ctx.clip();
     
      // draw background
      var lingrad = ctx.createLinearGradient(0,-75,0,75);
      lingrad.addColorStop(0, '#232256');
      lingrad.addColorStop(1, '#143778');
       
      ctx.fillStyle = lingrad;
      ctx.fillRect(-75,-75,150,150);
     
      // draw stars
      for (var j=1;j<50;j++){
        ctx.save();
        ctx.fillStyle = '#fff';
        ctx.translate(75-Math.floor(Math.random()*150),
                      75-Math.floor(Math.random()*150));
        drawStar(ctx,Math.floor(Math.random()*4)+2);
        ctx.restore();
      }
       
    }
    function drawStar(ctx,r){
      ctx.save();
      ctx.beginPath()
      ctx.moveTo(r,0);
      for (var i=0;i<9;i++){
        ctx.rotate(Math.PI/5);
        if(i%2 == 0) {
          ctx.lineTo((r/0.525731)*0.200811,0);
        } else {
          ctx.lineTo(r,0);
        }
      }
      ctx.closePath();
      ctx.fill();
      ctx.restore();
    }


    If I delete thoes lines:

    // draw stars
      for (var j=1;j<50;j++){
        ctx.save();
        ctx.fillStyle = '#fff';
        ctx.translate(75-Math.floor(Math.random()*150),
                      75-Math.floor(Math.random()*150));
        drawStar(ctx,Math.floor(Math.random()*4)+2);
        ctx.restore();
      }

    The image will be like this:

    Why the image will be mess when drawing shapes using CanvasRenderingContext2D.clip() method?





    • Edited by Lattimore Tuesday, January 8, 2013 9:59 AM
    Sunday, January 6, 2013 12:53 AM

Answers

  • Hi,

    I have reproduce the scenario on my side. And it is running normal on my side, the code just as follow:

    default.js

    (function () {
        "use strict";
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
        WinJS.strictProcessing();
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll().then(function completed() {
                    // addEventListener
                    draw();
                }));
            }
        };
    
        app.oncheckpoint = function (args) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
        function draw() {
            var ctx = document.getElementById('canvas').getContext('2d');
            ctx.fillRect(0, 0, 150, 150);
            ctx.translate(75, 75);
    
            // Create a circular clipping path
            ctx.beginPath();
            ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
            ctx.clip();
    
            // draw background
            var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
            lingrad.addColorStop(0, '#232256');
            lingrad.addColorStop(1, '#143778');
    
            ctx.fillStyle = lingrad;
            ctx.fillRect(-75, -75, 150, 150);
    
            // draw stars
            for (var j = 1; j < 50; j++) {
                ctx.save();
                ctx.fillStyle = '#fff';
                ctx.translate(75 - Math.floor(Math.random() * 150),
                              75 - Math.floor(Math.random() * 150));
                drawStar(ctx, Math.floor(Math.random() * 4) + 2);
                ctx.restore();
            }
    
        }
        function drawStar(ctx, r) {
            ctx.save();
            ctx.beginPath()
            ctx.moveTo(r, 0);
            for (var i = 0; i < 9; i++) {
                ctx.rotate(Math.PI / 5);
                if (i % 2 == 0) {
                    ctx.lineTo((r / 0.525731) * 0.200811, 0);
                } else {
                    ctx.lineTo(r, 0);
                }
            }
            ctx.closePath();
            ctx.fill();
            ctx.restore();
        }
    
    
        app.start();
    })();

    page.html

    <!DOCTYPE html>
    <html>
    <head>
        <title>draw example</title>
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet">
        <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
        <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
    
        <!-- ListViewExample references -->
        <script type="text/javascript" src="/draw/default.js"></script>
    </head>
    <body>
        <canvas id ="canvas"></canvas>
    
    </body>
    </html>
    

    Any question, please feel free to reply.

    Roy
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Lattimore Thursday, January 10, 2013 9:26 AM
    Thursday, January 10, 2013 3:50 AM

All replies

  • Hi,

    I have reproduce the scenario on my side. And it is running normal on my side, the code just as follow:

    default.js

    (function () {
        "use strict";
    
        var app = WinJS.Application;
        var activation = Windows.ApplicationModel.Activation;
        WinJS.strictProcessing();
    
        app.onactivated = function (args) {
            if (args.detail.kind === activation.ActivationKind.launch) {
                if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                    // TODO: This application has been newly launched. Initialize
                    // your application here.
                } else {
                    // TODO: This application has been reactivated from suspension.
                    // Restore application state here.
                }
                args.setPromise(WinJS.UI.processAll().then(function completed() {
                    // addEventListener
                    draw();
                }));
            }
        };
    
        app.oncheckpoint = function (args) {
            // TODO: This application is about to be suspended. Save any state
            // that needs to persist across suspensions here. You might use the
            // WinJS.Application.sessionState object, which is automatically
            // saved and restored across suspension. If you need to complete an
            // asynchronous operation before your application is suspended, call
            // args.setPromise().
        };
        function draw() {
            var ctx = document.getElementById('canvas').getContext('2d');
            ctx.fillRect(0, 0, 150, 150);
            ctx.translate(75, 75);
    
            // Create a circular clipping path
            ctx.beginPath();
            ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
            ctx.clip();
    
            // draw background
            var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
            lingrad.addColorStop(0, '#232256');
            lingrad.addColorStop(1, '#143778');
    
            ctx.fillStyle = lingrad;
            ctx.fillRect(-75, -75, 150, 150);
    
            // draw stars
            for (var j = 1; j < 50; j++) {
                ctx.save();
                ctx.fillStyle = '#fff';
                ctx.translate(75 - Math.floor(Math.random() * 150),
                              75 - Math.floor(Math.random() * 150));
                drawStar(ctx, Math.floor(Math.random() * 4) + 2);
                ctx.restore();
            }
    
        }
        function drawStar(ctx, r) {
            ctx.save();
            ctx.beginPath()
            ctx.moveTo(r, 0);
            for (var i = 0; i < 9; i++) {
                ctx.rotate(Math.PI / 5);
                if (i % 2 == 0) {
                    ctx.lineTo((r / 0.525731) * 0.200811, 0);
                } else {
                    ctx.lineTo(r, 0);
                }
            }
            ctx.closePath();
            ctx.fill();
            ctx.restore();
        }
    
    
        app.start();
    })();

    page.html

    <!DOCTYPE html>
    <html>
    <head>
        <title>draw example</title>
        <!-- WinJS references -->
        <link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet">
        <script src="//Microsoft.WinJS.1.0/js/base.js"></script>
        <script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
    
        <!-- ListViewExample references -->
        <script type="text/javascript" src="/draw/default.js"></script>
    </head>
    <body>
        <canvas id ="canvas"></canvas>
    
    </body>
    </html>
    

    Any question, please feel free to reply.

    Roy
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Lattimore Thursday, January 10, 2013 9:26 AM
    Thursday, January 10, 2013 3:50 AM
  • Hi,
    I have tested my code on Chrome. The draw() function also runs normally. Maybe there are some questions with my dev environment. I will check it. Thank you.
    Thursday, January 10, 2013 9:26 AM