Animate the coloring process with dynamic motion

Is there a way to dynamically fill a canvas with color and apply animation? I have successfully created a canvas cylinder that fills with color, but I'm hoping for a slow animation effect when the color is filled.

I've tried searching on Google and found suggestions to use animations like 'fadein' or 'ease in', but none seem to be working for me.

Below is the code snippet I'm currently using:


var perc = 0;
$(document).ready(function () {
    // Input focusout event
    $("#my_input").focusout(function (event) {
        if ($("#my_input").val().indexOf("%") != -1) {

            if ($.isNumeric($("#my_input").val().replace('%', ''))) {

                // Allow only specific key presses
                if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 37) {
                    //$("#myCanvas").animate({ opacity: 0.25 });
                } else {
                    // Ensure input is a number and block invalid keypresses
                    if (event.keyCode < 48 || event.keyCode > 57) {
                        event.preventDefault();
                    }
                }
                perc = parseInt($("#my_input").val().replace('%', '')) / 100;
                draw();
            }
        } else {
            alert('Value should be in percentage format');
        }
    });
});

The above code handles the filling of the canvas based on the percentage value entered into an input field. The goal is to animate this process smoothly.

If you have any insights or solutions on how to achieve this type of dynamic color filling animation on a canvas element, please let me know!

Answer №1

To ensure that all drawing occurs within a cylindrical container, you can create the container as a clipping region.

This method guarantees that all content will only be visible inside the cylinder-shaped container.

For a visual demonstration and sample code, check out this Demo.

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

    // canvas related variables
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    var cw=canvas.width;
    var ch=canvas.height;

    // general variables
    var PI=Math.PI;
    var PI2=PI*2;

    // cylinder related variables
    var cx=cw/2;
    var cy=ch/2;
    var width=65;
    var height=100;
    var fillY=cy+height/2+5;
    var w2=width/2;
    var h2=height/2;
    var h4=height/4;
    var h8=height/8;
    var h16=height/16;
    var ytop=-h2+h8;
    var cpYtop=-h2-h16;
    var ybottom=h2-h8;
    var cpYbottom=h2+h16;
    var degreeAngle,rAngle,dx,dy,r,a,xx,yy;

    // start the cylinder upright (at 0 degree angle)
    setContainerAngle(0);

    // start the animations
    requestAnimationFrame(animateFill);

    // animate filling the cylinder
    function animateFill(){
        if(fillY>cy-height/2+h8){
            requestAnimationFrame(animateFill);
        }else{
            requestAnimationFrame(animateEmpty);
        }
        draw();
        drawPouring(cx,0,fillY);
        fillY-=0.50;
    }

    // animate emptying the cylinder
    function animateEmpty(){
        if(degreeAngle>-91){
            requestAnimationFrame(animateEmpty);
        }else{
            fillY=cy+height/2+5;
            requestAnimationFrame(animateToBeginning);
        }
        draw();
        drawPouring(xx,yy,ch);    
        setContainerAngle(degreeAngle-0.50);
    }

    // animate rotating the empty cylinder back to upright
    function animateToBeginning(){
        if(degreeAngle<=0){
            requestAnimationFrame(animateToBeginning);
        }else{
            setContainerAngle(0);
            requestAnimationFrame(animateFill);
        }
        draw();
        setContainerAngle(degreeAngle+1);
    }


    // draw the scene (background, cylinder, liquid in cylinder)
    function draw(){

        ctx.fillStyle="gray";
        ctx.fillRect(0,0,cw,ch);

        ctx.save();

        defineFillOutline(cx,cy,width,height,degreeAngle);

        if(degreeAngle>=-90){
            ctx.clip();
            ctx.fillStyle='gold';
            ctx.fillRect(0,Math.max(fillY,yy),cw,ch);
        }

        ctx.restore();

        drawContainer(cx,cy,width,height,degreeAngle);

    }

    // draw the liquid being poured in a vertical stream
    function drawPouring(xx,yy,yyy){
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(xx,yy);
        ctx.lineTo(xx,yyy);
        ctx.lineWidth=5;
        ctx.shadowColor="gold";
        ctx.shadowBlur=8;
        ctx.strokeStyle="gold";
        ctx.stroke();
        ctx.restore();
    }

    // define the clipping region (which is the cylinder)
    function defineFillOutline(x,y,w,h,degrees){
        ctx.save();
        ctx.translate(x,y);
        ctx.rotate(degreeAngle*PI / 180);
        //
        ctx.beginPath();
        ctx.moveTo(-w2,ytop);
        ctx.bezierCurveTo( -w2,cpYtop, w2,cpYtop, w2,ytop);
        ctx.lineTo(w2,h2-h8);
        ctx.bezierCurveTo( w2,cpYbottom, -w2,cpYbottom, -w2,ybottom);
        ctx.closePath();
        //
        ctx.restore();
    }

    // draw the cylinder at the specified angle
    function drawContainer(cx,cy,width,height,degreeAngle){
        //
        defineFillOutline(cx,cy,width,height,degreeAngle);
        //
        ctx.save();
        ctx.translate(cx,cy);
        ctx.rotate(degreeAngle*PI / 180);

        // this is the top-outer lip of the cylinder
        ctx.moveTo(-w2,-h2+h8);        
        ctx.bezierCurveTo( -w2,-h4, w2,-h4, w2,-h2+h8);
        ctx.strokeStyle="royalblue";
        ctx.lineWidth=2;
        ctx.stroke();
        //
        ctx.restore();
    }

    // change the angle of the cylinder
    function setContainerAngle(degrees){
        degreeAngle=degrees;
        rAngle=degreeAngle*Math.PI/180;
        dx=width/2;
        dy=height/2-height/8;
        r=Math.sqrt(dx*dx+dy*dy);
        a=Math.atan2(dy,dx)+Math.PI+rAngle;
        xx=cx+r*Math.cos(a);
        yy=cy+r*Math.sin(a);
    }

}); // end $(function(){});
</script>
</head>
<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble retrieving image files from CSS within a Spring MVC Application

