Create a curve using two distinct colors in JavaScript

I am currently experimenting with a canvas and I have a specific challenge in mind. My goal is to draw an arc using two different colors, where the first half of the arc will be green and the second half red. Check out the code snippet below:

// CANVAS
const canvas = document.getElementById('bar'),
    width = canvas.width,
    height = canvas.height;

// CANVAS PROPERTIES
const ctx = canvas.getContext('2d');
ctx.lineWidth = 6;
ctx.strokeStyle = 'green';
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;

const x = width / 2,
    y = height / 2,
    radius = 41,
    circum = Math.PI * 2,
    start = 2.37, 
    finish = 75; 
  let curr = 0; 
const raf =
    window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame;
window.requestAnimationFrame = raf;

function animate(draw_to) {
  //ctx.clearRect(0, 0, width, height);
  ctx.beginPath();
  ctx.arc(x, y, radius, start, draw_to, false);
  ctx.stroke();
  curr++;
  if (curr < finish + 1) {
    requestAnimationFrame(function () {
      animate(circum * curr / 100 + start);
    });
  }
}

animate();

For the full code implementation, visit: https://jsfiddle.net/gowtham25/bp0myt21/11/

Answer №1

Is this what you're looking for?

const canvas = document.querySelector('canvas')
const ctx = canvas.getContext('2d')

const x = canvas.width / 2
const y = canvas.height / 2
const radius = 41
const start = -25
const end = 75
const width = 6

function DrawArc(x, y, radius, start, end, width, color) {
  ctx.beginPath()
  ctx.lineWidth = width
  ctx.strokeStyle = color
  ctx.arc(x, y, radius, start, end, false)
  ctx.stroke()
}

function DrawGauge(percentage) {
  const rotation = Math.PI * 0.75
  const angle = Math.PI * 1.5
  const current = angle * percentage / 100

  DrawArc(x, y, radius, rotation, rotation + current, width, 'green')
  DrawArc(x, y, radius, rotation + current, rotation + angle, width, 'red')
}

function Animate(percent = 0) {
  if (percent < 0) return
  if (percent > 100) return
  DrawGauge(percent)
  requestAnimationFrame(() => Animate(++percent))
}

Animate()
<canvas></canvas>

It's advisable to create separate functions to draw different elements so that you can easily customize and reuse them. This approach helps in separating the drawing logic from data manipulation, which is crucial as your projects become more complex.

Answer №2

To ensure proper drawing, it is essential to adjust the startAngle parameter in the
ctx.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);

If you modify the strokeStyle without updating the startAngle, the drawing will occur on the same path.

https://jsfiddle.net/97ogkwas/4/

// CANVAS
const canvas = document.getElementById('bar'),
    width = canvas.width,
    height = canvas.height;

// CANVAS PROPERTIES
const ctx = canvas.getContext('2d');
ctx.lineWidth = 6;
ctx.strokeStyle = 'green';
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;

let x = width / 2,
    y = height / 2,
    radius = 41,
    circum = Math.PI * 2
    start = 0.5* Math.PI
    finish = 75; 
  let curr = 0; 
const raf =
    window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame;
window.requestAnimationFrame = raf;

function animate(draw_to) {
  //ctx.clearRect(0, 0, width, height);
  ctx.beginPath();
   if(curr>45){
    ctx.strokeStyle = 'red';
        start = 1* Math.PI;
       
    }
  ctx.arc(x, y, radius, start, draw_to, false);
  ctx.stroke();
  curr++;
  if (curr < finish + 1) {
    requestAnimationFrame(function () {
  
      animate(circum * curr / 100 + start);
      
    });
  }
}

animate();
#bar {
  position: absolute;
  top: 0;
  left: 0;
}
<canvas id="bar" width="100" height="100"></canvas>

https://jsfiddle.net/97ogkwas/4/

Answer №3

// HTML CANVAS CREATION
const canvas = document.getElementById('bar'),
     width = canvas.width,
     height = canvas.height;

// SETTING CANVAS PROPERTIES
const ctx = canvas.getContext('2d');
ctx.lineWidth = 1;
ctx.strokeStyle = 'green';
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;

// ANOTHER SET OF CANVAS PROPERTIES
const ctx2 = canvas.getContext('2d');
ctx2.lineWidth = 1;
ctx2.shadowOffsetX = 0;
ctx2.shadowOffsetY = 0;

var x = width / 2,
    y = height / 2,
    radius = 40,
    circum = Math.PI * 2,
    start = 2.37, 
    finish = 50; 
      
let curr = 0; 
  
const raf = window.requestAnimationFrame ||
          window.mozRequestAnimationFrame ||
          window.webkitRequestAnimationFrame ||
          window.msRequestAnimationFrame;
window.requestAnimationFrame = raf;

function animate(draw_to) {
  //ctx.clearRect(0, 0, width, height);
  ctx.beginPath();
  ctx.arc(x, y, radius, start, draw_to, false);
  ctx.stroke();
  curr++;
  if (curr < finish + 5) {
    requestAnimationFrame(function () {
      animate(circum * curr / 100 + start);
    });
  }
}

function animate2(draw_to) {
  //ctx.clearRect(0, 0, width, height);
  ctx2.beginPath();
  ctx2.arc(x, y, radius, start, draw_to, false);
  ctx2.stroke();
  curr++;
  if (curr < finish + 5) {
    requestAnimationFrame(function () {
      animate2(circum * curr / 100 + start);
    });
  }
}

animate();

