Tips for including a line within a circular canvas

My progress bar crafted with css, javascript and html looks great (left image).

However, I'm facing a challenge in adding white color dividers to enhance the appearance of the progress bar as shown in the image on the right. Despite my various attempts, I have not been able to achieve this desired effect. I would greatly appreciate any assistance or guidance on how to resolve this issue.

Check out the DEMO

Answer №1

A solution to this problem involves using the globalCompositeOperation property in HTML canvas, which allows us to draw lines over the canvas and use them as a mask to clip the chart. Some adjustments may be necessary to customize the lines to your specific requirements. Here is a starting point for implementing this functionality:

var applyMask = function(numLines, lineWidth) {
  ctx.save();
  ctx.beginPath();
  // Reset any previous rotations:
  ctx.rotate(-1 * options.rotate * Math.PI / 180);
  // Set up the mask:
  ctx.globalCompositeOperation = 'destination-out';
  ctx.lineWidth = lineWidth;
  for (var i = 0; i < numLines; i++) {
    ctx.rotate(Math.PI / (numLines / 2));
    ctx.moveTo(0, 0);
    ctx.lineTo(0, 120);
    ctx.stroke();
  }
  ctx.restore();
}
applyMask(8, 4);

To observe how this code integrates with your existing implementation, you can view either the JSFiddle example or refer to the following functional demo:

// Retrieve canvas element
var el = document.getElementById('graph');

// Define custom options
var options = {
    percent: el.getAttribute('data-percent') || 45,
    size: el.getAttribute('data-size') || 220,
    lineWidth: el.getAttribute('data-line') || 25,
    rotate: el.getAttribute('data-rotate') || 200
}

// Create new canvas element
var canvas = document.createElement('canvas');
var span = document.createElement('span');
span.textContent = el.getAttribute('data-text') + ' $';

if (typeof(G_vmlCanvasManager) !== 'undefined') {
    G_vmlCanvasManager.initElement(canvas);
}

var ctx = canvas.getContext('2d');
canvas.width = canvas.height = options.size;
el.appendChild(span);
el.appendChild(canvas);

ctx.translate(options.size / 2, options.size / 2); 
ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); 

var radius = (options.size - options.lineWidth) / 2;

var drawCircle = function(color, lineWidth, percent) {
percent = Math.min(Math.max(0, percent || 1), 1);
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
ctx.strokeStyle = color;
ctx.lineCap = 'square'; 
ctx.lineWidth = lineWidth;
ctx.stroke();
};

drawCircle('#bbbec3', options.lineWidth, 100 / 100);
drawCircle('#c21b17', options.lineWidth, options.percent / 100);

// Apply mask over the chart
var applyMask = function(numLines, lineWidth) {
  ctx.save();
  ctx.beginPath();
  ctx.rotate(-1 * options.rotate * Math.PI / 180);
  ctx.globalCompositeOperation = 'destination-out';
  ctx.lineWidth = lineWidth;
  for (var i = 0; i < numLines; i++) {
    ctx.rotate(Math.PI / (numLines / 2));
    ctx.moveTo(0, 0);
    ctx.lineTo(0, 120);
    ctx.stroke();
  }
  ctx.restore();
}
applyMask(8, 4);
.chart {
    position: relative;
    width: 220px;
    text-align: center;
}
canvas {
    display: block;
    position:absolute;
    top:0;
    left:0;
}
span {
    color:#555;
    display:block;
    line-height:220px;
    text-align:center;
    width:220px;
    font-family:sans-serif;
    font-size:30px;
    font-weight:100;
    margin-left:5px;
} 
.centerbox{
        display: inline-block;
    bottom: 0;
    width: 45px;
    position: absolute;
    z-index: 1;
    margin-left: -50px;
    border-bottom: 35px solid #fff;
    border-left: 30px solid transparent;
    border-right: 30px solid transparent;
}
<div class="chart" id="graph" data-text="123123" data-percent="55"><label class="centerbox"><i class="fa fa-usd" aria-hidden="true" style="padding-top: 10px;position: absolute;"></i></label></div>

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

Exploring the Differences between Angular's Http Module and the Fetch API

While I grasp the process Angular uses for HTTP requests, I find myself leaning towards utilizing the Fetch API instead. It eliminates the need to subscribe and unsubscribe just for a single request, making it more straightforward. When I integrated it int ...

Implementing asynchronous validation in Angular 2

