Create a rectangular canvas that wraps around another rectangle with rounded corners

I am facing a challenge where I want to make a canvas line wrap around an image with border radius. The idea is to use the canvas element so that I can control how far the rectangle wraps around the image. For instance, setting the value to 1 would result in a minimal wrap, while setting it to 100 would fully encompass the image with border radius. Below is an example using a circle:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

function newLine(){
  let value = (Math.floor(Math.random() * 100) + 1) * 0.06283185307179587;
  ctx.clearRect(0, 0, c.width, c.height);
  ctx.lineWidth = 10;
  ctx.strokeStyle = '#00FF00';
  
  ctx.beginPath();
  ctx.arc(100, 75, 55, 0, value);
  ctx.stroke();
}

setInterval(()=>{
newLine()
}, 100)
img{
  width: 100px;
  border-radius: 50px;
  position: absolute;
  left: 58px;
  top: 33px;
 }
<img src="https://media-exp1.licdn.com/dms/image/C4E0BAQHikN6EXPd23Q/company-logo_200_200/0/1595359131127?e=2159024400&v=beta&t=S5MNjBDjiH433VCWzjPeiopNDhxGwmfcMk4Zf1P_m_s"></img>
<canvas id="myCanvas"></canvas>

However, when I reduce the border radius slightly, the line no longer wraps around the image. Is there a solution for this issue?

Here is a code snippet illustrating the problem:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

function newLine(){
  let value = (Math.floor(Math.random() * 100) + 1) * 0.06283185307179587;
  ctx.clearRect(0, 0, c.width, c.height);
  ctx.lineWidth = 10;
  ctx.strokeStyle = '#00FF00';
  
  ctx.beginPath();
  ctx.arc(100, 75, 55, 0, value);
  ctx.stroke();
}

setInterval(()=>{
newLine()
}, 100)
img{
  width: 100px;
  border-radius: 30px;
  position: absolute;
  left: 58px;
  top: 33px;
 }
<img src="https://media-exp1.licdn.com/dms/image/C4E0BAQHikN6EXPd23Q/company-logo_200_200/0/1595359131127?e=2159024400&v=beta&t=S5MNjBDjiH433VCWzjPeiopNDhxGwmfcMk4Zf1P_m_s"></img>
<canvas id="myCanvas"></canvas>

Is there a way to achieve this effect? Thank you.

Answer №1

Impressed by the elegance of this solution, it offers great flexibility without any unnecessary JavaScript code.

const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");

let value = 0

function newLine(){
  value += Math.PI/60
  value %= Math.PI*2
  
  ctx.clearRect(0, 0, c.width, c.height);
  ctx.lineWidth = 10;
  ctx.fillStyle = '#00FF00';
  
  ctx.beginPath();
  // move to center
  ctx.moveTo(c.width/2, c.height/2)
  // line to right
  ctx.lineTo(c.width, c.height/2)
  // make a big semicircle
  ctx.arc(c.width/2, c.height/2, c.width, 0, value);
  ctx.fill();
}

setInterval(()=>{
newLine()
}, 100)
:root {
/** ===== Try changing these variables ===== **/
  --thing-radius: 35px;
  --thing-border: 5px;
  --thing-size: 100px;
  
  
  --thing-double-border: calc(2 * var(--thing-border));
}

.thing {
  width: calc(var(--thing-size) + var(--thing-double-border));
  height: calc(var(--thing-size) + var(--thing-double-border));
  display: grid;
  grid-template-areas: "center";
  grid-template-columns: 100%;
}

.thing > * {
  box-sizing: border-box;
  grid-area: center;
  width: 100%;
}

.thing > img {
  border-radius: var(--thing-radius);
  border: var(--thing-border) solid transparent;
  z-index: 1;
}
 
.thing > canvas {
  border-radius: var(--thing-radius);
}
<div class="thing">
  <!-- note that you don't need to change the canvas size -->
  <canvas id="myCanvas" width="100" height="100"></canvas>
  <img src="https://media-exp1.licdn.com/dms/image/C4E0BAQHikN6EXPd23Q/company-logo_200_200/0/1595359131127?e=2159024400&v=beta&t=S5MNjBDjiH433VCWzjPeiopNDhxGwmfcMk4Zf1P_m_s"/>
</div>

This innovative approach involves creating a large pie shape that is then masked by CSS to fit behind the image seamlessly.

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

Optimal strategies for arranging the hierarchy of directories and documents within a Library

I am in the process of creating a new library to be distributed via npm and I am seeking advice on the most effective way to organize my folder and file structure. Is it recommended to minify the code and place it in a dist/ directory as well? Here is th ...

What is the process for setting up a resthook trigger in Zapier?

