avocado-old/packages/math/vector/mixin.js
2019-04-28 23:45:03 -05:00

82 lines
1.9 KiB
JavaScript

import {compose, Property} from '@avocado/core';
import * as Vector from './index'
export function VectorMixin(
vectorKey = 'vector',
x = 'x',
y = 'y',
meta = {},
) {
meta = {
default: [0, 0],
eq: function(l, r) {
return Vector.equals(l, r);
},
...meta,
};
let transformedProperty;
if (meta.transformProperty) {
transformedProperty = meta.transformProperty(vectorKey);
}
else {
transformedProperty = `$$avocado_property_${vectorKey}`;
}
meta.initialize = function() {
this[transformedProperty] = Vector.copy(meta.default);
};
const bypass = `${vectorKey}$bypassChangedEvent`;
meta.set = meta.set || new Function('vector', `
this.${transformedProperty} = [
this.${transformedProperty}[0],
this.${transformedProperty}[1],
];
if (this.${bypass}) {
this.${transformedProperty}[0] = vector[0];
this.${transformedProperty}[1] = vector[1];
}
else {
this.${x} = vector[0];
this.${y} = vector[1];
}
`);
function createPropertyPair(axe) {
return {
get: new Function(`
return this.${transformedProperty}[${'x' === axe ? 0 : 1}];
`),
set: new Function('value', `
this.${bypass} = true;
this.${vectorKey} = [
${'x' === axe ? 'value' : `this.${x}`},
${'y' === axe ? 'value' : `this.${y}`},
];
this.${bypass} = false;
`),
};
}
const decorate = compose(
Property(x, {
emit: meta.emit,
track: meta.track,
...createPropertyPair('x'),
}),
Property(y, {
emit: meta.emit,
track: meta.track,
...createPropertyPair('y'),
}),
Property(vectorKey, meta),
);
return (Superclass) => {
return class Vector extends decorate(Superclass) {
constructor(...args) {
super(...args);
this[bypass] = false;
}
}
};
}