diff --git a/components/Article.jsx b/components/Article.jsx index 2fea049f..c4619c7d 100644 --- a/components/Article.jsx +++ b/components/Article.jsx @@ -34,7 +34,8 @@ var Article = React.createClass({ generateNavItem: function(section, entry) { var name = section.props.name; - return
  • { section.props.title }
  • ; + var title = section.props.title; + return
  • { title }
  • ; }, render: function() { diff --git a/components/Graphic.jsx b/components/Graphic.jsx index b5592237..3073147e 100644 --- a/components/Graphic.jsx +++ b/components/Graphic.jsx @@ -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} - /> + />
    {this.props.title} {this.props.children}
    ); diff --git a/components/Ribbon.jsx b/components/Ribbon.jsx index 4da60853..8ec1b3b6 100644 --- a/components/Ribbon.jsx +++ b/components/Ribbon.jsx @@ -9,7 +9,7 @@ var Ribbon = React.createClass({ render: function() { return (
    - This page on GitHub + This page on GitHub This page on GitHub diff --git a/components/decorators/keyhandling-decorator.jsx b/components/decorators/keyhandling-decorator.jsx new file mode 100644 index 00000000..033fb33d --- /dev/null +++ b/components/decorators/keyhandling-decorator.jsx @@ -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 ; + } + }); +}; diff --git a/components/sections/arcapproximation/index.js b/components/sections/arcapproximation/index.js index b2a5edc1..89b7021c 100644 --- a/components/sections/arcapproximation/index.js +++ b/components/sections/arcapproximation/index.js @@ -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.

    - +

    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:

    - +

    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); diff --git a/components/sections/arclengthapprox/index.js b/components/sections/arclengthapprox/index.js index 734821ea..5c162b08 100644 --- a/components/sections/arclengthapprox/index.js +++ b/components/sections/arclengthapprox/index.js @@ -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 (

    @@ -81,8 +80,8 @@ var ArclengthApprox = React.createClass({

    If we combine the work done in the previous sections on curve flattening and arc length computation, we can implement these with minimal effort:

    - - + +

    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); - } - - - 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); - } - - */ \ No newline at end of file +module.exports = keyHandling(ArclengthApprox); \ No newline at end of file diff --git a/components/sections/catmullmoulding/index.js b/components/sections/catmullmoulding/index.js index f3a4f25e..57563774 100644 --- a/components/sections/catmullmoulding/index.js +++ b/components/sections/catmullmoulding/index.js @@ -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:

    - +

    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); diff --git a/components/sections/explanation/index.js b/components/sections/explanation/index.js index e99d5e0e..7d99e7d2 100644 --- a/components/sections/explanation/index.js +++ b/components/sections/explanation/index.js @@ -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 t from 0 to 5, we get this (use your up and down cursor keys to change the plot end value):

    - +

    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); diff --git a/components/sections/flattening/index.js b/components/sections/flattening/index.js index 5d2f39ed..9de250e6 100644 --- a/components/sections/flattening/index.js +++ b/components/sections/flattening/index.js @@ -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); diff --git a/components/sections/graduatedoffset/index.js b/components/sections/graduatedoffset/index.js index c4be72d3..f91cbd1c 100644 --- a/components/sections/graduatedoffset/index.js +++ b/components/sections/graduatedoffset/index.js @@ -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 (

    @@ -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):

    - - - + +
    ); } }); -module.exports = GraduatedOffsetting; +module.exports = keyHandling(GraduatedOffsetting); diff --git a/components/sections/offsetting/index.js b/components/sections/offsetting/index.js index de0eadd6..8bfd140a 100644 --- a/components/sections/offsetting/index.js +++ b/components/sections/offsetting/index.js @@ -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 (
    @@ -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.

    - - + +

    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); diff --git a/components/sections/preface/index.js b/components/sections/preface/index.js index f59caaeb..08776dde 100644 --- a/components/sections/preface/index.js +++ b/components/sections/preface/index.js @@ -47,15 +47,19 @@ var Preface = React.createClass({

    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.

    + what this page is for. Prepare to be mathed!

    -
    -

    All Bézier graphics are interactive.

    +

    —Pomax (or in the tweetworld, @TheRealPomax)

    -

    This page uses interactive examples, as well as "real" maths (in LaTeX form) which - is typeset using the most excellent MathJax 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.

    +
    +

    Note: All Bézier graphics are interactive.

    + +

    This page uses interactive examples, relying heavily on Bezier.js, + as well as "real" maths (in LaTeX form) which is typeset using the most excellent MathJax 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.

    How complicated is the maths going to be?

    @@ -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. - -

    —Pomax (or in the tweetworld, @TheRealPomax)

    ); diff --git a/components/sections/reordering/index.js b/components/sections/reordering/index.js index e6a5a9ac..af83953b 100644 --- a/components/sections/reordering/index.js +++ b/components/sections/reordering/index.js @@ -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({

    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.

    - +

    There is a good, if mathematical, explanation on the matrices necessary for optimal reduction over on Sirver's Castle, @@ -157,4 +162,4 @@ var Reordering = React.createClass({ } }); -module.exports = Reordering; +module.exports = keyHandling(Reordering); diff --git a/components/sections/tracing/index.js b/components/sections/tracing/index.js index 42998fc8..bfd4ca39 100644 --- a/components/sections/tracing/index.js +++ b/components/sections/tracing/index.js @@ -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 "t value", by plotting them against one another.

    -

    The following graphic shows a particularly illustrative curve, and it's length-to-t plot. +

    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-t 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).

    @@ -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:

    - +

    Use your up and down arrow keys to increase or decrease the number of equidistant segments used to colour the curve.

    @@ -199,4 +198,4 @@ var Tracing = React.createClass({ } }); -module.exports = Tracing; +module.exports = keyHandling(Tracing); diff --git a/index.html b/index.html index 2785ddfc..c4508cf3 100644 --- a/index.html +++ b/index.html @@ -16,34 +16,41 @@ - -
    DEV PREVIEW ONLY
    +
    + + DEV PREVIEW ONLY +
    + + +

    A Primer on Bézier Curves

    A free, online book for when you really need to know how to do Bézier things.

    diff --git a/lib/noop.js b/lib/noop.js new file mode 100644 index 00000000..2ca44828 --- /dev/null +++ b/lib/noop.js @@ -0,0 +1 @@ +module.exports = function(){}; diff --git a/package.json b/package.json index c7d0bd8a..3a0c3127 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/stylesheets/ribbon.less b/stylesheets/ribbon.less index 34db30d0..964f6262 100644 --- a/stylesheets/ribbon.less +++ b/stylesheets/ribbon.less @@ -3,6 +3,9 @@ top: 0; right: 0; + height: 0; + overflow: visible; + img { position: relative; z-index: 999; diff --git a/stylesheets/style.less b/stylesheets/style.less index 2bccd76b..245c4681 100644 --- a/stylesheets/style.less +++ b/stylesheets/style.less @@ -7,7 +7,6 @@ html, body { body { background: url('../images/paper.png'); - font-size: 16px; } header, section, footer { diff --git a/webpack.config.js b/webpack.config.js index e477b597..3521bd3e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -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/,