I'm currently integrating Zapier into my Angular application, but I'm struggling with setting up a REST hook trigger in Zapier and using that URL within my app. I need to be able to call the REST hook URL every time a new customer is created and ...

Change the background color of a link using jQuery

Currently in the process of using jQuery to change the background color of a link when it's clicked. However, I would like to revert this color back to its original state once either a) the link is closed or b) another link is clicked (such as Dropdow ...

Concealing Bootstrap Dialog in Angular 6 through Component隐藏Angular 6中

I have been struggling to hide a bootstrap dialog from a component with no success. Here is my Dialog code: <div class="modal fade" id="loading_video_upload" tabindex="-1" role="dialog" aria-labelledby="loading_video_upload_label" aria-hidde ...

When using .NET HtmlButton, validators will always be triggered

Recently, I converted an HtmlButton into a server control with validation disabled. <button runat="server" causesvalidation="false" /> This is not referring to the input button!!! <input type="button" runat="se ...

What is the best way to update information within a <tbody> tag?

Can someone assist me with replacing content in an HTML table? Please review my code below: <html> <head> <script type="text/javascript"> function changeRows() { var htmlString="<tr><td>bhanu</td><t ...

What is the best way to send the index variable to an HTML element in Angular?

Is there a way to pass the index variable to construct HTML in the append() function? .directive('grid', ['$compile', function(compile) { return { restrict: "E", scope: { elements: '=' ...

What is the best way to use a button to hide specific divs upon clicking?

Is there a way to use a button onclick event to hide specific divs within a parent div? I've tried using .toggleClass('.AddCSSClassHere') but I'm not sure how to apply it to multiple divs. The jQuery snippet provided only allows me to h ...

Creating distinctive ng-form tags within a form using ng-repeat in Angular

I need help with creating a form that includes a table looping over a list of objects. Each object should have checkboxes for the user to check/uncheck attributes. The issue I am facing is setting the ng-model attribute on the checkboxes. This is what my ...

Zebra Striping Tables with jQuery and Concealed Rows

Up until now, I haven't had any issues using the following code: $("#tableid tr:even").addClass("evenClass"); However, my table now contains hidden rows which is causing problems with the alternating row styles. I've attempted to add 'is(" ...

Shifting Elements - Navigation triggers subtle movements in CSS styles as you move across pages

I've noticed a strange issue on my website where certain elements seem to be shifting slightly when navigating between different pages. Here's a quick video clip demonstrating the problem. It appears that these elements are not staying static as ...

PHP - Basic table design

Can someone assist me in displaying my code output in a table format? https://i.sstatic.net/Urbjc.jpg I am new to PHP and struggling with formatting the label and value of $attribute and $attribute_label in a table. If anyone could provide guidance on h ...

"Exploring the capabilities of Node WebKit in conjunction with Serial

Currently, I am in the process of building an application using Node WebKit and require access to the SerialPort on my Windows 8 PC. To install third-party modules with C/C++ addons, I followed the instructions outlined in this guide: https://github.com/n ...

Unable to use jQuery for dynamically populating select options with values retrieved via AJAX calls

Trying to update the value of a select option using this method doesn't seem to work when the options are loaded via AJAX. The goal is to reset the option back to its original value after a page refresh due to form validation issues such as missing r ...

Utilizing Angular's binding feature with objects

Clarifying the question for better understanding. Plunkr Preview: <input type="text" ng-model="form['data']['sampleData']"> <input type="text" ng-model="form[bindingPrefix][bindingSuffix]"> <input type="text ...

Is there a way to rotate an object with an MTL material in an animated sequence

After spending the entire weekend attempting to rotate an obj mtl in the animation function, I've reached a dead end. Despite exhaustively searching through all related postings on this issue and making various changes, nothing seems to work. The cod ...

`Can JavaScript or jQuery be used to conceal the referrer and implement a redirect?`

I'm having trouble making this work. Can anyone offer assistance? When I open this page in my browser: http://www.domain.com/in.php?public=1&private=2 The code below is being called to reload the page without the private value: window.location ...

Tips for retaining the original text value even after clicking the submit button

import java.util.Map; import java.util.HashMap; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org ...

placing additional containers at the bottom rather than on the right side

Hey there! I'm currently working on a simple website and I'm having trouble getting the duplicated form rows to appear aligned below the previous one. Here's what I have right now: var i = 0; var original = document.getElementById("dupl ...

Ways to Verify the Existence of a Value in an Array Using JavaScript

In my Laravel blade file, I have an array that I am accessing in JavaScript like this: var data = {!! json_encode($data) !!}; When I check the console, the variable is displayed as seen here: variable data console print Additionally, I'm retrieving ...