MMTTMM
如果我们阅读关于 squircles的维基百科文章,我们会看到这只是使用 2 或更高幂的未加权椭圆函数,这意味着我们可以很容易地计算给定“x”值的“y”值并以这种方式绘制东西,但是这样做会给我们带来极不均匀的片段:微小的变化x会导致y起点和终点的巨大变化,而y中点的微小变化。相反,让我们将方圆建模为参数函数,因此我们改变一个控制值并获得合理均匀的间隔来使用。我们可以在关于超椭圆函数的维基百科文章中找到解释:x = |cos(t)^(2/n)| * sign(cos(t))y = |sin(t)^(2/n)| * sign(sin(t))对于t从 0 到 2π,半径固定为 1(因此它们从乘法中消失)。如果我们实现了这一点,那么我们几乎可以事后添加彩虹色,分别绘制每个路径段strokeStyle,使用 HSL 颜色的着色,其中色调值根据我们的t值发生变化:// alias some math functions so we don't need that "Math." all the timeconst abs=Math.abs, sign=Math.sign, sin=Math.sin, cos=Math.cos, pow=Math.pow;// N=2 YIELDS A CIRCLE, N>2 YIELDS A SQUIRCLEconst n = 4;function coord(t) { let power = 2/n; let c = cos(t), x = pow(abs(c), power) * sign(c); let s = sin(t), y = pow(abs(s), power) * sign(s); return { x, y };}function drawSegmentTo(t) { let c = coord(t); let cx = dim + r * c.x; // Here, dim is our canvas "radius", let cy = dim + r * c.y; // and r is our circle radius, with ctx.lineTo(cx, cy); // ctx being our canvas context. // stroke segment in rainbow colours let h = (360 * t)/TAU; ctx.strokeStyle = `hsl(${h}, 100%, 50%)`; ctx.stroke(); // start a new segment at the end point ctx.beginPath(); ctx.moveTo(cx, cy);}然后我们可以将它与一些标准的 Canvas2D API 代码结合使用:const PI = Math.PI, TAU = PI * 2, edge = 200, // SIZE OF THE CANVAS, IN PIXELS dim = edge/2, r = dim * 0.9, cvs = document.getElementById('draw');// set up our canvascvs.height = cvs.width = edge;ctx = cvs.getContext('2d');ctx.lineWidth = 2;ctx.fillStyle = '#004';ctx.strokeStyle = 'black';ctx.fillRect(0, 0, edge, edge);完成所有设置后,绘制代码非常简单:// THIS DETERMINES HOW SMOOTH OF A CURVE GETS DRAWNconst segments = 32;// Peg our starting point, which we know is (r,0) away from the center.ctx.beginPath();ctx.moveTo(dim + r, dim)// Then we generate all the line segments on the pathfor (let step=TAU/segments, t=step; t<=TAU; t+=step) drawSegmentTo(t);// And because IEEE floats are imprecise, the last segment may not// actually reach our starting point. As such, make sure to draw it!ctx.lineTo(dim + r, dim);ctx.stroke();运行这将产生以下squircle:使用 jsbin,您可以玩数字:https ://jsbin.com/haxeqamilo/edit?js,output当然,您也可以采用完全不同的方式:使用一个元素创建一个 SVG 元素(因为 SVG 是 HTML5 的一部分)<path>并适当地设置宽度、高度和视图框,然后生成一个d属性和渐变颜色,但这就是绝对更挑剔。