Skip to content

Commit 370c133

Browse files
committed
hot reload perlin example on file change with custom webpack loader
1 parent 86e9eb1 commit 370c133

File tree

8 files changed

+155
-65
lines changed

8 files changed

+155
-65
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

hot.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const acorn = require('acorn');
2+
3+
/**
4+
* webpack loader for hot patching top level functions on file change
5+
* inspired by https://github.com/jlongster/monkey-hot-loader
6+
*/
7+
module.exports = function (source) {
8+
if (this.cacheable) {
9+
this.cacheable();
10+
}
11+
12+
const ast = acorn.parse(source);
13+
const names = JSON.stringify(
14+
ast.body
15+
.filter(node => node.type == 'FunctionDeclaration')
16+
.map(node => node.id.name));
17+
18+
const s = `${source};
19+
var hot = module.hot;
20+
if (hot) {
21+
hot.accept(err => console.log('error', err));
22+
23+
var keep = (bindings, evalstr) =>
24+
hot.dispose(function (data) {
25+
data.bindings = bindings;
26+
data.evalstr = evalstr;
27+
});
28+
29+
if (!hot.data) {
30+
var bindings = {}, exports = module.exports;
31+
${names}.forEach(function (name) {
32+
var f = eval(name);
33+
var proxied = new Proxy(f, {
34+
apply: function (f, self, args) {
35+
return (bindings[name] || f).apply(self, args);
36+
}
37+
});
38+
eval(name + " = proxied;");
39+
if (exports[name]) exports[name] = proxied;
40+
});
41+
keep(bindings, str => eval(str));
42+
}
43+
else {
44+
var data = hot.data, bindings = data.bindings;
45+
${names}.forEach(function (name) {
46+
bindings[name] = data.evalstr(
47+
'(' +
48+
eval(name).toString()
49+
.replace(/^function \\w+\\(/,
50+
'function (') +
51+
')');
52+
});
53+
keep(bindings, data.evalstr);
54+
}
55+
}`;
56+
57+
this.callback(null, s);
58+
};

package.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,16 @@
44
"description": "Learning to master p5.js",
55
"repository": "https://github.com/kgolid/p5ycho.git",
66
"author": "Kjetil Midtgarden Golid",
7-
"license": "ISC"
7+
"license": "ISC",
8+
"scripts": {
9+
"watch": "webpack-dev-server --config webpack.config.js --hot"
10+
},
11+
"dependencies": {
12+
"p5": "^0.5.11"
13+
},
14+
"devDependencies": {
15+
"acorn": "^5.0.3",
16+
"webpack": "^2.6.1",
17+
"webpack-dev-server": "^2.4.5"
18+
}
819
}

perlin.html

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
<head>
44
<meta charset="utf-8">
55
<title>Generative Art</title>
6-
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.10/p5.js"></script>
7-
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.10/addons/p5.dom.js"></script>
8-
9-
<script src="sketches/perlin.js"></script>
6+
<script src="perlin.js"></script>
107
</head>
118
<body style="margin:0; padding:0;">
129
</body>

sketches/perlin.js

Lines changed: 0 additions & 60 deletions
This file was deleted.

sketches/perlin/perlin.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const p5 = require('p5');
2+
3+
const ui = require('./ui');
4+
5+
var sketch = function (p) {
6+
const w = p.windowWidth;
7+
const h = p.windowHeight;
8+
let t = 0;
9+
let n = 800;
10+
let particles = [];
11+
12+
p.setup = function() {
13+
p.createCanvas(w, h);
14+
p.stroke(0, 10);
15+
16+
for (var i = 0; i < n; i++) {
17+
particles.push({
18+
pos: p.createVector(p.random(w), p.random(h)),
19+
vel: p.createVector(0,0),
20+
seed: i
21+
});
22+
}
23+
};
24+
25+
p.draw = function() {
26+
particles.forEach( function(prtcl) {
27+
ui.display(p, prtcl.pos, prtcl.vel);
28+
ui.update(p, t, prtcl.pos, prtcl.vel, prtcl.seed);
29+
});
30+
t += 0.002;
31+
};
32+
};
33+
34+
new p5(sketch);

sketches/perlin/ui.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const p5 = require('p5');
2+
3+
exports.update = update;
4+
exports.display = display;
5+
6+
function display (p, pos, vel) {
7+
//p.line(pos.x, pos.y, (pos.x + vel.x), (pos.y + vel.y));
8+
//p.fill(0);
9+
//p.ellipse(pos.x, pos.y, 50);
10+
p.point(pos.x, pos.y);
11+
}
12+
13+
function update (p, t, pos, vel, seed) {
14+
const w = p.windowWidth;
15+
const h = p.windowHeight;
16+
17+
pos.x = mod((pos.x + vel.x), w);
18+
pos.y = mod((pos.y + vel.y), h);
19+
20+
var r = p5.Vector.fromAngle(p.noise(seed, t) * p.TWO_PI);
21+
vel.x = r.x;
22+
vel.y = r.y;
23+
24+
vel.add(flow(p, pos)).mult(3);
25+
}
26+
27+
function flow (p, pos) {
28+
let r = p.noise(pos.x / 100, pos.y / 100) * p.TWO_PI;
29+
return p5.Vector.fromAngle(r).mult(2);
30+
}
31+
32+
function mod (x, n) {
33+
return ((x % n) + n ) % n;
34+
}

webpack.config.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports = {
2+
entry: {
3+
perlin: './sketches/perlin/perlin.js'
4+
},
5+
6+
output: {
7+
filename: "[name].js"
8+
},
9+
10+
module: {
11+
loaders: [
12+
{ test: /\.js$/, exclude: /node_modules/, loaders: ['./hot'] },
13+
]
14+
}
15+
};

0 commit comments

Comments
 (0)