1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-01 06:20:52 +02:00

let's deploy this.

This commit is contained in:
Pomax
2016-01-12 18:55:20 -08:00
parent 8db94a3f50
commit 419fe35edf
20 changed files with 251 additions and 275 deletions

View File

@@ -34,7 +34,8 @@ var Article = React.createClass({
generateNavItem: function(section, entry) {
var name = section.props.name;
return <li key={name} data-number={entry}><a href={'#' + name}>{ section.props.title }</a></li>;
var title = section.props.title;
return <li key={name} data-number={entry}><a href={'#' + name}>{ title }</a></li>;
},
render: function() {

View File

@@ -1,6 +1,8 @@
var React = require("react");
var chroma = require("chroma-js");
var Bezier = require("bezier-js");
// event coordinate fix
var fix = function(e) {
e = e || window.event;
var target = e.target || e.srcElement,
@@ -9,11 +11,7 @@ var fix = function(e) {
e.offsetY = e.clientY - rect.top;
};
var Bezier = require("bezier-js");
var Graphic = React.createClass({
Paper: false,
defaultWidth: 275,
@@ -62,7 +60,7 @@ var Graphic = React.createClass({
onKeyUp={this.onKeyUp}
onKeyDown={this.onKeyDown}
onKeyPress={this.onKeyPress}
/>
/>
<figcaption>{this.props.title} {this.props.children}</figcaption>
</figure>
);

View File

@@ -9,7 +9,7 @@ var Ribbon = React.createClass({
render: function() {
return (<div className="ribbon">
<img src="images/ribbon.png" alt="This page on GitHub" border={0} useMap={"#githubmap"} />
<img src="images/ribbon.png" alt="This page on GitHub" border={0} useMap={"#githubmap"} width="200px" height="149px"/>
<map name="githubmap">
<area shape="poly" coords="30,0, 200,0, 200,114" href={this.state.href} alt="This page on GitHub"/>
</map>

View File

@@ -0,0 +1,33 @@
var React = require("react");
var noop = require("../../lib/noop");
module.exports = function(Component) {
var options = Component.keyHandlingOptions,
propName = options.propName || "",
values = options.values || {},
controller = options.controller || noop,
getDefaultProps = Component.getDefaultProps;
return React.createClass({
values: values,
getDefaultProps: getDefaultProps,
onKeyDown: function(event, api) {
var v = this.values[event.keyCode];
if(v) {
event.preventDefault();
if (typeof v === "function") {
v(api);
} else {
api[propName] += v;
controller(api);
}
}
},
render: function() {
return <Component {...this.props} onKeyDown={this.onKeyDown} />;
}
});
};

View File

@@ -1,10 +1,25 @@
var React = require("react");
var Graphic = require("../../Graphic.jsx");
var SectionHeader = require("../../SectionHeader.jsx");
var keyHandling = require("../../decorators/keyhandling-decorator.jsx");
var atan2 = Math.atan2, PI = Math.PI, TAU = 2*PI, cos = Math.cos, sin = Math.sin;
var Introduction = React.createClass({
statics: {
keyHandlingOptions: {
propName: "error",
values: {
"38": 0.1, // up arrow
"40": -0.1 // down arrow
},
controller: function(api) {
if (api.error < 0.1) {
api.error = 0.1;
}
}
}
},
getDefaultProps: function() {
return {
title: "Approximating Bézier curves with circular arcs"
@@ -27,22 +42,6 @@ var Introduction = React.createClass({
api.error = 0.5;
},
values: {
"38": 0.1, // up arrow
"40": -0.1 // down arrow
},
onKeyDown: function(e, api) {
var v = this.values[e.keyCode];
if(v) {
e.preventDefault();
api.error += v;
if (api.error < 0.1) {
api.error = 0.1;
}
}
},
getCCenter: function(api, p1, p2, p3) {
// deltas
var dx1 = (p2.x - p1.x),
@@ -237,7 +236,7 @@ var Introduction = React.createClass({
interactive, and you can use your up and down cursor keys keys to increase or decrease the error threshold,
to see what the effect of a smaller or larger error threshold is.</p>
<Graphic preset="simple" title="Arc approximation of a Bézier curve" setup={this.setupCubic} draw={this.drawSingleArc} onKeyDown={this.onKeyDown} />
<Graphic preset="simple" title="Arc approximation of a Bézier curve" setup={this.setupCubic} draw={this.drawSingleArc} onKeyDown={this.props.onKeyDown} />
<p>With that in place, all that's left now is to "restart" the procedure by treating the found arc's
end point as the new to-be-determined arc's starting point, and using points further down the curve. We
@@ -246,7 +245,7 @@ var Introduction = React.createClass({
so you can see how picking a different threshold changes the number of arcs that are necessary to
reasonably approximate a curve:</p>
<Graphic preset="simple" title="Arc approximation of a Bézier curve" setup={this.setupCubic} draw={this.drawArcs} onKeyDown={this.onKeyDown} />
<Graphic preset="simple" title="Arc approximation of a Bézier curve" setup={this.setupCubic} draw={this.drawArcs} onKeyDown={this.props.onKeyDown} />
<p>So... what is this good for? Obviously, If you're working with technologies that can't do curves,
but can do lines and circles, then the answer is pretty straight-forward, but what else? There are
@@ -265,4 +264,4 @@ var Introduction = React.createClass({
}
});
module.exports = Introduction;
module.exports = keyHandling(Introduction);

View File

@@ -1,8 +1,24 @@
var React = require("react");
var Graphic = require("../../Graphic.jsx");
var SectionHeader = require("../../SectionHeader.jsx");
var keyHandling = require("../../decorators/keyhandling-decorator.jsx");
var ArclengthApprox = React.createClass({
statics: {
keyHandlingOptions: {
propName: "steps",
values: {
"38": 1, // up arrow
"40": -1 // down arrow
},
controller: function(api) {
if (api.steps < 1) {
api.steps = 1;
}
}
}
},
getDefaultProps: function() {
return {
title: "Approximated arc length"
@@ -51,23 +67,6 @@ var ArclengthApprox = React.createClass({
api.text("Approximate length, "+api.steps+" steps: "+alen+" (true: "+len+")", {x:10, y: 15});
},
values: {
"38": 1, // up arrow
"40": -1 // down arrow
},
onKeyDown: function(e, api) {
var v = this.values[e.keyCode];
if(v) {
e.preventDefault();
api.steps += v;
if (api.steps < 1) {
api.steps = 1;
}
console.log(api.steps);
}
},
render: function() {
return (
<section>
@@ -81,8 +80,8 @@ var ArclengthApprox = React.createClass({
<p>If we combine the work done in the previous sections on curve flattening and arc length computation, we can
implement these with minimal effort:</p>
<Graphic preset="twopanel" title="Approximate quadratic curve arc length" setup={this.setupQuadratic} draw={this.draw} onKeyDown={this.onKeyDown} />
<Graphic preset="twopanel" title="Approximate cubic curve arc length" setup={this.setupCubic} draw={this.draw} onKeyDown={this.onKeyDown} />
<Graphic preset="twopanel" title="Approximate quadratic curve arc length" setup={this.setupQuadratic} draw={this.draw} onKeyDown={this.props.onKeyDown} />
<Graphic preset="twopanel" title="Approximate cubic curve arc length" setup={this.setupCubic} draw={this.draw} onKeyDown={this.props.onKeyDown} />
<p>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 may notice that the error in length is actually pretty significant, even if
@@ -94,87 +93,4 @@ var ArclengthApprox = React.createClass({
}
});
module.exports = ArclengthApprox;
/*
void setupCurve() {
setupDefaultQuadratic();
offsetting();
offset = 16;
}
void drawCurve(BezierCurve curve) {
additionals();
curve.draw();
nextPanel();
stroke(0);
float x = curve.getXValue(0),
y = curve.getYValue(0),
x2, y2, step = 1/offset, t,
length=0;
for(int i=1; i<=offset; i++) {
t = i*step;
x2 = curve.getXValue(t);
y2 = curve.getYValue(t);
line(x,y,x2,y2);
length += dist(x,y,x2,y2);
x = x2;
y = y2;
}
float arclength = curve.getCurveLength();
float error = 100 * (arclength - length) / arclength;
length = nfc(length, 3, 3);
arclength = nfc(arclength, 3, 3);
error = nfc(error, 3, 3);
if(error.indexOf(".")===0) { error = "0" + error; }
fill(0);
text("Approximate arc length based on "+offset+" segments: " + length, -dim/4, dim-20);
text("True length: " + arclength + ", error: " + error + "%", -dim/4, dim-5);
}</textarea>
void setupCurve() {
setupDefaultCubic();
offsetting();
offset = 24;
}
void drawCurve(BezierCurve curve) {
additionals();
curve.draw();
nextPanel();
stroke(0);
float x = curve.getXValue(0),
y = curve.getYValue(0),
x2, y2, step = 1/offset, t,
length=0;
for(int i=1; i<=offset; i++) {
t = i*step;
x2 = curve.getXValue(t);
y2 = curve.getYValue(t);
line(x,y,x2,y2);
length += dist(x,y,x2,y2);
x = x2;
y = y2;
}
float arclength = curve.getCurveLength();
float error = 100 * (arclength - length) / arclength;
length = nfc(length, 3, 3);
arclength = nfc(arclength, 3, 3);
error = nfc(error, 3, 3);
if(error.indexOf(".")===0) { error = "0" + error; }
fill(0);
text("Approximate arc length based on "+offset+" segments: " + length, -dim/4, dim-20);
text("True length: " + arclength + ", error: " + error + "%", -dim/4, dim-5);
}</textarea>
*/
module.exports = keyHandling(ArclengthApprox);

View File

@@ -1,8 +1,19 @@
var React = require("react");
var Graphic = require("../../Graphic.jsx");
var SectionHeader = require("../../SectionHeader.jsx");
var keyHandling = require("../../decorators/keyhandling-decorator.jsx");
var CatmullRomMoulding = React.createClass({
statics: {
keyHandlingOptions: {
propName: "distance",
values: {
"38": 1, // up arrow
"40": -1 // down arrow
}
}
},
getDefaultProps: function() {
return {
title: "Creating a Catmull-Rom curve from three points"
@@ -19,16 +30,6 @@ var CatmullRomMoulding = React.createClass({
api.distance = 0;
},
onKeyDown: function(evt, api) {
if (evt.key === "ArrowUp") {
evt.preventDefault();
api.distance += 1;
} else if (evt.key === "ArrowDown") {
evt.preventDefault();
api.distance -= 1;
}
},
convert: function(p1, p2, p3, p4) {
var t = 0.5;
return [
@@ -167,7 +168,7 @@ var CatmullRomMoulding = React.createClass({
we want to do this? Because the line p0--p2 acts as departure tangent at p1, and the line p2--p4 acts as
arrival tangent at p3. Play around with the graphic a bit to get an idea of what all of that meant:</p>
<Graphic preset="threepanel" title="Catmull-Rom curve fitting" setup={this.setup} draw={this.draw} onKeyDown={this.onKeyDown}/>
<Graphic preset="threepanel" title="Catmull-Rom curve fitting" setup={this.setup} draw={this.draw} onKeyDown={this.props.onKeyDown}/>
<p>As should be obvious by now, Catmull-Rom curves are great for "fitting a curvature to some points", but if we want
to convert that curve to Bézier form we're going to end up with a lot of separate (but visually joined) Bézier curves.
@@ -178,4 +179,4 @@ var CatmullRomMoulding = React.createClass({
}
});
module.exports = CatmullRomMoulding;
module.exports = keyHandling(CatmullRomMoulding);

View File

@@ -1,30 +1,30 @@
var React = require("react");
var Graphic = require("../../Graphic.jsx");
var SectionHeader = require("../../SectionHeader.jsx");
var keyHandling = require("../../decorators/keyhandling-decorator.jsx");
var Explanation = React.createClass({
statics: {
keyHandlingOptions: {
propName: "step",
values: {
"38": 0.1, // up arrow
"40": -0.1 // down arrow
},
controller: function(api) {
if (api.step < 0.1) {
api.step = 0.1;
}
}
}
},
getDefaultProps: function() {
return {
title: "The mathematics of Bézier curves"
};
},
values: {
"38": 0.1, // up arrow
"40": -0.1 // down arrow
},
onKeyDown: function(e, api) {
var v = this.values[e.keyCode];
if(v) {
e.preventDefault();
api.step += v;
if (api.step < 0.1) {
api.step = 0.1;
}
}
},
setup: function(api) {
api.step = 5;
},
@@ -126,7 +126,7 @@ var Explanation = React.createClass({
radius 1 around the origin (0,0). If we plot it for <i>t</i> from 0 to 5, we get this (use
your up and down cursor keys to change the plot end value):</p>
<Graphic preset="empty" title="A (partial) circle: x=sin(t), y=cos(t)" static={true} setup={this.setup} draw={this.draw} onKeyDown={this.onKeyDown}/>
<Graphic preset="empty" title="A (partial) circle: x=sin(t), y=cos(t)" static={true} setup={this.setup} draw={this.draw} onKeyDown={this.props.onKeyDown}/>
<p>Bézier curves are (one in many classes of) parametric functions, and are characterised
by using the same base function for all its dimensions. Unlike the above example,
@@ -277,4 +277,4 @@ function Bezier(3,t):
}
});
module.exports = Explanation;
module.exports = keyHandling(Explanation);

View File

@@ -1,8 +1,24 @@
var React = require("react");
var Graphic = require("../../Graphic.jsx");
var SectionHeader = require("../../SectionHeader.jsx");
var keyHandling = require("../../decorators/keyhandling-decorator.jsx");
var Flattening = React.createClass({
statics: {
keyHandlingOptions: {
propName: "steps",
values: {
"38": 1, // up arrow
"40": -1 // down arrow
},
controller: function(api) {
if (api.steps < 1) {
api.steps = 1;
}
}
}
},
getDefaultProps: function() {
return {
title: "Simplified drawing"
@@ -106,4 +122,4 @@ var Flattening = React.createClass({
}
});
module.exports = Flattening;
module.exports = keyHandling(Flattening);

View File

@@ -1,8 +1,19 @@
var React = require("react");
var Graphic = require("../../Graphic.jsx");
var SectionHeader = require("../../SectionHeader.jsx");
var keyHandling = require("../../decorators/keyhandling-decorator.jsx");
var GraduatedOffsetting = React.createClass({
statics: {
keyHandlingOptions: {
propName: "distance",
values: {
"38": 1, // up arrow
"40": -1 // down arrow
}
}
},
getDefaultProps: function() {
return {
title: "Graduated curve offsetting"
@@ -35,19 +46,6 @@ var GraduatedOffsetting = React.createClass({
outline.curves.forEach(c => api.drawCurve(c));
},
values: {
"38": 1, // up arrow
"40": -1 // down arrow
},
onKeyDown: function(e, api) {
var v = this.values[e.keyCode];
if(v) {
e.preventDefault();
api.distance += v;
}
},
render: function() {
return (
<section>
@@ -82,12 +80,11 @@ var GraduatedOffsetting = React.createClass({
will give us the following result (these have with a starting width of 0, and an end width
of 40 pixels, but can be controlled with your up and down cursor keys):</p>
<Graphic preset="simple" title="Offsetting a quadratic Bézier curve" setup={this.setupQuadratic} draw={this.draw} onKeyDown={this.onKeyDown}/>
<Graphic preset="simple" title="Offsetting a cubic Bézier curve" setup={this.setupCubic} draw={this.draw} onKeyDown={this.onKeyDown}/>
<Graphic preset="simple" title="Offsetting a quadratic Bézier curve" setup={this.setupQuadratic} draw={this.draw} onKeyDown={this.props.onKeyDown}/>
<Graphic preset="simple" title="Offsetting a cubic Bézier curve" setup={this.setupCubic} draw={this.draw} onKeyDown={this.props.onKeyDown}/>
</section>
);
}
});
module.exports = GraduatedOffsetting;
module.exports = keyHandling(GraduatedOffsetting);

View File

@@ -1,8 +1,19 @@
var React = require("react");
var Graphic = require("../../Graphic.jsx");
var SectionHeader = require("../../SectionHeader.jsx");
var keyHandling = require("../../decorators/keyhandling-decorator.jsx");
var Offsetting = React.createClass({
statics: {
keyHandlingOptions: {
propName: "distance",
values: {
"38": 1, // up arrow
"40": -1 // down arrow
}
}
},
getDefaultProps: function() {
return {
title: "Curve offsetting"
@@ -56,19 +67,6 @@ var Offsetting = React.createClass({
api.drawCircle(last.points[3] || last.points[2],1);
},
values: {
"38": 1, // up arrow
"40": -1 // down arrow
},
onKeyDown: function(e, api) {
var v = this.values[e.keyCode];
if(v) {
e.preventDefault();
api.distance += v;
}
},
render: function() {
return (
<section>
@@ -183,8 +181,8 @@ var Offsetting = React.createClass({
curves, no reduction is necessary, but the more twisty the curve gets, the more the curve needs to be reduced
in order to get segments that can safely be scaled.</p>
<Graphic preset="simple" title="Offsetting a quadratic Bézier curve" setup={this.setupQuadratic} draw={this.draw} onKeyDown={this.onKeyDown} />
<Graphic preset="simple" title="Offsetting a cubic Bézier curve" setup={this.setupCubic} draw={this.draw} onKeyDown={this.onKeyDown} />
<Graphic preset="simple" title="Offsetting a quadratic Bézier curve" setup={this.setupQuadratic} draw={this.draw} onKeyDown={this.props.onKeyDown} />
<Graphic preset="simple" title="Offsetting a cubic Bézier curve" setup={this.setupCubic} draw={this.draw} onKeyDown={this.props.onKeyDown} />
<p>You may notice that this may still lead to small 'jumps' in the sub-curves when moving the
curve around. This is caused by the fact that we're still performing a naive form of offsetting,
@@ -196,4 +194,4 @@ var Offsetting = React.createClass({
}
});
module.exports = Offsetting;
module.exports = keyHandling(Offsetting);

View File

@@ -47,15 +47,19 @@ var Preface = React.createClass({
<p>So, what if you need to program them yourself? What are the pitfalls? How do you draw them?
What are the bounding boxes, how do you determine intersections, how can you extrude a curve,
in short: how do you do everything that you might want when you do with these curves? That's
what this page is for. Prepare to be mathed.</p>
what this page is for. Prepare to be mathed!</p>
<div>
<h2>All Bézier graphics are interactive.</h2>
<p>—Pomax (or in the tweetworld, <a href="https://twitter.com/TheRealPomax">@TheRealPomax</a>)</p>
<p>This page uses interactive examples, as well as "real" maths (in LaTeX form) which
is typeset using the most excellent <a href="http://MathJax.org">MathJax</a> library.
This page is still in rewriting, but once done, all examples will also have a "view source"
option, which lets you see how things were implemented using the Bezier.js library.</p>
<div className="note">
<h2>Note: All Bézier graphics are interactive.</h2>
<p>This page uses interactive examples, relying heavily on <a href="http://pomax.github.io/bezierjs/">Bezier.js</a>,
as well as "real" maths (in LaTeX form) which is typeset using the most excellent <a href="http://MathJax.org">MathJax</a> library.
The page is generated offline as a React application, using Webpack, which has made adding
"view source" options considerably more challenging. I'm still trying to figure out how to
add them back in, but it didn't feel like it should hold up deploying this update compared
to the previous years' version.</p>
<h2>How complicated is the maths going to be?</h2>
@@ -74,8 +78,6 @@ var Preface = React.createClass({
but you can use the issue tracker for that as well. Once the rewrite is done, I'll add a general
comment section back in, and maybe a more topical "select this section of text and hit the
'question' button to ask a question about it" system. We'll see.
<p>Pomax (or in the tweetworld, <a href="https://twitter.com/TheRealPomax">@TheRealPomax</a>)</p>
</div>
</section>
);

View File

@@ -1,8 +1,39 @@
var React = require("react");
var Graphic = require("../../Graphic.jsx");
var SectionHeader = require("../../SectionHeader.jsx");
var keyHandling = require("../../decorators/keyhandling-decorator.jsx");
var Reordering = React.createClass({
statics: {
// Improve this based on http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves/
lower: function(curve) {
var pts = curve.points, q=[], n = pts.length;
pts.forEach((p,k) => {
if (!k) { return (q[k] = p); }
var f1 = k/n, f2 = 1 - f1;
q[k] = {
x: f1 * p.x + f2 * pts[k-1].x,
y: f1 * p.y + f2 * pts[k-1].y
};
});
q.splice(n-1,1);
q[n-2] = pts[n-1];
curve.points = q;
return curve;
},
keyHandlingOptions: {
values: {
"38": function(api) {
api.setCurve(api.curve.raise());
},
"40": function(api) {
api.setCurve(Reordering.lower(api.curve));
}
}
}
},
getDefaultProps: function() {
return {
title: "Lowering and elevating curve order"
@@ -69,32 +100,6 @@ var Reordering = React.createClass({
});
},
// Improve this based on http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves/
lower: function(curve) {
var pts = curve.points, q=[], n = pts.length;
pts.forEach((p,k) => {
if (!k) { return (q[k] = p); }
var f1 = k/n, f2 = 1 - f1;
q[k] = {
x: f1 * p.x + f2 * pts[k-1].x,
y: f1 * p.y + f2 * pts[k-1].y
};
});
q.splice(n-1,1);
q[n-2] = pts[n-1];
curve.points = q;
return curve;
},
onKeyDown: function(evt, api) {
evt.preventDefault();
if(evt.key === "ArrowUp") {
api.setCurve(api.curve.raise());
} else if(evt.key === "ArrowDown") {
api.setCurve(this.lower(api.curve));
}
},
getOrder: function() {
var order = this.state.order;
if (order%10 === 1 && order !== 11) {
@@ -146,7 +151,7 @@ var Reordering = React.createClass({
<p>We can apply this to a (semi) random curve, as is done in the following graphic. Select the sketch
and press your up and down cursor keys to elevate or lower the curve order.</p>
<Graphic preset="simple" title={"A " + this.getOrder() + " order Bézier curve"} setup={this.setup} draw={this.draw} onKeyDown={this.onKeyDown} />
<Graphic preset="simple" title={"A " + this.getOrder() + " order Bézier curve"} setup={this.setup} draw={this.draw} onKeyDown={this.props.onKeyDown} />
<p>There is a good, if mathematical, explanation on the matrices necessary for optimal reduction
over on <a href="http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves/">Sirver's Castle</a>,
@@ -157,4 +162,4 @@ var Reordering = React.createClass({
}
});
module.exports = Reordering;
module.exports = keyHandling(Reordering);

View File

@@ -1,8 +1,24 @@
var React = require("react");
var Graphic = require("../../Graphic.jsx");
var SectionHeader = require("../../SectionHeader.jsx");
var keyHandling = require("../../decorators/keyhandling-decorator.jsx");
var Tracing = React.createClass({
statics: {
keyHandlingOptions: {
propName: "steps",
values: {
"38": 1, // up arrow
"40": -1 // down arrow
},
controller: function(api) {
if (api.steps < 1) {
api.steps = 1;
}
}
}
},
getDefaultProps: function() {
return {
title: "Tracing a curve at fixed distance intervals"
@@ -60,23 +76,6 @@ var Tracing = React.createClass({
}
},
values: {
"38": 1, // up arrow
"40": -1 // down arrow
},
onKeyDown: function(e, api) {
var v = this.values[e.keyCode];
if(v) {
e.preventDefault();
api.steps += v;
if (api.steps < 1) {
api.steps = 1;
}
console.log(api.steps);
}
},
drawColoured: function(api, curve) {
api.setPanelCount(3);
var w = api.getPanelWidth();
@@ -155,11 +154,11 @@ var Tracing = React.createClass({
apart. In fact, let's look at the relation between "distance long a curve" and
"<i>t</i> value", by plotting them against one another.</p>
<p>The following graphic shows a particularly illustrative curve, and it's length-to-<i>t</i> plot.
<p>The following graphic shows a particularly illustrative curve, and it's length-to-t plot.
For linear traversal, this line needs to be straight, running from (0,0) to (length,1). This is,
it's safe to say, not what we'll see, we'll see something wobbly instead. To make matters even
worse, the length-to-<i>t</i> function is also of a much higher order than our curve is: while
the curve we're using for this exercise is a cubic curve, able to switch concave/convex form twice
the curve we're using for this exercise is a cubic curve, which can switch concave/convex form once
at best, the plot shows that the distance function along the curve is able to switch forms three
times (to see this, try creating an S curve with the start/end close together, but the control
points far apart).</p>
@@ -183,7 +182,7 @@ var Tracing = React.createClass({
along the horizontal axis. It also shows the curve in an alternating colouring based on the
t-for-distance values we find our LUT:</p>
<Graphic preset="threepanel" title="Fixed-interval coloring a curve" setup={this.setup} draw={this.drawColoured} onKeyDown={this.onKeyDown}/>
<Graphic preset="threepanel" title="Fixed-interval coloring a curve" setup={this.setup} draw={this.drawColoured} onKeyDown={this.props.onKeyDown}/>
<p>Use your up and down arrow keys to increase or decrease the number of equidistant segments
used to colour the curve.</p>
@@ -199,4 +198,4 @@ var Tracing = React.createClass({
}
});
module.exports = Tracing;
module.exports = keyHandling(Tracing);

View File

@@ -16,34 +16,41 @@
<meta property="og:section" content="Bézier Curves">
<meta property="og:tag" content="Bézier Curves">
<!-- these rules will get overwritten by the style in the article.js React bundle -->
<style>
html, body, article { height: 100%; margin: 0; }
body { width: 800px; margin: auto; }
header h1, header h2 { text-align: center; }
header h1 { font-size: 300%; margin: 0.2em; }
p.jsnote { margin: 2em; text-align: justify; }
p.jsnote:first-child { width: 13em; margin: auto; }
div.dev {
background: rgb(43, 49, 95);
color: rgb(81, 181, 255);
position: fixed;
transform: rotate(-45deg);
width: 22em;
text-align: center;
top: 4em;
left: -6em;
font-variant: small-caps;
font-weight: bolder;
font-family: Helvetica;
box-shadow: 0px 5px 7px 2px rgba(0, 0, 0, 0.3);
}
body { width: 800px; margin: auto; font-size: 4.25mm!important; }
</style>
</head>
<body>
<div style="" class="dev">DEV PREVIEW ONLY</div>
<div class="dev">
<style>
div.dev {
background: rgb(43, 49, 95);
color: rgb(81, 181, 255);
position: fixed;
transform: rotate(-45deg);
width: 22em;
text-align: center;
top: 4em;
left: -6em;
font-variant: small-caps;
font-weight: bolder;
font-family: Helvetica;
box-shadow: 0px 5px 7px 2px rgba(0, 0, 0, 0.3);
}
</style>
DEV PREVIEW ONLY
</div>
<article>
<!-- these rules will get overwritten by the style in the article.js React bundle -->
<style>
header h1, header h2 { text-align: center; }
header h1 { font-size: 300%; margin: 0.2em; }
p.jsnote { margin: 2em; text-align: justify; }
p.jsnote:first-child { width: 13em; margin: auto; }
</style>
<header>
<h1>A Primer on Bézier Curves</h1>
<h2>A free, online book for when you really need to know how to do Bézier things.</h2>

1
lib/noop.js Normal file
View File

@@ -0,0 +1 @@
module.exports = function(){};

View File

@@ -2,7 +2,6 @@
"name": "bezierinfo",
"version": "1.0.0",
"description": "pomax.github.io/bezierinfo",
"main": "build.js",
"scripts": {
"build": "webpack --prod",
"latex": "node tools/mathjax",
@@ -43,6 +42,7 @@
"file-loader": "^0.8.5",
"image-size": "^0.4.0",
"jsmin": "^1.0.1",
"json-loader": "^0.5.4",
"json-stringify-safe": "^5.0.1",
"less": "^2.5.3",
"less-loader": "^2.2.2",

View File

@@ -3,6 +3,9 @@
top: 0;
right: 0;
height: 0;
overflow: visible;
img {
position: relative;
z-index: 999;

View File

@@ -7,7 +7,6 @@ html, body {
body {
background: url('../images/paper.png');
font-size: 16px;
}
header, section, footer {

View File

@@ -38,6 +38,7 @@ module.exports = {
loaders: [
{ test: /\.(png|gif)$/, loader: "file?name=images/packed/[hash].[ext]" },
{ test: /\.less$/, loader: "style!css!less" },
{ test: /\.json$/, loader: "json" },
{
test: /.jsx?$/,
include: /components/,