class Filter {
constructor(name, min, max, defaultValue = 0) {
this.name = name;
this.min = min;
this.max = max;
this.defaultValue = defaultValue;
this.value = defaultValue;
this.active = false;
}
apply(r, g, b) {
throw new Error(
`${this.name}: apply() not implemented`
);
}
reset() {
this.value = this.defaultValue;
this.active = false;
}
}
class BrightnessFilter extends Filter {
constructor() {
super('Brightness', -100, 100, 0);
}
apply(r, g, b) {
return [
r + this.value,
g + this.value,
b + this.value
];
}
}
class GrayscaleFilter extends Filter {
constructor() {
super('Grayscale', 0, 1, 0);
}
apply(r, g, b) {
if (!this.active) return [r, g, b];
const avg = (r + g + b) / 3;
return [avg, avg, avg];
}
}
class FilterManager {
constructor() {
this.filters = [
new BrightnessFilter(),
new ContrastFilter(),
new SaturationFilter(),
new GrayscaleFilter(),
new InvertFilter(),
];
}
applyAll(r, g, b) {
let result = [r, g, b];
for (const filter of this.filters) {
result = filter.apply(...result);
}
return result;
}
resetAll() {
this.filters.forEach(f => f.reset());
}
}
Replace the 14 scattered filter functions with the class hierarchy. Wire the FilterManager into the rendering pipeline from Session 28.
| Use Classes When | Use Functions When |
|---|---|
| Shared structure + state + behavior | Stateless transformation |
| Multiple instances needed | Single utility function |
| Inheritance makes sense | Composition is simpler |
| Complex internal state | Input → output (pure) |
git switch -c refactor/PIXELCRAFT-025-class-hierarchy
git add src/scripts/
git commit -m "Refactor filters to class hierarchy with FilterManager (PIXELCRAFT-025)"
git push origin refactor/PIXELCRAFT-025-class-hierarchy
# PR → Review → Merge → Close ticket ✅
Object-Oriented Programming (OOP).
Classes model "things" that have both state (properties) and behavior (methods). Inheritance shares common behavior while specializing.