Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

context.beginPath() is not a function - why?

I'm trying to build an analogue clock SP feature, but before anything else, I've put it in an HTML file to provide proof of concept.

In an HTML file, separate from SharePoint, the code runs perfectly fine, no problem (in IE, Chrome and Firefox).

However, if I point a Content Editor web part to this file, the canvas draws but the setInterval doesn't fire because I get this:

Uncaught TypeError: ctx.beginPath is not a function

How do I resolve that?

Code (edited):

<canvas id="abcdef" width="400" height="400"></canvas>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

<script>

(function() {

    var canvas = document.getElementById("abcdef");
    var ctx = canvas.getContext("2d");
    var radius = canvas.height / 2;

    ctx.translate(radius, radius);
    radius = radius * 0.90;
    drawClock(ctx);
    setInterval(drawClock, 1000);

    function drawClock(context) {

        drawFace(context);
        drawNumbers(context);
        drawTime(context);
    }

    function drawFace(ctx) {

        var grad;

        console.info(ctx);

        ctx.beginPath();
        ctx.arc(0, 0, radius, 0, 2 * Math.PI);
        ctx.fillStyle = "lightgrey";
        ctx.fill()

        grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
        grad.addColorStop(0, '#333');
        grad.addColorStop(0.5, 'white');
        grad.addColorStop(1, '#333');
        ctx.strokeStyle = grad;
        ctx.lineWidth = radius * 0.1;
        ctx.stroke();

        ctx.beginPath();
        ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
        ctx.fillStyle = 'black';
        ctx.fill();
    }

    function drawNumbers(ctx) {

        var ang;
        var num;
        ctx.font = radius * 0.15 + "px arial";
        ctx.textBaseline = "middle";
        ctx.textAlign = "center";
        for (num = 1; num < 13; num++) {
        ang = num * Math.PI / 6;
        ctx.rotate(ang);
        ctx.translate(0, -radius * 0.85);
        ctx.rotate(-ang);
        ctx.fillText(num.toString(), 0, 0);
        ctx.rotate(ang);
        ctx.translate(0, radius * 0.85);
        ctx.rotate(-ang);
    }
    }

    function drawTime(ctx) {

        var now = new Date();
        var hour = now.getHours();
        var minute = now.getMinutes();
        var second = now.getSeconds();

        //hour
        hour = hour % 12;
        hour = (hour * Math.PI / 6) + (minute * Math.PI / (6 * 60)) + (second * Math.PI / (360 * 60));
        drawHand(hour, radius * 0.5, radius * 0.07, "grey");

        //minute
        minute = (minute * Math.PI / 30) + (second * Math.PI / (30 * 60));
        drawHand(minute, radius * 0.8, radius * 0.07, "black");

        // second
        second = (second * Math.PI / 30);
        drawHand(second, radius * 0.9, radius * 0.02, "red");
    }

    function drawHand(pos, length, width, colour) {

        ctx.beginPath();
        ctx.lineWidth = width;
        ctx.lineCap = "round";
        ctx.strokeStyle = colour;
        ctx.moveTo(0, 0);
        ctx.rotate(pos);
        ctx.lineTo(0, -length);
        ctx.stroke();
        ctx.rotate(-pos);
    }

}());

</script>
like image 265
user6778257 Avatar asked Jun 14 '26 13:06

user6778257


1 Answers

The error you're getting suggests that the global variable, ctx, is being used elsewhere in the page you're embedded inside, and is being overridden after your code has executed. The easiest solution to this, if your code otherwise works elsewhere, is to simply wrap it all in an IIFE, so all your variables are then locally scoped:

(function() {
    var canvas = document.getElementById("abcdef");
    var ctx = canvas.getContext("2d");
    var radius = canvas.height / 2;

    /* etc - include all your functions here too */
}());

This way none of your variables will conflict with any others that share the same name at the global scope.

like image 134
James Thorpe Avatar answered Jun 17 '26 02:06

James Thorpe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!