0

I'm trying to smoothly resize an html5 canvas element. I've cobbled together bits of code and I think the following should work:

<body>
    <header id='myheader' height='200'>
        <canvas id='mycanvas' width='200' height='200'></canvas>

        <script>

        var mycanvas = document.getElementById('mycanvas');
        var context = mycanvas.getContext('2d');
        var centerX = mycanvas.width / 2;
        var centerY = mycanvas.height / 2;
        var radius = 70;

        context.beginPath();
        context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
        context.fillStyle = 'blue';
        context.fill();
        context.lineWidth = 5;
        context.strokeStyle = '#003300';
        context.stroke();

        var animate = function(prop, val, duration) {
            var start = new Date().getTime();
            var end = start + duration;
            var current = mycanvas[prop];
            var distance = val - current;
            var step = function() {
                var timestamp = new Date().getTime();
                var progress = Math.min((duration - (end - timestamp)) / duration, 1);
                mycanvas[prop] = current + (distance * progress);
                if (progress < 1) requestAnimationFrame(step);
            };
            return step();
        };

        animate('mycanvas.height', 10, 1000);

        </script>
    </header>       
</body>

...but obviously it doesn't! The result I'm looking for is a canvas that shrinks to just show the middle part of the circle (something more interesting than a circle will be added later). Is there anything obvious that I'm missing, or am I just doing this the wrong way? Ultimately I want to to resize both the canvas and the header together, so getting the canvas resizing to work is stage 1. Any help appreciated...

(Edit: actually, I ultimately want to resize both the canvas and header in response to a scroll event - which I think means avoiding a css solution - but I want to get this bit working first!)

1 Answer 1

1

Here are a few changes to your script that I believe do what you want:

    var mycanvas = document.getElementById('mycanvas');
    var context = mycanvas.getContext('2d');
    var radius = 70;

    function draw() {
        var centerX = mycanvas.width / 2;
        var centerY = mycanvas.height / 2;

        context.beginPath();
        context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
        context.fillStyle = 'blue';
        context.fill();
        context.lineWidth = 5;
        context.strokeStyle = '#003300';
        context.stroke();
    }

    var animate = function(target, prop, val, duration, action) {
        var start = new Date().getTime();
        var end = start + duration;
        var current = target[prop];
        var distance = val - current;
        var step = function() {
            var timestamp = new Date().getTime();
            var progress = Math.min((duration - (end - timestamp)) / duration, 1);
            target[prop] = current + (distance * progress);
            action();
            if (progress < 1) requestAnimationFrame(step);
        };
        return step();
    };

    animate(mycanvas, 'height', 10, 1000, draw);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! That's just what I wanted it to do - massively helpful.

Your Answer

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.