After I googling a lot, I cannot find any tutorials which answering how to draw squircle shape in HTML5 canvas, please forgive me as I am very poor on math.
However I do find some similar / related answers, but I don't know how to combine these knowledges...
HTML5 Canvas alpha transparency doesn't work in firefox for curves when window is big
Continuous gradient along a HTML5 canvas path
https://stackoverflow.com/a/44856925/3896501
Thanks for any help!
UPDATE 1:
Code so far I created:
<body>
<div class="con">
<div class="ava"></div>
<canvas id="canvas"></canvas>
</div>
<script>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var shadowPadding = 8;
var strokeWidth = 2;
canvas.width = canvas.height = (64 + shadowPadding * 2) * window.devicePixelRatio
canvas.style.width = canvas.style.height = `${canvas.width / window.devicePixelRatio}px`
function drawMultiRadiantCircle(xc, yc, r, radientColors) {
var partLength = (2 * Math.PI) / radientColors.length;
var start = 0;
var gradient = null;
var startColor = null,
endColor = null;
for (var i = 0; i < radientColors.length; i++) {
startColor = radientColors[i];
endColor = radientColors[(i + 1) % radientColors.length];
// x start / end of the next arc to draw
var xStart = xc + Math.cos(start) * r;
var xEnd = xc + Math.cos(start + partLength) * r;
// y start / end of the next arc to draw
var yStart = yc + Math.sin(start) * r;
var yEnd = yc + Math.sin(start + partLength) * r;
ctx.beginPath();
gradient = ctx.createLinearGradient(xStart, yStart, xEnd, yEnd);
gradient.addColorStop(0, startColor);
gradient.addColorStop(1, endColor);
ctx.lineWidth = strokeWidth;
ctx.strokeStyle = gradient;
// squircle START
// https://stackoverflow.com/questions/50206406/drawing-a-squircle-shape-on-canvas-android
// //Formula: (|x|)^3 + (|y|)^3 = radius^3
// ctx.moveTo(-r, 0);
// const radiusToPow = r ** 3;
// const rad = r
// for (let x = -rad ; x <= rad ; x++)
// ctx.lineTo(x + r, Math.cbrt(radiusToPow - Math.abs(x ** 3)) + r);
// for (let x = rad ; x >= -rad ; x--)
// ctx.lineTo(x + r, -Math.cbrt(radiusToPow - Math.abs(x ** 3)) + r);
// ctx.translate(r, r)
// ctx.restore()
// squircle END
// circle START
// https://stackoverflow.com/a/22231473/3896501
ctx.arc(xc, yc, r, start, start + partLength);
// circle END
if (i === 1) {
break
}
ctx.stroke();
ctx.closePath();
start += partLength;
}
}
var someColors = [];
someColors.push('#0F0');
someColors.push('#0FF');
someColors.push('#F00');
someColors.push('#FF0');
someColors.push('#F0F');
var mid = canvas.width / 2;
var r = (canvas.width - (shadowPadding * 2)) / 2 + (strokeWidth / 2)
drawMultiRadiantCircle(mid, mid, r, someColors);
</script>
<style>
.con {
align-items: center;
justify-content: center;
display: flex;
height: 4rem;
margin: 6rem;
width: 4rem;
position: relative;
}
.ava {
background: #555 50% no-repeat;
background-size: contain;
border-radius: 24px;
height: 100%;
width: 100%;
}
canvas {
height: 100%;
width: 100%;
position: absolute;
}
</style>
</body>
drawing portion of circle with gradient color:
drawing a squircle:
I don't know how to code a algorithm that draws a portion of squircle just like what context.arc
does.