I am facing an issue with my Spring MVC application where I cannot get an image to display in a CSS file accessed from a JSP file. The CSS is working fine, but the image just won't show up. It seems like there might be an issue with how I am addressin ...

Creating distinct web addresses for various sections of vue.js pagination

I've implemented pagination using vue.js for my website's gallery. However, I'm facing an issue where the URL doesn't change when navigating through pages and upon page refresh, it always resets to page 1. My goal is to have the URL ref ...

How do I switch the background-image on li hover and revert it back when I move off the li element?

Looking to update the background image of a div upon hovering over a li element? Check out this example here. So far, I've got that part working fine. But now I want the background picture to revert back to its original CSS when I move away from the l ...

Changing Settings on the Fly with JQuery

I am facing an issue with a table that has values generated dynamically using PHP, such as id and name attributes (e.g. id="question_". My challenge is how to set an element attribute considering this dynamic nature. For instance, I need to update the tex ...

What is the best way to determine the height of a DIV element set to "auto"?

When setting a fixed height on a div using jQuery, such as $('div').height(200);, the value of $('div').height() will always be 200. This remains true even if the content within the div exceeds that height and overflow is hidden. Is th ...

Can parameters be passed in an ajax request with a dynamic parameter name in asp.net?

Can someone help me with an issue I am facing with ajax requests? I have a post ajax request in asp.net where I pass parameters. When I change the parameter name in the code behind (aspx.cs), the request fails to post. However, when I tried the same with M ...

What is the correct way to denote a CSS class in SASS syntax?

Can you show me how to code this in SASS? .solo:hover > .solo-pane, .solo-pane.active, .solo-pane.lighten { opacity: 0.5; } I'm having trouble separating the classes using commas. ...

The magic of coding is in the combination of Javascript

My goal is to create a CSS animation using jQuery where I add a class with a transition of 0s to change the color, and then promptly remove that class so it gradually returns to its original color (with the original transition of 2s). The code below illus ...

"Stylish hover effect for list items using CSS arrows

I'm struggling with creating a list menu that has a 1px border and spans the entire width. Here is what I have so far (image 1): https://i.stack.imgur.com/y3EDP.png The tricky part is making it so that when the mouse hovers over a menu item, someth ...

"Interactive jQuery feature allows users to edit table content live with the ability to update and delete data via

I am working on implementing live editing, updating, and deleting functionality in a table using jQuery. However, I have encountered two problems: When clicking the pen icon from order #3 to #1, it requires 3 clicks, but when clicking from order #1 to ...

The max-width attribute is failing to apply to the form within the Bootstrap framework

login.html file: {% extends "base.html" %} {% block content %} <div class="container login-page-form"> <form id="login-form" action="/auth/login" method="post"> <div class="f ...

Error encountered with AJAX call when attempting to utilize string method

I am looking to add HTML content to a TinyMCE editor in an ASP.NET MVC project. After some thought, I have found a solution that involves converting the HTML file to a string on the server side and then calling it using Ajax on the client side. Here is a ...

Transitioning the height of a Vue component when switching routes

I've been struggling to implement a transition slide effect on my hero section. The height of the hero is set to 100vh on the homepage and half of that on other pages. Despite trying various methods, I haven't been able to get it working properly ...

What exactly does the <cbn-root> HTML element signify, and how can it be parsed using Java programming language?

I attempted to develop a Java program to monitor the availability of reserved spots on this website: However, when I examine the page source using Chrome or Edge, only <cbn-root></cbn-root> is displayed in the body section. Yet, utilizing Chro ...

Attempting to insert a square-shaped div within a larger square-shaped div and enable it to be moved around by dragging

Imagine this scenario: I have a button and a large div. When the button is clicked, the code adds a new div inside the larger one. However, the new div is not draggable because I didn't implement the necessary code. I'm also trying to figure out ...

Ajax waits for the animation to finish before proceeding

This topic has been previously discussed on stackoverflow, but none of the solutions have helped me solve my issue. I am utilizing the "form" jQuery plugin in the following manner: $(document).ready(function() { $('#myForm').ajaxForm({ ...

Share a model between two partial views within the same view

I'm facing an issue with loading two partial views in my main view. The main view is set to automatically refresh partial view 1, while partial view 2 should only update when a user clicks on an Ajax.ActionLink from partial view 1. This click event sh ...

convert webpages and images to PDF with a custom watermark

Looking to convert images fetched from the server into PDF format with a watermark by clicking a button. It would be ideal if there is a plugin that allows for PDF preview with disabled user selection and copy options. The website's platform is Sales ...

Looping through multi-dimensional JSON objects with jQuery

Hello there, I'm currently facing some challenges in getting the screen below to work properly: Project progress screen I have generated the following JSON data from PHP and MYSQL. My goal is to display the project alongside user images and names whe ...

absence of data returned in Ajax call for a REST endpoint

Currently, I am testing a straightforward REST service that was created using Java. The server-side code includes: import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import ...