Enhance the HTML5 Canvas arc by redrawing it upon hover

I have a challenge with my arcs: the first one loads on page-load, the second one loads on mouse-over, and the third one loads on mouse-out. However, I want the mouse-over-out effect to happen repeatedly rather than just once as it currently does.

For reference, here's the fiddle link: http://jsfiddle.net/krish7878/7bX7n/

Below is the JavaScript code snippet:


var currentEndAngle = 0;
var currentStartAngle = 0;

var currentEndAngle2 = 0;
var currentStartAngle2 = 0;

var currentEndAngle3 = -0.5;
var currentStartAngle3 = -0.5;

var something = setInterval(draw, 5);

$("#canvas1").hover(
    function(){
        var something2 = setInterval(draw2, 5);
    },
    function(){
        var something3 = setInterval(draw3, 5);
    }
);

function draw() { 
    var can = document.getElementById('canvas1'); 
    var canvas = document.getElementById("canvas1");
    var context = canvas.getContext("2d");
    var x = canvas.width / 2;
    var y = canvas.height / 2;
    var radius;
    var width;
    var currentColor = "#00b5ff";
    var radius = 100;
    var width = 8;

    var startAngle = currentStartAngle * Math.PI;
    var endAngle = (currentEndAngle) * Math.PI;

    if(currentEndAngle < 0.1){
      currentEndAngle = currentEndAngle - 0.01;
    }
    if (currentEndAngle < -0.5){
        clearInterval(something);
    }       
    context.beginPath();
    context.arc(x, y, radius, startAngle, endAngle, true);
    context.lineWidth = width;
    context.strokeStyle = currentColor;
    context.stroke();
}

function draw2() {
    // Function code removed for brevity
}

function draw3() {
    // Function code removed for brevity
}

Explanation of the code: There are three functions - draw(), draw2(), and draw3(). Draw is executed on page load, draw2() on mouse-over, and draw3() on mouse-out.

The final question raised is whether each arc should be drawn on individual canvases and cleared individually or if there is a more efficient method to achieve this effect?

Answer №1

Here is a method you can use:

Check out this demonstration: http://jsfiddle.net/m1erickson/wMy4G/

Create an arc object

var arc={
    cx:canvas.width/2,
    cy:canvas.height/2,
    radius:100,
    startRadians:0,
    endRadians:-Math.PI/2,
    linewidth:8,
    animationPercent:0,
    animationRate:10,
    animationDirection:0,
};

Display a section of the arc based on an animated point

function drawArc(arc,color){
    var rStart=arc.startRadians;
    var rEnd=arc.endRadians;
    if(!arc.animationDirection==0){
        if(arc.animationDirection>0){
            rEnd=arc.animationPercent/100*(rEnd-rStart);
        }else{
            rEnd=(100-arc.animationPercent)/100*(rEnd-rStart);
        }
    }
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.beginPath();
    ctx.arc(arc.cx,arc.cy,arc.radius,rStart,rEnd,true);
    ctx.strokeStyle=color;
    ctx.stroke();
}

Animate sections of the arc

function animate(time){

    if(continueAnimation){RAF=requestAnimationFrame(animate);}

    drawArc(arc,"blue");

    arc.animationPercent+=arc.animationRate;
    if(arc.animationPercent>=100){
        continueAnimation=false;
    }

}

Respond to hover events by displaying or hiding the arc

$("#canvas").hover(
    function(){
        cancelAnimationFrame(RAF);
        arc.animationPercent=0;
        arc.animationDirection=1;
        continueAnimation=true;
        requestAnimationFrame(animate);
    },
    function(){
        cancelAnimationFrame(RAF);
        arc.animationPercent=0;
        arc.animationDirection=-1;
        continueAnimation=true;
        requestAnimationFrame(animate);
    }
);

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

Troubleshooting an issue in Chrome with animating the "d" value using Snap.svg

To uncover the issue, try opening in both Chrome and Safari browsers. The logo animation should animate one section at a time like it does in Safari, but in Chrome, the animation seems to freeze. Check out the Snap.svg function responsible for running th ...

Incorporate a fresh attribute into each JSON object within a JavaScript array

Currently, my focus is on a react application where I am retrieving a JSON response from a specific route that consists of a collection of JSON objects. My objective now is to introduce a new field in each JSON object based on another field within the sam ...

Adjusting font size in a responsive div using Bootstrap 4

I'm attempting to dynamically resize text within a div, similar to the functionality shown in this example. As I resize the div, I want the font size to adjust accordingly. I've tried using various relative length units in pure CSS for the text ...

