Skip to content

Commit

Permalink
feat: add reactive state #79
Browse files Browse the repository at this point in the history
  • Loading branch information
daybrush committed Dec 15, 2022
1 parent c479682 commit af5045f
Show file tree
Hide file tree
Showing 20 changed files with 8,602 additions and 1,635 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ $ npm install scenejs
## 馃摝 Packages
|Package|Version|Description|
|---|---|---|
|[**react-scenejs**](https://github.com/daybrush/scenejs/tree/master/packages/react-scenejs)|(Soon)|A React Component that create JavaScript & CSS timeline-based animation with Scene.js.|
|[**react-scenejs**](https://github.com/daybrush/scenejs/tree/master/packages/react-scenejs)|[![](https://img.shields.io/npm/v/react-scenejs.svg?style=flat-square)](https://npmjs.com/package/react-scenejs)|A React Component that create JavaScript & CSS timeline-based animation with Scene.js.|
|[**vue2-scenejs**](https://github.com/daybrush/scenejs/tree/master/packages/vue-scenejs)|(Soon)|A Vue Component that create JavaScript & CSS timeline-based animation with Scene.js.|
|[**vue-scenejs**](https://github.com/daybrush/scenejs/tree/master/packages/vue3-scenejs)|(Soon)|A Vue 3 Component that create JavaScript & CSS timeline-based animation with Scene.js.|
|[**svelte-scenejs**](https://github.com/daybrush/scenejs/tree/master/packages/svelte-scenejs)|(Soon)|A Svelte Component that create JavaScript & CSS timeline-based animation with Scene.js.|
Expand Down
4 changes: 3 additions & 1 deletion jsdoc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
},
"source": {
"include": [
"./packages/scenejs/src",
"./packages/scenejs/src/",
"./packages/scenejs/src/reactive",
"./packages/react-scenejs/src/react-scenejs/",
"./README.md",
"./node_modules/@scena/event-emitter/src/"
],
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"release": "lerna-helper release --base scenejs"
},
"devDependencies": {
"@daybrush/builder": "^0.1.2",
"@daybrush/jsdoc": "^0.4.3",
"@daybrush/release": "^0.7.1",
"cpx": "1.5.0",
Expand All @@ -60,7 +59,8 @@
"resolutions": {
"@daybrush/builder": "^0.2.0",
"@daybrush/utils": "^1.7.1",
"@types/react": "^16.9.17",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"typescript": "^4.5.0 <4.6.0",
"@scena/event-emitter": "^1.0.3",
"css-styled": "^1.0.0",
Expand All @@ -70,7 +70,8 @@
"overrides": {
"@daybrush/builder": "^0.2.0",
"@daybrush/utils": "^1.7.1",
"@types/react": "^16.9.17",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"typescript": "^4.5.0 <4.6.0",
"@scena/event-emitter": "^1.0.3",
"css-styled": "^1.0.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/scenejs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"start": "rollup -c -w",
"test:chrome": "karma start --chrome",
"build": "rollup -c && print-sizes ./dist && npm run declaration",
"declaration": "rm -rf declaration && tsc -p tsconfig.declaration.json",
"declaration": "tsc -p tsconfig.declaration.json",
"coveralls": "cat ./coverage/lcov.info | coveralls"
},
"repository": {
Expand Down Expand Up @@ -66,6 +66,7 @@
"typescript": "^4.5.0 <4.6.0"
},
"dependencies": {
"@cfcs/core": "^0.0.9",
"@daybrush/utils": "^1.8.0",
"@scena/event-emitter": "^1.0.3",
"css-styled": "^1.0.0",
Expand Down
19 changes: 13 additions & 6 deletions packages/scenejs/src/Animator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
EasingFunction, FillModeType, PlayStateType, EasingType, AnimatorOptions, AnimatorEvents,
} from "./types";
import EventEmitter from "@scena/event-emitter";
import { reactive } from "@cfcs/core";

function GetterSetter<T extends new (...args: any[]) => {}>(
getter: string[], setter: string[], parent: string) {
Expand Down Expand Up @@ -51,16 +52,22 @@ export function isDirectionReverse(iteration: number, iteraiontCount: IterationC
* @property {"normal"|"reverse"|"alternate"|"alternate-reverse"} [direction] The direction property defines whether an animation should be played forwards, backwards or in alternate cycles.
*/

const setters = ["id", ITERATION_COUNT, DELAY, FILL_MODE,
DIRECTION, PLAY_SPEED, DURATION, PLAY_SPEED, ITERATION_TIME, PLAY_STATE];
const getters = [...setters, EASING, EASING_NAME];
export const ANIMATOR_SETTERS = [
"id", ITERATION_COUNT, DELAY, FILL_MODE,
DIRECTION, PLAY_SPEED, DURATION,
PLAY_SPEED, ITERATION_TIME, PLAY_STATE
];
export const ANIMATOR_GETTERS = [
...ANIMATOR_SETTERS,
EASING, EASING_NAME,
];

/**
* play video, animation, the others
* @extends EventEmitter
* @see {@link https://www.w3schools.com/css/css3_animations.asp CSS3 Animation}
*/
@GetterSetter(getters, setters, "state")
@GetterSetter(ANIMATOR_GETTERS, ANIMATOR_SETTERS, "state")
class Animator <
Options extends AnimatorOptions = AnimatorOptions,
State extends AnimatorState = AnimatorState,
Expand All @@ -83,7 +90,7 @@ class Animator <
*/
constructor(options?: Partial<Options & AnimatorOptions>) {
super();
this.state = {
this.state = reactive({
id: "",
easing: 0,
easingName: "linear",
Expand All @@ -99,7 +106,7 @@ class Animator <
prevTime: 0,
playState: PAUSED,
duration: 0,
} as State;
}) as State;
this.setOptions(options);
}
/**
Expand Down
145 changes: 81 additions & 64 deletions packages/scenejs/src/Frame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import {
decamelize,
camelize,
} from "@daybrush/utils";
import { NameType, KeyValueChildren } from "./types";
import { NameType, KeyValueChildren, FrameEvents } from "./types";
import OrderMap from "order-map";
import { Observe } from "@cfcs/core";
import EventEmitter from "@scena/event-emitter";

function toInnerProperties(obj: IObject<string>, orders: NameType[] = []) {
if (!obj) {
Expand Down Expand Up @@ -76,10 +78,12 @@ function getValue(names: NameType[], value: any): any {
}
return value;
}


/**
* Animation's Frame
*/
class Frame {
class Frame extends EventEmitter<FrameEvents> {
public properties: IObject<any> = {};
public orderMap: OrderMap = new OrderMap(NAME_SEPARATOR);
/**
Expand All @@ -93,7 +97,8 @@ class Frame {
}
});
*/
constructor(properties: any = {}) {
constructor(properties: string | Record<string, any> = {}) {
super();
this.properties = {};
// this.orders = [];
this.set(properties);
Expand Down Expand Up @@ -129,7 +134,10 @@ class Frame {
frame.setOrders(["transform"], ["scale", "tralsate"])
*/
public setOrders(names: NameType[], orders: NameType[]): NameType[] {
return this.orderMap.set(names, orders);
const result = this.orderMap.set(names, orders);

this._update();
return result;
}
/**
* get properties order object
Expand All @@ -150,6 +158,7 @@ class Frame {
*/
public setOrderObject(obj: IObject<NameType[]>) {
this.orderMap.setObject(obj);
this._update();
}

/**
Expand Down Expand Up @@ -206,6 +215,7 @@ class Frame {
if (isObject(value)) {
delete value[params[length - 1]];
}
this._update();
return this;
}
/**
Expand Down Expand Up @@ -236,60 +246,9 @@ class Frame {
frame.set("transform", "translate", "50px");
*/
public set(...args: any[]) {
const self = this;
const length = args.length;
const params = args.slice(0, -1);
const value = args[length - 1];
const firstParam = params[0];

if (length === 1 && isFrame(value)) {
self.merge(value);
} else if (firstParam in ALIAS) {
self._set(ALIAS[firstParam], value);
} else if (length === 2 && isArray(firstParam)) {
self._set(firstParam, value);
} else if (isPropertyObject(value)) {
if (isRole(params)) {
self.set(...params, toObject(value));
} else {
self._set(params, value);
}
} else if (isArray(value)) {
self._set(params, value);
} else if (isObject(value)) {
if (!self.has(...params) && isRole(params)) {
self._set(params, {});
}
for (const name in value) {
self.set(...params, name, value[name]);
}
} else if (isString(value)) {
if (isRole(params, true)) {
if (isFixed(params) || !isRole(params)) {
this._set(params, value);
} else {
const obj = toPropertyObject(value);

if (isObject(obj)) {
self.set(...params, obj);
}
}
return this;
} else {
const { styles, length: stylesLength } = splitStyle(value);

for (const name in styles) {
self.set(...params, name, styles[name]);
}
if (stylesLength) {
return this;
}
}
self._set(params, value);
} else {
self._set(params, value);
}
return self;
this._set(...args);
this._update();
return this;
}
/**
* Gets the names of properties.
Expand Down Expand Up @@ -425,29 +384,87 @@ class Frame {
this.orderMap.clear();
return this;
}
private _set(args: NameType[], value: any) {
let properties = this.properties;
private _set(...args: any[]) {
const self = this;
const length = args.length;
const params = args.slice(0, -1);
const value = args[length - 1];
const firstParam = params[0];

if (length === 1 && isFrame(value)) {
self.merge(value);
} else if (firstParam in ALIAS) {
self._setByPath(ALIAS[firstParam], value);
} else if (length === 2 && isArray(firstParam)) {
self._setByPath(firstParam, value);
} else if (isPropertyObject(value)) {
if (isRole(params)) {
self._set(...params, toObject(value));
} else {
self._setByPath(params, value);
}
} else if (isArray(value)) {
self._setByPath(params, value);
} else if (isObject(value)) {
if (!self.has(...params) && isRole(params)) {
self._setByPath(params, {});
}
for (const name in value) {
self._set(...params, name, value[name]);
}
} else if (isString(value)) {
if (isRole(params, true)) {
if (isFixed(params) || !isRole(params)) {
this._setByPath(params, value);
} else {
const obj = toPropertyObject(value);

if (isObject(obj)) {
self._set(...params, obj);
}
}
return this;
} else {
const { styles, length: stylesLength } = splitStyle(value);

for (const name in styles) {
self._set(...params, name, styles[name]);
}
if (stylesLength) {
return this;
}
}
self._setByPath(params, value);
} else {
self._setByPath(params, value);
}
}
private _setByPath(path: NameType[], value: any) {
let properties = this.properties;
const length = path.length;

for (let i = 0; i < length - 1; ++i) {
const name = args[i];
const name = path[i];

!(name in properties) && (properties[name] = {});
properties = properties[name];
}
if (!length) {
return;
}
const lastParam = args[length - 1];
const lastParam = path[length - 1];

this.orderMap.add(args);
this.orderMap.add(path);
if (length === 1 && lastParam === TIMING_FUNCTION) {
properties[lastParam] = getEasing(value);
} else {
properties[lastParam] = isString(value) && !isFixed(args)
properties[lastParam] = isString(value) && !isFixed(path)
? toPropertyObject(value, lastParam)
: value;
}
}
private _update() {
this.emit("update");
}
}
export default Frame;
Loading

0 comments on commit af5045f

Please sign in to comment.