mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-31 03:59:58 +02:00
fixed curvature
This commit is contained in:
@@ -5,17 +5,15 @@ Bézier curves are, like all "splines", interpolation functions. This means that
|
||||
The following graphs show the interpolation functions for quadratic and cubic curves, with "S" being the strength of a point's contribution to the total sum of the Bézier function. Click-and-drag to see the interpolation percentages for each curve-defining point at a specific <i>t</i> value.
|
||||
|
||||
<div class="figure">
|
||||
<graphics-element title="Quadratic interpolations" src="./lerp.js" data-degree="3">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="Cubic interpolations" src="./lerp.js" data-degree="4">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="15th degree interpolations" src="./lerp.js" data-degree="15">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="Quadratic interpolations" src="./lerp.js" data-degree="3">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="Cubic interpolations" src="./lerp.js" data-degree="4">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="15th degree interpolations" src="./lerp.js" data-degree="15">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
</div>
|
||||
|
||||
Also shown is the interpolation function for a 15<sup>th</sup> order Bézier function. As you can see, the start and end point contribute considerably more to the curve's shape than any other point in the control point set.
|
||||
|
@@ -5,17 +5,15 @@
|
||||
下のグラフは、2次ベジエ曲線や3次ベジエ曲線の補間関数を表しています。ここでSは、ベジエ関数全体に対しての、その点の寄与の大きさを示します。ある<i>t</i>において、ベジエ曲線を定義する各点の補間率がどのようになっているのか、クリックドラッグをして確かめてみてください。
|
||||
|
||||
<div class="figure">
|
||||
<graphics-element title="2次の補間" src="./lerp.js" data-degree="3">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="3次の補間" src="./lerp.js" data-degree="4">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="15次の補間" src="./lerp.js" data-degree="15">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="2次の補間" src="./lerp.js" data-degree="3">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="3次の補間" src="./lerp.js" data-degree="4">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="15次の補間" src="./lerp.js" data-degree="15">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
</div>
|
||||
|
||||
あわせて、15次ベジエ関数における補間関数も示しています。始点と終点は他の制御点と比較して、曲線の形に対してかなり大きな影響を与えていることがわかります。
|
||||
|
@@ -5,17 +5,15 @@
|
||||
下面的图形显示了二次曲线和三次曲线的差值方程,“S”代表了点对贝塞尔方程总和的贡献。点击拖动点来看看在特定的<i>t</i>值时,每个曲线定义的点的插值百分比。
|
||||
|
||||
<div class="figure">
|
||||
<graphics-element title="二次插值" src="./lerp.js" data-degree="3">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="三次插值" src="./lerp.js" data-degree="4">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="15次插值" src="./lerp.js" data-degree="15">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="二次插值" src="./lerp.js" data-degree="3">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="三次插值" src="./lerp.js" data-degree="4">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="15次插值" src="./lerp.js" data-degree="15">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0" class="slide-control">
|
||||
</graphics-element>
|
||||
</div>
|
||||
|
||||
上面有一张是15<sup>th</sup>阶的插值方程。如你所见,在所有控制点中,起点和终点对曲线形状的贡献比其他点更大些。
|
||||
|
@@ -41,6 +41,7 @@ drawCurvature(curve) {
|
||||
// and then draw it.
|
||||
ox = k * n.x;
|
||||
oy = k * n.y;
|
||||
|
||||
setStroke(`rgba(255,127,${s},0.6)`);
|
||||
line(p.x, p.y, p.x + ox, p.y + oy);
|
||||
|
||||
@@ -57,7 +58,7 @@ computeCurvature(curve, t) {
|
||||
dd = curve.dderivative(t),
|
||||
num = d.x * dd.y - d.y * dd.x,
|
||||
qdsum = d.x * d.x + d.y * d.y,
|
||||
dnm = qdsum ** 3/2;
|
||||
dnm = qdsum ** (3/2);
|
||||
|
||||
// shortcut
|
||||
if (num === 0 || dnm === 0) return 0;
|
||||
|
@@ -5,13 +5,12 @@ We can also simplify the drawing process by "sampling" the curve at certain poin
|
||||
We can do this is by saying "we want X segments", and then sampling the curve at intervals that are spaced such that we end up with the number of segments we wanted. The advantage of this method is that it's fast: instead of evaluating 100 or even 1000 curve coordinates, we can sample a much lower number and still end up with a curve that sort-of-kind-of looks good enough. The disadvantage of course is that we lose the precision of working with "the real curve", so we usually can't use the flattened for doing true intersection detection, or curvature alignment.
|
||||
|
||||
<div class="figure">
|
||||
<graphics-element title="Flattening a quadratic curve" src="./flatten.js" data-type="quadratic">
|
||||
<input type="range" min="1" max="16" step="1" value="4" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="Flattening a cubic curve" src="./flatten.js" data-type="cubic">
|
||||
<input type="range" min="1" max="24" step="1" value="8" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="Flattening a quadratic curve" src="./flatten.js" data-type="quadratic">
|
||||
<input type="range" min="1" max="16" step="1" value="4" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="Flattening a cubic curve" src="./flatten.js" data-type="cubic">
|
||||
<input type="range" min="1" max="24" step="1" value="8" class="slide-control">
|
||||
</graphics-element>
|
||||
</div>
|
||||
|
||||
Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You'll notice that for certain curvatures, a low number of segments works quite well, but for more complex curvatures (try this for the cubic curve), a higher number is required to capture the curvature changes properly.
|
||||
|
@@ -5,13 +5,12 @@
|
||||
例えば「X個の線分がほしい」場合には、分割数がそうなるようにサンプリング間隔を選び、曲線をサンプリングします。この方法の利点は速さです。曲線の座標を100個だの1000個だの計算するのではなく、ずっと少ない回数のサンプリングでも、十分きれいに見えるような曲線を作ることができるのです。欠点はもちろん、「本物の曲線」に比べて精度が損なわれてしまうことです。したがって、交点の検出や曲線の位置揃えを正しく行いたい場合には、平坦化した曲線は普通利用できません。
|
||||
|
||||
<div class="figure">
|
||||
<graphics-element title="2次ベジエ曲線の平坦化" src="./flatten.js" data-type="quadratic">
|
||||
<input type="range" min="1" max="16" step="1" value="4" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="3次ベジエ曲線の平坦化" src="./flatten.js" data-type="cubic">
|
||||
<input type="range" min="1" max="24" step="1" value="8" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="2次ベジエ曲線の平坦化" src="./flatten.js" data-type="quadratic">
|
||||
<input type="range" min="1" max="16" step="1" value="4" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="3次ベジエ曲線の平坦化" src="./flatten.js" data-type="cubic">
|
||||
<input type="range" min="1" max="24" step="1" value="8" class="slide-control">
|
||||
</graphics-element>
|
||||
</div>
|
||||
|
||||
2次ベジエ曲線も3次ベジエ曲線も、図をクリックして上下キーを押すと曲線の分割数が増減しますので、試してみてください。ある曲線では分割数が少なくてもうまくいきますが、曲線が複雑になればなるほど、曲率の変化を正確に捉えるためにはより多くの分割数が必要になることがわかります(3次ベジエ曲線で試してみてください)。
|
||||
|
@@ -5,13 +5,12 @@
|
||||
我们可以先确定“想要X个分段”,然后在间隔的地方采样曲线,得到一定数量的分段。这种方法的优点是速度很快:比起遍历100甚至1000个曲线坐标,我们可以采样比较少的点,仍然得到看起来足够好的曲线。这么做的缺点是,我们失去了“真正的曲线”的精度,因此不能用此方法来做真实的相交检测或曲率对齐。
|
||||
|
||||
<div class="figure">
|
||||
<graphics-element title="拉平一条二次曲线" src="./flatten.js" data-type="quadratic">
|
||||
<input type="range" min="1" max="16" step="1" value="4" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="拉平一条三次曲线" src="./flatten.js" data-type="cubic">
|
||||
<input type="range" min="1" max="24" step="1" value="8" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="拉平一条二次曲线" src="./flatten.js" data-type="quadratic">
|
||||
<input type="range" min="1" max="16" step="1" value="4" class="slide-control">
|
||||
</graphics-element>
|
||||
<graphics-element title="拉平一条三次曲线" src="./flatten.js" data-type="cubic">
|
||||
<input type="range" min="1" max="24" step="1" value="8" class="slide-control">
|
||||
</graphics-element>
|
||||
</div>
|
||||
|
||||
试着点击图形,并用上下键来降低二次曲线和三次曲线的分段数量。你会发现对某些曲率来说,数量少的分段也能做的很好,但对于复杂的曲率(在三次曲线上试试),足够多的分段才能很好地满足曲率的变化。
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
Binary file not shown.
After Width: | Height: | Size: 103 KiB |
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
9402
docs/index.html
9402
docs/index.html
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,186 +1,153 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-GB">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>A Primer on Bézier Curves - Rewriting the tech stack</title>
|
||||
|
||||
<base href=".." />
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>A Primer on Bézier Curves - Rewriting the tech stack</title>
|
||||
|
||||
<link rel="icon" href="images/favicon.png" type="image/png" />
|
||||
<base href="..">
|
||||
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS" href="news/rss.xml" />
|
||||
<link rel="icon" href="images/favicon.png" type="image/png" />
|
||||
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS" href="news/rss.xml">
|
||||
|
||||
|
||||
<!-- page styling -->
|
||||
<link rel="preload" href="images/paper.png" as="image" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<!-- page styling -->
|
||||
<link rel="preload" href="images/paper.png" as="image" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
|
||||
<!-- And a slew of SEO related meta elements, because being discoverable is important -->
|
||||
<meta name="description" content="Rewriting the tech stack" />
|
||||
<!-- And a slew of SEO related meta elements, because being discoverable is important -->
|
||||
<meta name="description" content="Rewriting the tech stack" />
|
||||
|
||||
<!-- opengraph information -->
|
||||
<meta property="og:title" content="Rewriting the tech stack" />
|
||||
<meta property="og:image" content="https://pomax.github.io/bezierinfo/images/og-image.png" />
|
||||
<meta property="og:type" content="text" />
|
||||
<meta property="og:url" content="https://pomax.github.io/bezierinfo/news/2020-09-18.html" />
|
||||
<meta property="og:description" content="Rewriting the tech stack" />
|
||||
<meta property="og:locale" content="en-GB" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:published_time" content="Thu Sep 17 2020 17:00:00 +00:00" />
|
||||
<meta property="og:updated_time" content="Fri Sep 25 2020 15:42:02 +00:00" />
|
||||
<meta property="og:author" content="Mike 'Pomax' Kamermans" />
|
||||
<meta property="og:section" content="Bézier Curves" />
|
||||
<meta property="og:tag" content="Bézier Curves" />
|
||||
<!-- opengraph information -->
|
||||
<meta property="og:title" content="Rewriting the tech stack" />
|
||||
<meta property="og:image" content="https://pomax.github.io/bezierinfo/images/og-image.png" />
|
||||
<meta property="og:type" content="text" />
|
||||
<meta property="og:url" content="https://pomax.github.io/bezierinfo/news/2020-09-18.html" />
|
||||
<meta property="og:description" content="Rewriting the tech stack" />
|
||||
<meta property="og:locale" content="en-GB" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:published_time" content="Thu Sep 17 2020 17:00:00 +00:00" />
|
||||
<meta property="og:updated_time" content="Fri Sep 25 2020 16:00:34 +00:00" />
|
||||
<meta property="og:author" content="Mike 'Pomax' Kamermans" />
|
||||
<meta property="og:section" content="Bézier Curves" />
|
||||
<meta property="og:tag" content="Bézier Curves" />
|
||||
|
||||
<!-- twitter card information -->
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@TheRealPomax" />
|
||||
<meta name="twitter:creator" content="@TheRealPomax" />
|
||||
<meta name="twitter:image" content="https://pomax.github.io/bezierinfo/images/og-image.png" />
|
||||
<meta name="twitter:url" content="https://pomax.github.io/bezierinfo/news/" />
|
||||
<meta name="twitter:description" content="Rewriting the tech stack" />
|
||||
<!-- twitter card information -->
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@TheRealPomax" />
|
||||
<meta name="twitter:creator" content="@TheRealPomax" />
|
||||
<meta name="twitter:image" content="https://pomax.github.io/bezierinfo/images/og-image.png" />
|
||||
<meta name="twitter:url" content="https://pomax.github.io/bezierinfo/news/" />
|
||||
<meta name="twitter:description" content="Rewriting the tech stack" />
|
||||
|
||||
<!-- my own referral/page hit tracker, because Google knows enough -->
|
||||
<script src="./js/site/referrer.js" type="module" async></script>
|
||||
|
||||
<!--
|
||||
|
||||
<!-- my own referral/page hit tracker, because Google knows enough -->
|
||||
<script src="./js/site/referrer.js" type="module" async></script>
|
||||
|
||||
<!--
|
||||
The part that makes interactive graphics work: an HTML5 <graphics-element> custom element.
|
||||
Note that we're not defering this: we just want it to kick in as soon as possible, and
|
||||
given how much HTML there is, that means this can, and thus should, kick in before the
|
||||
document is done even transferring.
|
||||
-->
|
||||
<script src="./js/custom-element/graphics-element.js" type="module" async></script>
|
||||
<link rel="stylesheet" href="./js/custom-element/graphics-element.css" />
|
||||
<script src="./js/custom-element/graphics-element.js" type="module" async></script>
|
||||
<link rel="stylesheet" href="./js/custom-element/graphics-element.css" />
|
||||
|
||||
<!-- make images lazy load much earlier -->
|
||||
<script src="./js/site/better-lazy-loading.js" type="module" async defer></script>
|
||||
</head>
|
||||
<!-- make images lazy load much earlier -->
|
||||
<script src="./js/site/better-lazy-loading.js" type="module" async defer></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="dev" style="display: none;">
|
||||
DEV PREVIEW ONLY
|
||||
<script>
|
||||
(function () {
|
||||
var loc = window.location.toString();
|
||||
if (loc.includes("localhost") || loc.includes("BezierInfo-2")) {
|
||||
var e = document.querySelector("div.dev");
|
||||
e.removeAttribute("style");
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<body>
|
||||
<div class="dev" style="display:none;">
|
||||
DEV PREVIEW ONLY
|
||||
<script>
|
||||
(function () {
|
||||
var loc = window.location.toString();
|
||||
if (loc.includes('localhost') || loc.includes('BezierInfo-2')) {
|
||||
var e = document.querySelector('div.dev');
|
||||
e.removeAttribute("style");
|
||||
}
|
||||
}());
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div class="github">
|
||||
<img src="images/ribbon.png" alt="This page on GitHub" style="border: none;" usemap="#githubmap" width="200" height="149" />
|
||||
<map name="githubmap">
|
||||
<area shape="poly" coords="30,0, 200,0, 200,114" href="http://github.com/pomax/BezierInfo-2" alt="This page on GitHub" />
|
||||
</map>
|
||||
</div>
|
||||
<div class="github">
|
||||
<img src="images/ribbon.png" alt="This page on GitHub" style="border:none;" useMap="#githubmap" width="200" height="149" />
|
||||
<map name="githubmap">
|
||||
<area shape="poly" coords="30,0, 200,0, 200,114" href="http://github.com/pomax/BezierInfo-2" alt="This page on GitHub" />
|
||||
</map>
|
||||
</div>
|
||||
|
||||
<header>
|
||||
<h1>Rewriting the tech stack</h1>
|
||||
<h5 class="post-date">Fri, 18 Sep 2020</h5>
|
||||
</header>
|
||||
|
||||
|
||||
<main>
|
||||
<!-- Because people probably want to share this article -->
|
||||
<div class="notforprint scl">
|
||||
<img src="images/icons.gif" usemap="#rhtimap" title="Share this on social media" />
|
||||
<map name="rhtimap">
|
||||
<area
|
||||
class="sclnk-rdt"
|
||||
shape="rect"
|
||||
coords="0, 0, 19, 15"
|
||||
href="https://www.reddit.com/submit?url=https://pomax.github.io/bezierinfo/news/2020-09-18.html&title==A Primer on Bézier Curves - Rewriting the tech stack&text=An update about the Primer on Bézier curves."
|
||||
alt="submit to reddit"
|
||||
title="submit to reddit"
|
||||
/>
|
||||
<area
|
||||
class="sclnk-hn"
|
||||
shape="rect"
|
||||
coords="0, 20, 19, 35"
|
||||
href="https://news.ycombinator.com/submitlink?u=https://pomax.github.io/bezierinfo/news/2020-09-18.html&t=A Primer on Bézier Curves - Rewriting the tech stack"
|
||||
alt="submit to hacker news"
|
||||
title="submit to hacker news"
|
||||
/>
|
||||
<area
|
||||
class="sclnk-twt"
|
||||
shape="rect"
|
||||
coords="0, 40, 19, 55"
|
||||
href="https://twitter.com/intent/tweet?hashtags=bezier,curves,maths&original_referer=https://pomax.github.io/bezierinfo&text=Reading “Rewriting the tech stack” by @TheRealPomax over on https://pomax.github.io/bezierinfo/news/2020-09-18.html"
|
||||
alt="tweet your read"
|
||||
title="tweet your read"
|
||||
/>
|
||||
</map>
|
||||
</div>
|
||||
<header>
|
||||
|
||||
<h1>Rewriting the tech stack</h1>
|
||||
<h5 class="post-date">Fri, 18 Sep 2020</h5>
|
||||
|
||||
<p>
|
||||
Once upon a time, I needed to draw some Bezier curves because I was trying to create a Japanese kanji composition system that turned strokes
|
||||
into outlines, and that required knowing how to offset Bezier curves and... at the time (2011, time flies) there was no good single source of
|
||||
information for Bezier curves on the web. So I made one. Sure it started small, but it turns out that if you just keep adding bits to
|
||||
something, several years later you have quite the monster, and a single HTML file becomes intractible.
|
||||
</p>
|
||||
<p>
|
||||
So, in 2016, when <a href="">React.js</a> exploded onto the scene, I rewrote the primer as a React app, and it became a lot easier to
|
||||
maintain. Like, <em>a lot</em> a lot. However, there was a downside: no JS meant no content. Sure, server-side rendering sort of existed, but
|
||||
not really, and because the Primer is hosted through github, there was no "server" to run. Plus, trying to rehydrate an app the size of the
|
||||
Primer from a giant HTML file had truly <em>dire</em> performance.
|
||||
</p>
|
||||
<p>
|
||||
So I left it a regular React app, and every time I thought "wouldn't it be nice if it was just... a web page again?" the browser landscape
|
||||
just hadn't caught up. Finally, in 2020, things are different: with a global pandemic, and some vacation time, and something random causing me
|
||||
to look up the state of HTML custom elements, everything was pointing at it being time to finally, <em>finally</em>, turn the Primer back into
|
||||
a normal web page.
|
||||
</p>
|
||||
<p>
|
||||
The new tech stack is, frankly, pretty amazing. It does some things that weren't possible even half a year before I started the rewrite, let
|
||||
alone being possible in 2016, and so because so much has changed, this post will be the first in a series of posts on how the new tech stack
|
||||
works.
|
||||
</p>
|
||||
<p>To give a bit of a teaser, some of the things I'll be writing about:</p>
|
||||
<ul>
|
||||
<li>Essentially reinventing (a limited form of) Processing.js</li>
|
||||
<li>Writing a custom build system, because I'm exhausted with Webpack and hope to never use it again.</li>
|
||||
<li>Using modern ES module code that runs in both the browser and Node.js.</li>
|
||||
<li>
|
||||
Chapter content written as easy to read and write markdown format: <a href="./news/2020-09-18.md">view this blog post's source file</a>.
|
||||
</li>
|
||||
<li>A custom <code><graphics-element></code> element that turns a <code>src="blah.js"</code> into an interactive canvas graphic...</li>
|
||||
<li>...with that same source code being read in and run by Node.js <em>on a canvas</em> to generate fallback images.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<graphics-element title="An example graphic" width="275" height="275" src="./news/example.js">
|
||||
<fallback-image>
|
||||
<span class="view-source">Scripts are disabled. Showing fallback image.</span>
|
||||
<img width="275px" height="275px" src="./images/news/2020-09-18.html/b465a1526a406578c9806a9985e2dbd0.png" loading="lazy" />
|
||||
<label>An example graphic</label>
|
||||
</fallback-image></graphics-element
|
||||
>
|
||||
</blockquote>
|
||||
</header>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
Real LaTeX code, that gets compiled into optimized SVG using <code>xelatex</code>, <code>pdfcrop</code>, <code>pdf2svg</code>, and
|
||||
<code>svgo</code>:
|
||||
</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<img class="LaTeX SVG" src="./images/news/2020-09-18.html/15225da473048d8c7b5b473b89de0b66.svg" width="401px" height="97px" loading="lazy" />
|
||||
</blockquote>
|
||||
<main>
|
||||
|
||||
<!-- Because people probably want to share this article -->
|
||||
<div class="notforprint scl">
|
||||
<img src="images/icons.gif" usemap="#rhtimap" title="Share this on social media" />
|
||||
<map name="rhtimap">
|
||||
<area class="sclnk-rdt" shape="rect" coords="0, 0, 19, 15"
|
||||
href="https://www.reddit.com/submit?url=https://pomax.github.io/bezierinfo/news/2020-09-18.html&title==A Primer on Bézier Curves - Rewriting the tech stack&text=An update about the Primer on Bézier curves."
|
||||
alt="submit to reddit" title="submit to reddit">
|
||||
<area class="sclnk-hn" shape="rect" coords="0, 20, 19, 35"
|
||||
href="https://news.ycombinator.com/submitlink?u=https://pomax.github.io/bezierinfo/news/2020-09-18.html&t=A Primer on Bézier Curves - Rewriting the tech stack"
|
||||
alt="submit to hacker news" title="submit to hacker news">
|
||||
<area class="sclnk-twt" shape="rect" coords="0, 40, 19, 55"
|
||||
href="https://twitter.com/intent/tweet?hashtags=bezier,curves,maths&original_referer=https://pomax.github.io/bezierinfo&text=Reading “Rewriting the tech stack” by @TheRealPomax over on https://pomax.github.io/bezierinfo/news/2020-09-18.html"
|
||||
alt="tweet your read" title="tweet your read">
|
||||
</map>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<li>"Lazy loaded everything", so that you get what you need, only when or even just before you need it.</li>
|
||||
<li>Localized content based on a simple filenaming scheme.</li>
|
||||
<li>Nicely formatted HTML, CSS, and JS thanks to <code>prettier</code>.</li>
|
||||
<li>with some code formatting so that there are line numbers without needing JS:</li>
|
||||
</ul>
|
||||
|
||||
<p>Once upon a time, I needed to draw some Bezier curves because I was trying to create a Japanese kanji composition system that turned strokes into outlines, and that required knowing how to offset Bezier curves and... at the time (2011, time flies) there was no good single source of information for Bezier curves on the web. So I made one. Sure it started small, but it turns out that if you just keep adding bits to something, several years later you have quite the monster, and a single HTML file becomes intractible.</p>
|
||||
<p>So, in 2016, when <a href="">React.js</a> exploded onto the scene, I rewrote the primer as a React app, and it became a lot easier to maintain. Like, <em>a lot</em> a lot. However, there was a downside: no JS meant no content. Sure, server-side rendering sort of existed, but not really, and because the Primer is hosted through github, there was no "server" to run. Plus, trying to rehydrate an app the size of the Primer from a giant HTML file had truly <em>dire</em> performance.</p>
|
||||
<p>So I left it a regular React app, and every time I thought "wouldn't it be nice if it was just... a web page again?" the browser landscape just hadn't caught up. Finally, in 2020, things are different: with a global pandemic, and some vacation time, and something random causing me to look up the state of HTML custom elements, everything was pointing at it being time to finally, <em>finally</em>, turn the Primer back into a normal web page.</p>
|
||||
<p>The new tech stack is, frankly, pretty amazing. It does some things that weren't possible even half a year before I started the rewrite, let alone being possible in 2016, and so because so much has changed, this post will be the first in a series of posts on how the new tech stack works.</p>
|
||||
<p>To give a bit of a teaser, some of the things I'll be writing about:</p>
|
||||
<ul>
|
||||
<li>Essentially reinventing (a limited form of) Processing.js</li>
|
||||
<li>Writing a custom build system, because I'm exhausted with Webpack and hope to never use it again.</li>
|
||||
<li>Using modern ES module code that runs in both the browser and Node.js.</li>
|
||||
<li>Chapter content written as easy to read and write markdown format: <a href="./news/2020-09-18.md">view this blog post's source file</a>.</li>
|
||||
<li>A custom <code><graphics-element></code> element that turns a <code>src="blah.js"</code> into an interactive canvas graphic...</li>
|
||||
<li>...with that same source code being read in and run by Node.js <em>on a canvas</em> to generate fallback images.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<graphics-element title="An example graphic" width="275" height="275" src="./news/example.js" >
|
||||
<fallback-image>
|
||||
<span class="view-source">Scripts are disabled. Showing fallback image.</span>
|
||||
<img width="275px" height="275px" src="./images/news/2020-09-18.html/b465a1526a406578c9806a9985e2dbd0.png" loading="lazy">
|
||||
<label>An example graphic</label>
|
||||
</fallback-image></graphics-element>
|
||||
</blockquote>
|
||||
|
||||
<table class="code">
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td rowspan="13">
|
||||
<textarea disabled rows="13" role="doc-example">
|
||||
let curve;
|
||||
<ul>
|
||||
<li>Real LaTeX code, that gets compiled into optimized SVG using <code>xelatex</code>, <code>pdfcrop</code>, <code>pdf2svg</code>, and <code>svgo</code>:</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<img class="LaTeX SVG" src="./images/news/2020-09-18.html/15225da473048d8c7b5b473b89de0b66.svg" width="401px" height="97px" loading="lazy">
|
||||
</blockquote>
|
||||
|
||||
<ul>
|
||||
<li>"Lazy loaded everything", so that you get what you need, only when or even just before you need it.</li>
|
||||
<li>Localized content based on a simple filenaming scheme.</li>
|
||||
<li>Nicely formatted HTML, CSS, and JS thanks to <code>prettier</code>.</li>
|
||||
<li>with some code formatting so that there are line numbers without needing JS:</li>
|
||||
</ul>
|
||||
|
||||
<table class="code"><tr><td>1</td><td rowspan="13">
|
||||
<textarea disabled rows="13" role="doc-example">let curve;
|
||||
|
||||
setup() {
|
||||
curve = Bezier.defaultCubic();
|
||||
@@ -192,71 +159,47 @@ draw() {
|
||||
clear(`lightblue`);
|
||||
curve.drawCurve();
|
||||
curve.drawPoints();
|
||||
}</textarea
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>7</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>8</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>9</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>10</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>11</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>12</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>13</td>
|
||||
</tr>
|
||||
</table>
|
||||
}</textarea>
|
||||
</td></tr>
|
||||
<tr><td>2</td></tr>
|
||||
<tr><td>3</td></tr>
|
||||
<tr><td>4</td></tr>
|
||||
<tr><td>5</td></tr>
|
||||
<tr><td>6</td></tr>
|
||||
<tr><td>7</td></tr>
|
||||
<tr><td>8</td></tr>
|
||||
<tr><td>9</td></tr>
|
||||
<tr><td>10</td></tr>
|
||||
<tr><td>11</td></tr>
|
||||
<tr><td>12</td></tr>
|
||||
<tr><td>13</td></tr></table>
|
||||
|
||||
<ul>
|
||||
<li>Responsive CSS, so the content intelligently reflows where possible.</li>
|
||||
<li>A "Live build" setup for working on the content and code.</li>
|
||||
<li>Automatic link-checking to make sure none of the links in the Primer lead you to a 404.</li>
|
||||
<li>This "news" section, so that I can write posts to go along with new sections getting added, or notable changes being made.</li>
|
||||
</ul>
|
||||
<p>It's going to take me a while to detail the entire tech stack, but ultimately what matters is that you get a Primer that is a normal "vanilla" HTML, CSS, and JS page again, that "just works" even with JS disabled.</p>
|
||||
<p>Enjoy <a href="https://pomax.github.io/bezierinfo">The new Primer on Bézier Curves</a>, and if you find any problems, <a href="https://github.com/Pomax/BezierInfo-2/issues">you know where to go</a>.</p>
|
||||
<p>See you in the next post!</p>
|
||||
<p>— Pomax</p>
|
||||
|
||||
<ul>
|
||||
<li>Responsive CSS, so the content intelligently reflows where possible.</li>
|
||||
<li>A "Live build" setup for working on the content and code.</li>
|
||||
<li>Automatic link-checking to make sure none of the links in the Primer lead you to a 404.</li>
|
||||
<li>This "news" section, so that I can write posts to go along with new sections getting added, or notable changes being made.</li>
|
||||
</ul>
|
||||
<p>
|
||||
It's going to take me a while to detail the entire tech stack, but ultimately what matters is that you get a Primer that is a normal "vanilla"
|
||||
HTML, CSS, and JS page again, that "just works" even with JS disabled.
|
||||
</p>
|
||||
<p>
|
||||
Enjoy <a href="https://pomax.github.io/bezierinfo">The new Primer on Bézier Curves</a>, and if you find any problems,
|
||||
<a href="https://github.com/Pomax/BezierInfo-2/issues">you know where to go</a>.
|
||||
</p>
|
||||
<p>See you in the next post!</p>
|
||||
<p>— Pomax</p>
|
||||
</main>
|
||||
|
||||
<hr />
|
||||
</main>
|
||||
|
||||
<footer class="copyright">This post is a news entry for the <a href="https://pomax.github.io/bezierinfo/">Primer on Bézier Curves</a></footer>
|
||||
<hr>
|
||||
|
||||
<!-- fix firefox's scroll position algorithm. Due to how it works, it cannot be async/defer -->
|
||||
<script src="./js/site/fix-scroll.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
<footer class="copyright">
|
||||
|
||||
This post is a news entry for the <a href="https://pomax.github.io/bezierinfo/">Primer on Bézier Curves</a>
|
||||
|
||||
</footer>
|
||||
|
||||
|
||||
<!-- fix firefox's scroll position algorithm. Due to how it works, it cannot be async/defer -->
|
||||
<script src="./js/site/fix-scroll.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@@ -1,108 +1,129 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-GB">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>A Primer on Bézier Curves - News</title>
|
||||
|
||||
<base href=".." />
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>A Primer on Bézier Curves - News</title>
|
||||
|
||||
<link rel="icon" href="images/favicon.png" type="image/png" />
|
||||
<base href="..">
|
||||
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS" href="news/rss.xml" />
|
||||
<link rel="icon" href="images/favicon.png" type="image/png" />
|
||||
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS" href="news/rss.xml">
|
||||
|
||||
|
||||
<!-- page styling -->
|
||||
<link rel="preload" href="images/paper.png" as="image" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<!-- page styling -->
|
||||
<link rel="preload" href="images/paper.png" as="image" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
|
||||
<!-- And a slew of SEO related meta elements, because being discoverable is important -->
|
||||
<meta name="description" content="" />
|
||||
<!-- And a slew of SEO related meta elements, because being discoverable is important -->
|
||||
<meta name="description" content="" />
|
||||
|
||||
<!-- opengraph information -->
|
||||
<meta property="og:title" content="" />
|
||||
<meta property="og:image" content="https://pomax.github.io/bezierinfo/images/og-image.png" />
|
||||
<meta property="og:type" content="text" />
|
||||
<meta property="og:url" content="https://pomax.github.io/bezierinfo" />
|
||||
<meta property="og:description" content="" />
|
||||
<meta property="og:locale" content="en-GB" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:published_time" content="Fri Sep 25 2020 15:42:02 GMT-0700 (Pacific Daylight Time)" />
|
||||
<meta property="og:updated_time" content="" />
|
||||
<meta property="og:author" content="Mike 'Pomax' Kamermans" />
|
||||
<meta property="og:section" content="Bézier Curves" />
|
||||
<meta property="og:tag" content="Bézier Curves" />
|
||||
<!-- opengraph information -->
|
||||
<meta property="og:title" content="" />
|
||||
<meta property="og:image" content="https://pomax.github.io/bezierinfo/images/og-image.png" />
|
||||
<meta property="og:type" content="text" />
|
||||
<meta property="og:url" content="https://pomax.github.io/bezierinfo" />
|
||||
<meta property="og:description" content="" />
|
||||
<meta property="og:locale" content="en-GB" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:published_time" content="Fri Sep 25 2020 16:00:34 GMT-0700 (Pacific Daylight Time)" />
|
||||
<meta property="og:updated_time" content="" />
|
||||
<meta property="og:author" content="Mike 'Pomax' Kamermans" />
|
||||
<meta property="og:section" content="Bézier Curves" />
|
||||
<meta property="og:tag" content="Bézier Curves" />
|
||||
|
||||
<!-- twitter card information -->
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@TheRealPomax" />
|
||||
<meta name="twitter:creator" content="@TheRealPomax" />
|
||||
<meta name="twitter:image" content="https://pomax.github.io/bezierinfo/images/og-image.png" />
|
||||
<meta name="twitter:url" content="https://pomax.github.io/bezierinfo" />
|
||||
<meta name="twitter:description" content="" />
|
||||
<!-- twitter card information -->
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@TheRealPomax" />
|
||||
<meta name="twitter:creator" content="@TheRealPomax" />
|
||||
<meta name="twitter:image" content="https://pomax.github.io/bezierinfo/images/og-image.png" />
|
||||
<meta name="twitter:url" content="https://pomax.github.io/bezierinfo" />
|
||||
<meta name="twitter:description" content="" />
|
||||
|
||||
<!-- my own referral/page hit tracker, because Google knows enough -->
|
||||
<script src="./js/site/referrer.js" type="module" async></script>
|
||||
|
||||
<!--
|
||||
|
||||
<!-- my own referral/page hit tracker, because Google knows enough -->
|
||||
<script src="./js/site/referrer.js" type="module" async></script>
|
||||
|
||||
<!--
|
||||
The part that makes interactive graphics work: an HTML5 <graphics-element> custom element.
|
||||
Note that we're not defering this: we just want it to kick in as soon as possible, and
|
||||
given how much HTML there is, that means this can, and thus should, kick in before the
|
||||
document is done even transferring.
|
||||
-->
|
||||
<script src="./js/custom-element/graphics-element.js" type="module" async></script>
|
||||
<link rel="stylesheet" href="./js/custom-element/graphics-element.css" />
|
||||
<script src="./js/custom-element/graphics-element.js" type="module" async></script>
|
||||
<link rel="stylesheet" href="./js/custom-element/graphics-element.css" />
|
||||
|
||||
<!-- make images lazy load much earlier -->
|
||||
<script src="./js/site/better-lazy-loading.js" type="module" async defer></script>
|
||||
</head>
|
||||
<!-- make images lazy load much earlier -->
|
||||
<script src="./js/site/better-lazy-loading.js" type="module" async defer></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="dev" style="display: none;">
|
||||
DEV PREVIEW ONLY
|
||||
<script>
|
||||
(function () {
|
||||
var loc = window.location.toString();
|
||||
if (loc.includes("localhost") || loc.includes("BezierInfo-2")) {
|
||||
var e = document.querySelector("div.dev");
|
||||
e.removeAttribute("style");
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<body>
|
||||
<div class="dev" style="display:none;">
|
||||
DEV PREVIEW ONLY
|
||||
<script>
|
||||
(function () {
|
||||
var loc = window.location.toString();
|
||||
if (loc.includes('localhost') || loc.includes('BezierInfo-2')) {
|
||||
var e = document.querySelector('div.dev');
|
||||
e.removeAttribute("style");
|
||||
}
|
||||
}());
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div class="github">
|
||||
<img src="images/ribbon.png" alt="This page on GitHub" style="border: none;" usemap="#githubmap" width="200" height="149" />
|
||||
<map name="githubmap">
|
||||
<area shape="poly" coords="30,0, 200,0, 200,114" href="http://github.com/pomax/BezierInfo-2" alt="This page on GitHub" />
|
||||
</map>
|
||||
</div>
|
||||
<div class="github">
|
||||
<img src="images/ribbon.png" alt="This page on GitHub" style="border:none;" useMap="#githubmap" width="200" height="149" />
|
||||
<map name="githubmap">
|
||||
<area shape="poly" coords="30,0, 200,0, 200,114" href="http://github.com/pomax/BezierInfo-2" alt="This page on GitHub" />
|
||||
</map>
|
||||
</div>
|
||||
|
||||
<header>
|
||||
<h1>News posts</h1>
|
||||
</header>
|
||||
|
||||
|
||||
<main>
|
||||
<p>
|
||||
Every now and then the Primer gets updated - these posts chronicle the evolution of the site, and hopefully offer interesting information not
|
||||
just about the process of maintaining a resource like this, but also neat tech tricks, implementation approaches, maths that didn't make it
|
||||
into the primer itself, etc.
|
||||
</p>
|
||||
<header>
|
||||
|
||||
<h1>News posts</h1>
|
||||
|
||||
<p>
|
||||
This section is still very new, so for the moment there aren't all that many posts up yet, but there's a series of posts planned already, and
|
||||
if you're the kind of person who likes to keep tabs on updates by using RSS: good news, <a href="news/rss.xml">have an RSS link!</a>.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<ul>
|
||||
<li><a href="news/2020-09-18.html">Rewriting the tech stack</a> (Fri, 18 Sep 2020)</li>
|
||||
</ul>
|
||||
</main>
|
||||
<main>
|
||||
|
||||
<p>
|
||||
Every now and then the Primer gets updated - these posts chronicle the evolution of the site,
|
||||
and hopefully offer interesting information not just about the process of maintaining a resource
|
||||
like this, but also neat tech tricks, implementation approaches, maths that didn't make it into
|
||||
the primer itself, etc.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<p>
|
||||
This section is still very new, so for the moment there aren't all that many posts up yet, but
|
||||
there's a series of posts planned already, and if you're the kind of person who likes to keep
|
||||
tabs on updates by using RSS: good news, <a href="news/rss.xml">have an RSS link!</a>.
|
||||
</p>
|
||||
|
||||
<footer class="copyright">This post is a news entry for the <a href="..">Primer on Bézier Curves</a></footer>
|
||||
<ul>
|
||||
<li><a href="news/2020-09-18.html">Rewriting the tech stack</a> (Fri, 18 Sep 2020) </li>
|
||||
|
||||
<!-- fix firefox's scroll position algorithm. Due to how it works, it cannot be async/defer -->
|
||||
<script src="./js/site/fix-scroll.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
|
||||
<hr>
|
||||
|
||||
<footer class="copyright">
|
||||
|
||||
This post is a news entry for the <a href="..">Primer on Bézier Curves</a>
|
||||
|
||||
</footer>
|
||||
|
||||
|
||||
<!-- fix firefox's scroll position algorithm. Due to how it works, it cannot be async/defer -->
|
||||
<script src="./js/site/fix-scroll.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@@ -6,7 +6,7 @@
|
||||
<atom:link href="https://pomax.github.io/bezierinfo" rel="self"></atom:link>
|
||||
<description>News updates for the <a href="https://pomax.github.io/bezierinfo">primer on Bézier Curves</a> by Pomax</description>
|
||||
<language>en-GB</language>
|
||||
<lastBuildDate>Fri Sep 25 2020 15:42:02 +00:00</lastBuildDate>
|
||||
<lastBuildDate>Fri Sep 25 2020 16:00:34 +00:00</lastBuildDate>
|
||||
<image>
|
||||
<url>https://pomax.github.io/bezierinfo/images/og-image.png</url>
|
||||
<title>A Primer on Bézier Curves</title>
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user