animation-graph-variant.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. exports.template = `
  2. <section class="asset-animation-graph-variant">
  3. <ui-prop>
  4. <ui-label slot="label" value="Animation Graph"></ui-label>
  5. <ui-asset slot="content" droppable="cc.animation.AnimationGraph" class="graph-asset"></ui-asset>
  6. </ui-prop>
  7. <ui-section class="clips" expand>
  8. <ui-label slot="header" value="Clip Overrides"></ui-label>
  9. <table class="table">
  10. <thead class="thead">
  11. <tr>
  12. <td>Original</td>
  13. <td>Override</td>
  14. </tr>
  15. </thead>
  16. <tbody class="tbody">
  17. </tbody>
  18. </table>
  19. </ui-section>
  20. </section>
  21. `;
  22. exports.$ = {
  23. container: '.asset-animation-graph-variant',
  24. graphAsset: '.graph-asset',
  25. table: '.table',
  26. tbody: '.tbody',
  27. };
  28. exports.style = `
  29. .asset-animation-graph-variant {
  30. padding-top: 4px;
  31. padding-right: 4px;
  32. }
  33. .asset-animation-graph-variant .clips {
  34. padding-top: 10px;
  35. padding-bottom: 10px;
  36. }
  37. .asset-animation-graph-variant .table {
  38. border-collapse: collapse;
  39. margin-left: -8px;
  40. }
  41. .asset-animation-graph-variant .thead td {
  42. text-align: center;
  43. width: 50%;
  44. }
  45. .asset-animation-graph-variant .tbody td {
  46. padding: 13px 5px 5px 5px;
  47. }
  48. .asset-animation-graph-variant .tbody ui-asset {
  49. width: 100%;
  50. }
  51. `;
  52. exports.methods = {
  53. record() {
  54. return JSON.stringify(this.animationGraphVariant);
  55. },
  56. async restore(record) {
  57. record = JSON.parse(record);
  58. if (!record || typeof record !== 'object') {
  59. return false;
  60. }
  61. this.animationGraphVariant = record;
  62. await this.change();
  63. return true;
  64. },
  65. async query(uuid) {
  66. return await Editor.Message.request('scene', 'query-animation-graph-variant', uuid);
  67. },
  68. async apply() {
  69. this.reset();
  70. await Editor.Message.request('scene', 'apply-animation-graph-variant', this.asset.uuid, this.animationGraphVariant);
  71. },
  72. abort() {
  73. this.reset();
  74. },
  75. reset() {
  76. /**
  77. * reset 环节只需把 uuid 清空
  78. * 会重新进入 panel.update 周期,根据 uuid 为空的条件,把 this.dirtyData.origin 重新填充
  79. */
  80. this.dirtyData.uuid = '';
  81. },
  82. async change() {
  83. this.animationGraphVariant = await Editor.Message.request('scene', 'change-animation-graph-variant', this.animationGraphVariant);
  84. this.updateInterface();
  85. this.setDirtyData();
  86. this.dispatch('change');
  87. },
  88. updateInterface() {
  89. this.$.graphAsset.value = this.animationGraphVariant.graphUuid;
  90. this.$.graphAsset.readonly = this.asset.readonly;
  91. const oldPropKeys = Object.keys(this.$props);
  92. const newPropKeys = Object.keys(this.animationGraphVariant.clips);
  93. for (const key in this.animationGraphVariant.clips) {
  94. // reuse
  95. if (!this.$props[key]) {
  96. this.$props[key] = document.createElement('tr');
  97. const originTd = document.createElement('td');
  98. this.$props[key].$origin = document.createElement('ui-asset');
  99. this.$props[key].$origin.setAttribute('disabled', '');
  100. this.$props[key].$origin.droppable = 'cc.AnimationClip';
  101. originTd.appendChild(this.$props[key].$origin);
  102. const overrideTd = document.createElement('td');
  103. this.$props[key].$override = document.createElement('ui-asset');
  104. this.$props[key].$override.droppable = 'cc.AnimationClip';
  105. this.$props[key].$override.addEventListener('confirm', (event) => {
  106. this.animationGraphVariant.clips[key] = event.target.value;
  107. this.change();
  108. });
  109. overrideTd.appendChild(this.$props[key].$override);
  110. this.$props[key].appendChild(originTd);
  111. this.$props[key].appendChild(overrideTd);
  112. }
  113. this.$.tbody.appendChild(this.$props[key]);
  114. this.$props[key].$origin.value = key;
  115. this.$props[key].$override.value = this.animationGraphVariant.clips[key];
  116. this.$props[key].$override.readonly = this.asset.readonly;
  117. }
  118. for (const key of oldPropKeys) {
  119. if (!newPropKeys.includes(key)) {
  120. const $prop = this.$props[key];
  121. if ($prop && $prop.parentElement) {
  122. $prop.parentElement.removeChild($prop);
  123. }
  124. }
  125. }
  126. },
  127. /**
  128. * Detection of data changes only determines the currently selected technique
  129. */
  130. setDirtyData() {
  131. this.dirtyData.realtime = JSON.stringify(this.animationGraphVariant);
  132. if (!this.dirtyData.origin) {
  133. this.dirtyData.origin = this.dirtyData.realtime;
  134. this.dispatch('snapshot');
  135. }
  136. },
  137. isDirty() {
  138. const isDirty = this.dirtyData.origin !== this.dirtyData.realtime;
  139. return isDirty;
  140. },
  141. };
  142. exports.ready = function() {
  143. // Used to determine whether the material has been modified in isDirty()
  144. this.dirtyData = {
  145. uuid: '',
  146. origin: '',
  147. realtime: '',
  148. };
  149. this.$props = {};
  150. this.$.graphAsset.addEventListener('confirm', (event) => {
  151. this.animationGraphVariant.graphUuid = event.target.value;
  152. this.change();
  153. });
  154. };
  155. exports.update = async function(assetList, metaList) {
  156. this.assetList = assetList;
  157. this.metaList = metaList;
  158. this.asset = assetList[0];
  159. this.meta = metaList[0];
  160. if (assetList.length !== 1) {
  161. this.$.container.innerText = Editor.I18n.t('ENGINE.assets.multipleWarning');
  162. return;
  163. }
  164. if (this.dirtyData.uuid !== this.asset.uuid) {
  165. this.dirtyData.uuid = this.asset.uuid;
  166. this.dirtyData.origin = '';
  167. }
  168. this.animationGraphVariant = await this.query(this.asset.uuid);
  169. this.updateInterface();
  170. this.setDirtyData();
  171. };
  172. exports.close = function() {
  173. // Used to determine whether the material has been modified in isDirty()
  174. this.dirtyData = {
  175. uuid: '',
  176. origin: '',
  177. realtime: '',
  178. };
  179. };