Skip to content

Commit

Permalink
Merge pull request #45 from JVital2013/animationOptimizationV1
Browse files Browse the repository at this point in the history
Rotation animation optimizations
  • Loading branch information
adizanni authored Aug 27, 2021
2 parents 09edf18 + d0e21ee commit 942b219
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 70 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ entities:
object_id: <an object id representing the object to be rotated>
rotate:
axis: <'x', 'y' and 'z', along which axis the object should rotate>
round_per_seconds: 1-4, speed of rotation (experimental)
round_per_seconds: 1-4, speed of rotation. Use a negative number to spin the other direction.
```
an object to rotate (animation) when the associated entity will be 'on'. Be advised that for the first release the object will rotate using the center as point of rotation. Center being defined as the center of the bounding box of the object. For fans, if the fan object is not centered in the rotation axis you will see strange revolution animations.

Expand Down
4 changes: 2 additions & 2 deletions dist/floor3d-card.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "floor3d-card",
"version": "1.0.3alpha",
"version": "1.0.4alpha",
"description": "Lovelace floor3d-card",
"keywords": [
"home-assistant",
Expand Down
2 changes: 1 addition & 1 deletion src/const.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const CARD_VERSION = '1.0.3alpha';
export const CARD_VERSION = '1.0.4alpha';
110 changes: 45 additions & 65 deletions src/floor3d-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ export class Floor3dCard extends LitElement {
private _modelY?: number;
private _modelZ?: number;
private _to_animate: boolean;
private _count_to_animate: number;

private _canvas_id: string;
private _states?: string[];
Expand Down Expand Up @@ -296,42 +295,6 @@ export class Floor3dCard extends LitElement {
}, 250);
}


private async _rotateobjects() {

let lastFrameSec = this._clock.getDelta();
let targetFps = 240;
let fps = lastFrameSec == 0 ? targetFps : 1 / lastFrameSec;
await new Promise(r => setTimeout(r, 1000 / targetFps));

requestAnimationFrame(this._rotateobjects.bind(this));
let to_render = false;

this._rotation_state.forEach((state, index) => {

if (state != 0) {
to_render = true;
switch (this._axis_to_rotate[index]) {
case 'x':
this._objects_to_rotate[index].rotation.x += this._round_per_seconds[index] * Math.PI * 2 * state / fps;
break;
case 'y':
this._objects_to_rotate[index].rotation.y += this._round_per_seconds[index] * Math.PI * 2 * state / fps;
break;
case 'z':
this._objects_to_rotate[index].rotation.z += this._round_per_seconds[index] * Math.PI * 2 * state / fps;
break;
}

}

});

if (to_render) {
this._renderer.render(this._scene, this._camera);
}
}

private _resizeCanvas(): void {
console.log('Resize canvas start');
if (
Expand Down Expand Up @@ -381,8 +344,7 @@ export class Floor3dCard extends LitElement {
this._brightness = [];
this._lights = [];
this._canvas = [];
this._to_animate = false;
this._count_to_animate = 0;

this._config.entities.forEach((entity) => {
if (entity.entity !== '') {
this._states.push(this._statewithtemplate(entity));
Expand Down Expand Up @@ -412,9 +374,6 @@ export class Floor3dCard extends LitElement {
} else {
this._unit_of_measurement.push('');
}
if (entity.type3d == 'rotate') {
this._to_animate = true;
}
}
});
this._firstcall = false;
Expand Down Expand Up @@ -648,10 +607,6 @@ export class Floor3dCard extends LitElement {
//first render
this._render();
this._resizeCanvas();
if (this._to_animate) {
this._clock = new THREE.Clock();
this._rotateobjects();
}
}
}

Expand Down Expand Up @@ -995,26 +950,51 @@ export class Floor3dCard extends LitElement {
}

private _rotatecalc(entity: Floor3dCardConfig, i: number) {
this._rotation_index.forEach((index, j) => {
if (index == i) {
//1 if the entity is on, 0 if the entity is off
this._rotation_state[j] = (this._states[i] == 'on' ? 1 : 0);

//If the entity is on and it has the 'percentage' attribute, convert the percentage integer
//into a decimal and store it as the rotation state
if(this._rotation_state[j] != 0 && this._hass.states[entity.entity].attributes['percentage']) {
this._rotation_state[j] = this._hass.states[entity.entity].attributes['percentage'] / 100;
}

//If the entity is on and it is reversed, set the rotation state to the negative value of itself
if(
this._rotation_state[j] != 0 && this._hass.states[entity.entity].attributes['direction'] &&
this._hass.states[entity.entity].attributes['direction'] == 'reverse'
) {
this._rotation_state[j] = 0 - this._rotation_state[j];
}

let j = this._rotation_index.indexOf(i);

//1 if the entity is on, 0 if the entity is off
this._rotation_state[j] = (this._states[i] == 'on' ? 1 : 0);

//If the entity is on and it has the 'percentage' attribute, convert the percentage integer
//into a decimal and store it as the rotation state
if(this._rotation_state[j] != 0 && this._hass.states[entity.entity].attributes['percentage']) {
this._rotation_state[j] = this._hass.states[entity.entity].attributes['percentage'] / 100;
}

//If the entity is on and it is reversed, set the rotation state to the negative value of itself
if(
this._rotation_state[j] != 0 && this._hass.states[entity.entity].attributes['direction'] &&
this._hass.states[entity.entity].attributes['direction'] == 'reverse'
) {
this._rotation_state[j] = 0 - this._rotation_state[j];
}

//If every rotating entity is stopped, disable animation
if(this._rotation_state.every(item => item === 0)) {
if(this._to_animate) {
this._to_animate = false;
this._clock = null;
this._renderer.setAnimationLoop(null);
}
});
}

//Otherwise, start an animation loop
else if(!this._to_animate) {
this._to_animate = true;
this._clock = new THREE.Clock();
this._renderer.setAnimationLoop(() => {
let moveBy = this._clock.getDelta() * Math.PI * 2;

this._rotation_state.forEach((state, index) => {
if (state != 0) {
this._objects_to_rotate[index].rotation[this._axis_to_rotate[index]] += this._round_per_seconds[index] * state * moveBy;
}
});

this._renderer.render(this._scene, this._camera);
});
}
}

private _rotatedoor(_obj: THREE.Mesh, side: string, direction: string, pos: number[], _doorstate: string) {
Expand Down

0 comments on commit 942b219

Please sign in to comment.