Skip to content

Commit

Permalink
Add animation
Browse files Browse the repository at this point in the history
  • Loading branch information
kentquirk committed Dec 20, 2024
1 parent 5ff0c72 commit 8443294
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 56 deletions.
16 changes: 11 additions & 5 deletions docs/parametrix/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,30 @@ <h1>Experimental Parameterized Sketcher</h1>
<p class="description">
This is an experiment to see what would happen if I allowed all of the
parameters of a graph to be controlled by functions that can be stacked.
Instead of setting the parameters of a line (position, width, color) to a
constant, allow it to be adjusted mathematically along the path of the
line.
</p>
<p class="description">
Each parameter has two functions that are applied one after the other
along the stroke of the curve. These are shown on the left, with the boxes
representing the values of that parameter along the curve.
<i>x</i> and <i>y</i> control the position of the point along the curve;
<i>w</i> is the width of the line at that point; <i>r</i>, <i>g</i>, <i>b</i>,
and <i>a</i> are the red, green, blue, and alpha values of the color.
</p>
<p class="description">
In animation mode (press 'a'), instead of applying the functions one after the other,
the system smoothly interpolates between the values of the left and right functions.
</p>
<div id="sketch-holder">
</div>
<h2>Controls</h2>
<ul>
<li><b>right click in a function box</b> -- cycle between function types: sin, cos, linear, constant, quadratic, cubic, bezier</li>
<li><b>left click and drag within a function box</b> -- adjust the function parameters. Experiment!</li>
<li><b>r</b> -- reset the sketch.</li>
<li><b>a</b> -- toggle animation mode.</li>
<li><b>b</b> -- toggle bounce or loop animation.</li>
<li><b>c</b> -- copy the left column of functions to the right column</li>
<li><b>&lt;, &gt;</b> -- increase or decrease animation speed.</li>
<li><b>1-0</b> -- set animation duration to 1-10 seconds.</li>
<li><b>p</b> -- pause the animation.</li>
</p>
</body>
</html>
127 changes: 104 additions & 23 deletions docs/parametrix/sketch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ let ww = 1400;
let wh = 1000;
let blocksize = 100;
let currentFunctionBlock = null;
let animate = false;
let frame = 0;
let animationFrameTimeMs = 2000;
let totalAnimationTimeMs = 0;
let bounce = true;
let lastDrawMs = 0;

let sketch;

Expand Down Expand Up @@ -122,15 +128,32 @@ class parameter {
this.minvalue = minvalue;
}

copyF1toF2() {
this.f2.copyFrom(this.f1);
}

setPosition = (x, y)=> {
this.y = y;
this.f1.setPosition(x+50, y);
this.f2.setPosition(x+50 + blocksize + 20, y);
}

plot = (animated, frame, t)=> {
if (animated) {
return this.animatedValueAt(frame, t);
} else {
return this.valueAt(t);
}
}

valueAt = (t)=> {
return lerp(this.minvalue, this.maxvalue, this.f2.valueAt(this.f1.valueAt(t)));
// return this.f1.valueAt(t);
}

animatedValueAt = (frame, t)=> {
let v1 = this.f1.valueAt(t);
let v2 = this.f2.valueAt(t);
return lerp(this.minvalue, this.maxvalue, lerp(v1, v2, frame));
}

