explode-units.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /**
  2. * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import { PluginCommands } from '../../../mol-plugin/commands';
  7. import { StateSelection } from '../../../mol-state';
  8. import { ParamDefinition as PD } from '../../../mol-util/param-definition';
  9. import { PluginStateObject } from '../../objects';
  10. import { StateTransforms } from '../../transforms';
  11. import { PluginStateAnimation } from '../model';
  12. export const AnimateUnitsExplode = PluginStateAnimation.create({
  13. name: 'built-in.animate-units-explode',
  14. display: { name: 'Explode Units' },
  15. params: () => ({
  16. durationInMs: PD.Numeric(3000, { min: 100, max: 10000, step: 100})
  17. }),
  18. initialState: () => ({ t: 0 }),
  19. async setup(_, plugin) {
  20. const state = plugin.state.data;
  21. const reprs = state.select(StateSelection.Generators.ofType(PluginStateObject.Molecule.Structure.Representation3D));
  22. const update = state.build();
  23. let changed = false;
  24. for (const r of reprs) {
  25. const explodes = state.select(StateSelection.Generators.ofTransformer(StateTransforms.Representation.ExplodeStructureRepresentation3D, r.transform.ref));
  26. if (explodes.length > 0) continue;
  27. changed = true;
  28. update.to(r.transform.ref)
  29. .apply(StateTransforms.Representation.ExplodeStructureRepresentation3D, { t: 0 }, { tags: 'animate-units-explode' });
  30. }
  31. if (!changed) return;
  32. return update.commit({ doNotUpdateCurrent: true });
  33. },
  34. teardown(_, __, plugin) {
  35. const state = plugin.state.data;
  36. const reprs = state.select(StateSelection.Generators.ofType(PluginStateObject.Molecule.Structure.Representation3DState)
  37. .withTag('animate-units-explode'));
  38. if (reprs.length === 0) return;
  39. const update = state.build();
  40. for (const r of reprs) update.delete(r.transform.ref);
  41. return update.commit();
  42. },
  43. async apply(animState, t, ctx) {
  44. const state = ctx.plugin.state.data;
  45. const anims = state.select(StateSelection.Generators.ofTransformer(StateTransforms.Representation.ExplodeStructureRepresentation3D));
  46. if (anims.length === 0) {
  47. return { kind: 'finished' };
  48. }
  49. const update = state.build();
  50. const d = (t.current - t.lastApplied) / ctx.params.durationInMs;
  51. const newTime = (animState.t + d) % 1;
  52. for (const m of anims) {
  53. update.to(m).update({ t: newTime });
  54. }
  55. await PluginCommands.State.Update(ctx.plugin, { state, tree: update, options: { doNotLogTiming: true } });
  56. return { kind: 'next', state: { t: newTime } };
  57. }
  58. });