Achieving a horizontal alignment of these four div elements containing images

I need some assistance with aligning the divs using the .acontainer class. It was working perfectly before adding the images, but now it's all messed up. I've tried various adjustments and searches online, but I'm still stuck. Thank you for ...

Unable to use column formatting on a row using flexbox

I am working on creating a layout with rows and columns where the content in each column is vertically aligned. Here is an example of what I am trying to achieve: Currently, I am using react and have multiple components. The approach I believe will work ...

Determining the total of input values based on identification number

Can anyone help me figure out how to calculate the total sum of the values entered using IDs? I've been struggling with it and can't seem to get it to work. Your assistance would be greatly appreciated. <input type="number" id=&quo ...

Arranging arrays in Javascript within two dimensions

In my data set, I possess an array that contains tags along with their respective counts. tags_array[0] = tags; tags_array[1] = tags_count; My goal is to rearrange the arrays based on the tag counts to easily identify the most popular tags. ...

clickable jquery elements that can be selected and enabled for right

Currently, I have implemented a jQuery selectable feature in my project. Here is the code snippet: //Selectable Functionality $(document).ready(function () { $("#Selectable_Positions").selectable({ selected: function (event, ui) { ...

What is the best method to invoke a function recursively with a delay of 1 second following the completion of an ajax

I am facing a situation where I need to implement a delay of 1 second after an ajax request is completed, regardless of the outcome. Instead of calling a method every second, I specifically want to call a function 1 second after the ajax request finishes. ...

Delayed Page Update: Click Event Doesn't Execute Correctly Without JQuery

I'm a beginner in JavaScript and unable to use JQuery I have a table and I want to highlight the selected row on the click event. At the same time, I need to change the value of an input field. However, when I click on a row, the highlight effect get ...

Is there a non-table layout method to achieve equal width sharing with a fixed solution?

If I have n different elements to be placed in the same horizontal space, each taking up 100% of the screen width, for example: <table style="width:100%;text-align:center;table-layout:fixed"> <tr> <td><input/></td ...

After completing the installation of "node-pty" in an electron-forge project on Linux, I noticed that the pty.node.js file is not present. What is the proper way to install node-pty

Following the installation of node-pty, an external module utilized to generate pseudo terminals with Node.js in a boilerplate electron-forge project, I encountered an issue. The error indicated that a core module within node-pty was attempting to import a ...

Using CSS to leverage the power of both Grid and Flex simultaneously

Help Needed: CSS Challenge! I'm not a fan of CSS and can't seem to crack this code conundrum. Here's what I want the end result to look like: https://i.sstatic.net/z06qO.png Current Situation: #newOrderControl { border-style: solid ...

Modify the React MUI GridToolbar's font style

Is there a way to adjust the font size of the GridToolbar? https://mui.com/x/react-data-grid/components/#toolbar <DataGrid {...data} components={{ Toolbar: GridToolbar, }} /> I attempted to change the font size using the following code: & ...

Placing the error message for validation in its appropriate position

My login form has a layout that looks like this: https://i.stack.imgur.com/i7rCj.png If I enter incorrect information, it displays like this: https://i.stack.imgur.com/ItNJn.png The issue is that when the error message appears, it causes the login form ...

JavaScript issue: Submitting form does not trigger the associated function

I am currently in the process of learning JavaScript as part of my university course, and I have encountered an issue where my function is not being called. I am seeking to gain a better understanding of why this problem is occurring. Summary The situati ...

Calculating the average value of an attribute in an array using Mongodb (Mongoose)

Seeking assistance with a query to find sellers near users based on location input and sorting them by average rating. Is this achievable? Snippet of the model including an array of reviews: const sellerSchema = new mongoose.Schema({ _id: Mongo ...

Replicating Images in a Drag and Drop Layout

I am encountering an issue with my drag and drop feature, where dragging an image within the grid results in copying it instead of moving it. Below is the relevant code snippet: function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { ...

When using TypeScript with custom components as children in React, the `type` returned by React.Children is a string representing the function

It might sound a bit odd, or maybe I'm completely off track here. While going through some articles and React documentation on getting children and identifying specific child components using React.Component.map(), I ran into an issue with my custom c ...

The issue lies with Mongoose's inability to convert a string into an object key

When making an ajax call, I pass the object below to Mongoose: {category: 'name', direction: 1} To sort the query results using Mongoose, I use the following code: Site.find(query).sort(sortBy) Prior to this call, I need to format the object ...