1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-25 17:42:46 +02:00

splines + slider refinement

This commit is contained in:
Pomax
2020-09-06 09:08:11 -07:00
parent 9434a71d34
commit 1de1fc9ce3
21 changed files with 324 additions and 258 deletions

View File

@@ -1,4 +1,5 @@
import { enrich } from "../lib/enrich.js";
import { create } from "../lib/create.js";
import { Bezier } from "./types/bezier.js";
import { BSpline } from "./types/bspline.js";
import { Vector } from "./types/vector.js";
@@ -176,6 +177,23 @@ class GraphicsAPI extends BaseAPI {
this.line(0, 0, 0, this.height);
}
/**
* Dynamically add a slider
*/
addSlider(classes, propname, min, max, step, value, transform) {
if (this.element) {
let slider = create(`input`);
slider.type = `range`;
slider.min = min;
slider.max = max;
slider.step = step;
slider.setAttribute(`value`, value);
slider.setAttribute(`class`, classes);
this.element.append(slider);
this.setSlider(slider, propname, value, transform);
}
}
/**
* Set up a slider to control a named, numerical property in the sketch.
*
@@ -185,22 +203,31 @@ class GraphicsAPI extends BaseAPI {
* @param {boolean} redraw whether or not to redraw after updating the value from the slider.
*/
setSlider(qs, propname, initial, transform) {
if (typeof this[propname] !== `undefined`) {
if (propname !== false && typeof this[propname] !== `undefined`) {
throw new Error(`this.${propname} already exists: cannot bind slider.`);
}
let slider = this.find(qs);
let slider = typeof qs === `string` ? this.find(qs) : qs;
if (!slider) {
console.warn(`Warning: no slider found for query selector "${qs}"`);
this[propname] = initial;
if (propname) this[propname] = initial;
return undefined;
}
const updateProperty = (evt) => {
let value = parseFloat(slider.value);
slider.setAttribute(`value`, value);
this[propname] = transform ? transform(value) : value;
try {
let checked = transform ? transform(value) ?? value : value;
if (propname) this[propname] = checked;
} catch (e) {
if (evt instanceof Event) {
evt.preventDefault();
evt.stopPropagation();
}
slider.value = e.value;
slider.setAttribute(`value`, e.value);
}
if (!this.redrawing) this.redraw();
};
@@ -211,6 +238,15 @@ class GraphicsAPI extends BaseAPI {
return slider;
}
/**
* remove all sliders from this element
*/
removeSliders() {
this.findAll(`input[type=range]`).forEach((s) => {
s.parentNode.removeChild(s);
});
}
/**
* Convert the canvas to an image
*/
@@ -413,7 +449,7 @@ class GraphicsAPI extends BaseAPI {
* Set the context lineWidth
*/
setWidth(width) {
this.ctx.lineWidth = `${width}px`;
this.ctx.lineWidth = width;
}
/**

View File

@@ -1,4 +1,4 @@
import interpolate from "../util/spline.js";
import interpolate from "../util/interpolate-bspline.js";
// cubic B-Spline
const DEGREE = 3;

View File

@@ -24,6 +24,11 @@ export default function interpolate(
}
}
// closed curve?
if (weights.length < points.length) {
weights = weights.concat(weights.slice(0, degree));
}
if (!knots) {
// build knot vector of length [n + degree + 1]
var knots = [];
@@ -35,6 +40,11 @@ export default function interpolate(
throw new Error("bad knot vector length");
}
// closed curve?
if (knots.length === points.length) {
knots = knots.concat(knots.slice(0, degree));
}
var domain = [degree, knots.length - 1 - degree];
var low = knots[domain[0]];

View File

@@ -0,0 +1,14 @@
import { enrich } from "./enrich.js";
function create(element) {
if (typeof document !== `undefined`) {
return enrich(document.createElement(element));
}
return {
name: element,
tag: element.toUpperCase(),
};
}
export { create };