draw = ()=> {
Expand Down Expand Up @@ -177,16 +200,24 @@ class functorBlock {
constructor(size, fix, f, v1, v2) {
this.x = 0;
this.y = 0;
this.size = size;
// v1 and v2 are values from 0-1 that can be set by clicking on the block
this.v1value = v1;
this.v2value = v2;
this.size = size;

this.functionIndex = fix;
this.f = f;
this.fname = functionTable[fix].name;
}

copyFrom = (other) => {
this.v1value = other.v1value;
this.v2value = other.v2value;
this.functionIndex = other.functionIndex;
this.f = other.f;
this.fname = other.fname;
}

setFunction = () => {
this.functionIndex = (this.functionIndex + 1) % functionTable.length;
this.f = functionTable[this.functionIndex].f();
Expand Down Expand Up @@ -277,6 +308,12 @@ class parametricSketch {
this.layout();
}

copyAll() {
for (let i = 0; i < this.parameters.length; i++) {
this.parameters[i].copyF1toF2();
}
}

layout() {
let y = this.top + 20;
for (let i = 0; i < this.parameters.length; i++) {
Expand All @@ -288,35 +325,31 @@ class parametricSketch {
addParameter(name, startf, maxvalue = 1, minvalue = 0) {
let p = new parameter(name, startf, maxvalue, minvalue);
this.parameters.push(p);
this[name] = p.valueAt;
this[name] = p.plot;
return p;
}

valuesAt(t) {
valuesAt(animated, frame, t) {
return {
x: this.x(t),
y: this.y(t),
r: this.r(t),
g: this.g(t),
b: this.b(t),
a: this.a(t),
w: this.w(t),
x: this.x(animated, frame, t),
y: this.y(animated, frame, t),
r: this.r(animated, frame, t),
g: this.g(animated, frame, t),
b: this.b(animated, frame, t),
a: this.a(animated, frame, t),
w: this.w(animated, frame, t),
};
}

draw() {
draw(animated = false, frame = 0) {
fill(this.bgcolor);
noStroke();
rect(this.left, this.top, this.width, this.height);

let current = this.valuesAt(0);
let printed = false;
// main plotting loop
let current = this.valuesAt(animated, frame, 0);
for (let i = this.step; i <= 1; i += this.step) {
let next = this.valuesAt(i);
if (i > 0.5 && !printed) {
// console.log(next);
printed = true;
}
let next = this.valuesAt(animated, frame, i);
stroke(current.r, current.g, current.b, current.a);
strokeWeight(current.w);
// invert the y axis
Expand Down Expand Up @@ -346,12 +379,45 @@ function windowResized() {

function keyTyped() {
switch (key) {
case ' ':
case 'p':
paused = !paused;
break;
case 'r':
restart();
break;
case 'c':
sketch.copyAll();
break;
case 'a':
animate = !animate;
break;
case 'b':
bounce = !bounce;
break;
case '>':
animationFrameTimeMs = Math.min(10000, animationFrameTimeMs* 1.05);
totalAnimationTimeMs = frame * animationFrameTimeMs;
break;
case '<':
animationFrameTimeMs = Math.max(100, animationFrameTimeMs * 0.95);
totalAnimationTimeMs = frame * animationFrameTimeMs;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
animationFrameTimeMs = 1000 * (key - '0');
totalAnimationTimeMs = frame * animationFrameTimeMs;
break;
case '0':
animationFrameTimeMs = 10000;
totalAnimationTimeMs = frame * animationFrameTimeMs;
break;
}
}

Expand Down Expand Up @@ -415,10 +481,25 @@ function setup() {

function draw() {
clear();
background(142, 206, 255);
if (animate) {
background(206, 142, 255);
} else {
background(142, 206, 255);
}

let t = millis();
let deltaTMs = t - lastDrawMs;
lastDrawMs = t;
if (!paused) {
sketch.draw();
if (animate) {
totalAnimationTimeMs += deltaTMs;
frame = (totalAnimationTimeMs / animationFrameTimeMs) % 1;
if (bounce) {
if (totalAnimationTimeMs % (2 * animationFrameTimeMs) > animationFrameTimeMs) {
frame = 1 - frame;
}
}
}
}

sketch.draw(animate, frame);
}
16 changes: 11 additions & 5 deletions p5/parametrix/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,30 @@ <h1>Experimental Parameterized Sketcher</h1>
<p class="description">
This is an experiment to see what would happen if I allowed all of the
parameters of a graph to be controlled by functions that can be stacked.
Instead of setting the parameters of a line (position, width, color) to a
constant, allow it to be adjusted mathematically along the path of the
line.
</p>
<p class="description">
Each parameter has two functions that are applied one after the other
along the stroke of the curve. These are shown on the left, with the boxes
representing the values of that parameter along the curve.
<i>x</i> and <i>y</i> control the position of the point along the curve;
<i>w</i> is the width of the line at that point; <i>r</i>, <i>g</i>, <i>b</i>,
and <i>a</i> are the red, green, blue, and alpha values of the color.
</p>
<p class="description">
In animation mode (press 'a'), instead of applying the functions one after the other,
the system smoothly interpolates between the values of the left and right functions.
</p>
<div id="sketch-holder">
</div>
<h2>Controls</h2>
<ul>
<li><b>right click in a function box</b> -- cycle between function types: sin, cos, linear, constant, quadratic, cubic, bezier</li>
<li><b>left click and drag within a function box</b> -- adjust the function parameters. Experiment!</li>
<li><b>r</b> -- reset the sketch.</li>
<li><b>a</b> -- toggle animation mode.</li>
<li><b>b</b> -- toggle bounce or loop animation.</li>
<li><b>c</b> -- copy the left column of functions to the right column</li>
<li><b>&lt;, &gt;</b> -- increase or decrease animation speed.</li>
<li><b>1-0</b> -- set animation duration to 1-10 seconds.</li>
<li><b>p</b> -- pause the animation.</li>
</p>
</body>
</html>
Loading

0 comments on commit 8443294

Please sign in to comment.