setTimeout(function(){ 
finish = 52;
start = 5.5;
ctx2.strokeStyle = 'red';
animate2();
}, 2000);
#bar {
  position: absolute;
  top: 0;
  left: 0;
}
<canvas id="bar" width="100" height="100"></canvas>

The question is vague! Here is a possible solution:

https://jsfiddle.net/15srnh4w/

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

The CSS of the Sendgrid template is being overlooked

I have utilized Sendgrid to create the template mentioned below: In order to send this template using my Node server, I have developed the module provided in the code snippet: /* * Created by root on 6/6/16. */ var path = require('path'), ...

I encountered an issue while trying to integrate VideoJS with React

While using VideoJS, the video plays without any issues. However, I am facing an issue where the available source options are not being displayed as they should be. I attempted to use a plugin for the sources, but even then, the options didn't show u ...

The alertify.alert function encounters issues when used within the response of a mithril m.request

I'm currently working on a project utilizing mithril.js and also integrating alertify.js. I am encountering an issue when trying to alert some data in the response. Strangely, it doesn't work as expected. However, if I use the same alert function ...

The z-index property does not seem to apply to pseudo elements

I am facing an issue while trying to add a pseudo element after a div in my react project. Surprisingly, the code works perfectly fine in CodePen but fails to work on my local machine. I have applied z-index only in CodePen, which seems to resolve the issu ...

Sometimes, the browser may fail to recognize a jQuery click event when a CSS3 transform is applied

There is an issue where click events are sometimes not triggered when an element contains another element being animated with CSS transitions. To see an example of this problem, check out the test case at http://codepen.io/anon/pen/gbosy In my layout, I ...

Using Mongoose with Next.js to implement CRUD operations

I have been successful in implementing POST and GET methods in my Next.js app using mongoose, but I am facing challenges with the delete operation. This is an example of my POST method located in the API folder: export default async function addUser(req, ...

implementing a timestamp in a specific timezone with Vue.js

Utilizing a timestamp attribute, I have successfully implemented the display of the current time and date on my webpage. Is there a way to showcase this information in a specific time zone? I am looking to present it in the ZULU timezone, which remains st ...

Display or conceal div based on chosen options

I am working on a feature that involves three dropdown select boxes, each containing different sets of demographic attributes. My goal is to show a score based on the combination of selections made by the user. For example, if a user chooses Male, 18-24, A ...

Could someone assist me in understanding why VScode is displaying an error stating it cannot locate a module?

node:internal/modules/cjs/loader:1051 throw err; ^ Error: The module '/Users/ben/Desktop/GA/unit2/week5/GA_Project_2/QuotaQuest/index.js' cannot be found. at Module._resolveFilename (node:internal/modules/cjs/loader:1048:15) at Modul ...

I am experiencing an issue where the Mongo item ID is not being successfully passed through the REST API

Recently, I've been working on developing a blog site for my class project. The main goal is to create a REST API for the blog site. I have successfully managed to display data from the database using .ejs views, except for one issue. I am facing diff ...

Exploring the concept of self in JavaScript

Exploring the concept of "self" magic, take a peek at this excerpt from nodejs (which is not complete). Socket.prototype.connect = function(options, cb) { ...... var self = this; var pipe = !!options.path; if (this.destroyed || !this._handle) { ...

Using whitespace to format a document.write in JavaScript

I'm in the process of creating a dynamic table using JavaScript and a set of objects. I've managed to structure it, but now I require some extra white space between them, almost like tabbing them out. How can I achieve this efficiently with my cu ...

What would be the ideal alternative if the Google Ajax API is unavailable, given that Google does not allow for local installation?

On my website, I include the following script: ... <script type="text/javascript" src="https://www.google.com/jsapi"></script> ... This particular script is from Google and is used to dynamically load other resources, such as the Google Chart ...

Guide on dynamically updating a div in PHP with a mix of text output and images at regular intervals

My current project involves creating a browser-based card game primarily using PHP, with potentially incorporating other languages to help me enhance and test my PHP skills. However, I've encountered difficulties while attempting to implement various ...

Manipulate a JavaScript object with AngularJS - viewing and editing capabilities

I'm looking to create a dynamic list of objects where clicking on an entry displays the object details and an edit button. When clicking on the edit button, the details should disappear and a form for editing the object should appear on the right side ...

Error encountered while attempting to retrieve an environment variable: Invalid token found

I am currently facing an issue while trying to add an environment variable inside the .env file in my Nuxt project. The version of Nuxt.js I am using is 2.15.3 Below is a snippet from my nuxt.config.js: export default { publicRuntimeConfig: { baseU ...

Updating the load context variable in Django template after making changes via an AJAX call: a step-by-step guide

Here is the code snippet for displaying table items in my customer_items.html page: <table id="tblData" style="width: 100% !important;" class="display table table-bordered table-striped table-condensed"> <thead> <tr> ...

site with scrolling options in various directions

Someone recently asked me if I could create a multi-directional scrolling website similar to the one found at COS, but using WordPress. At first, I assumed it might be done with Flash, but the source code suggests it could actually be more simple, possibly ...

Attempting to understand how to retrieve specific items from my MongoDB Database that are associated with a particular user based on their ID

I've been attempting to retrieve specific items (Portfolio pics) that have been submitted by a user from my Mongo Database. However, when I checked the extracted items using Console logs, it seems to display all portfolio pieces for every user instead ...

The Vue design is not being reflected as expected

Encountering a peculiar issue where the style in my Vue component is not being compiled and applied alongside the template and script. Here's the code snippet: To achieve an animated slide fade effect on hidden text upon clicking a button, I've ...