Recently started working with Angular 2 and encountered an issue while trying to validate an email address from the server This is the form structure I have implemented: this.userform = this._formbuilder.group({ email: ['', [Validators.requir ...

Combining two HTML tables using jQuery/JavaScript

My table is displayed below: <table id="first" class="merge"> <tr> <td>Mick Jagger</td> <td>30</td> <td>50</td> <td>10</td> </t ...

Material-inspired Design Device Compatible DIV slide with JS, JQuery, and CSS

My goal is to achieve something similar to this: Desired Live Website I am looking for a feature where clicking on the div will slide in content from the right, load an external page inside it, and close when prompted. The slider div should be device c ...

Utilize Express Handlebars to render an input-generated list for display

My goal is to showcase a collection of wishlist items on a basic webpage through user interaction. Here's how I envision it: 1. do something 2. do another thing 3. blahblah This snippet shows my index.js code: var wishlist = []; router.post('/& ...

Conceal or reveal input elements with a toggle function in jQuery by utilizing

When the user chooses an option from a dropdown list, I want to display or hide different input fields accordingly. I attempted to use toggle with boolean values, but it doesn't seem to be working as expected. I expect that if I send 'true' ...

Ways to condense a text by using dots in the middle portion of it

How can I dynamically shorten the text within a container that varies in width? The goal is to replace the strings between the first and last words with dots so that it fits within the container. For example, Sydney - ... - Quito. It should only replace wh ...

Creating a system to add and limit dynamic fields with a counter in jQuery

Check out this fiddle link http://jsfiddle.net/gKJEs/80/ I'm looking for a way to limit the number of rows that can be added, let's say up to 5. Here is the HTML code: <table id="table"></table> <button id="addRowBtn">Add Ro ...

Ways in which elements can be toggled through jquery or javascript?

There are various words listed below: word1 word2 word3 ... Every word in the list is linked to 1 to 3 examples. When a user clicks on a word, certain actions should take place. I want the examples to display when the associated word (e.g., word1) is c ...

Transform a single data point into pixels by converting its latitude and longitude coordinates

I am facing a specific challenge where I have hit a roadblock after conducting some research. The issue at hand is this: I am working with a raster image that has known dimensions (800 x 800 px) I have two points within this image with their pixel and g ...

Using Vue.js to toggle rendering based on checkbox selection

Struggling to conditionally render form elements in Vue based on user input. I can do this with VanillaJS or jQuery, but struggling to implement it with Vue's built-in conditional directives. Using single-file components with the webpack template from ...

I keep encountering a 'Missing Permissions' issue whenever I attempt to execute the ban command in Discord.js. What could be causing this problem?

While working on coding a ban command for my Discord server, I encountered an issue where the command was not working as expected. Upon testing, I received an error message on the console stating DiscordAPIError[50013]: Missing Permissions. This was puzzli ...

What is the most efficient way to access a cell within an HTML table using jQuery or the Document Object Model (

I have an unchangeable HTML table styled with CSS. My goal is to extract the value from the first column for filtering purposes. I've been struggling to locate a suitable jQuery or DOM function to accomplish this task. Unable to find a way to access ...

Deciphering key-value pairs that are separated by commas

I am looking to convert the following format: realm="https://api.digitalocean.com/v2/registry/auth",service="registry.digitalocean.com",scope="registry:catalog:*" Into this JSON object: { realm: "https://api.digitaloce ...

Steps for Disabling Autocomplete in a JSP Page

How can I prevent the browser from remembering the username and password on my JSP page after submitting the form? I've already tried using autocomplete=off in the JSP code. <form name="indexFrm" id="indexFrm" autocomplete="off" method="post"> ...

Using Laravel to submit a form with identical input names via AJAX

Seeking assistance with my ajax function. A form I have is submitting data with the same input name. Without using JavaScript, I can insert multiple input data with the same name easily, Here is the structure of the submitted data {"_token":& ...

Experimenting with a custom AngularJS filter designed to extract numerical values from a chunk of text

I am working on creating a unique filter that can extract numbers from text input into a text box. For example: User enters: The cat went to 4 stores and bought 3 bags of cat litter for 1 dollar. The desired output would be: [4, 3, 1] This filter works ...

Utilizing Ajax to Invoke Wordpress Functions from a Client's Browser

Currently working on setting up a WordPress website integrated with WooCommerce, while also developing an HTML5 app for my small online store. I am looking to utilize Ajax to call WordPress functions like search directly from my HTML5 app and receive the r ...

Tips on implementing CSS to the subpar class in Vuejs

I am working on an HTML file that operates with button in Vue.js. The v-bind:class can be utilized for a single tag as shown below. It disappears based on the boolean value of bool data. <h3 v-bind:class="{active: bool}">{{counter.document}}&l ...

Tips for optimizing the performance of a sine wave animation

After experimenting with JavaScript, I've managed to create a visually appealing sine wave animation but it's causing performance issues due to the high number of vectors being generated. My current setup involves utilizing the p5js library. Bel ...