Source: lib/sys/ext/htmltex.js

  1. import AssetKeepr from '../../xutils/assetkeepr.js';
  2. import XSys from '../xsys';
  3. import {Visual, Canvas, AssetType} from '../../component/visual.js'
  4. import {Obj3, Obj3Type} from '../../component/obj3.js'
  5. const iffall = ['Visual', 'Canvas', 'Obj3'];
  6. /**Rendering html content as dynamic texture.
  7. *
  8. * This system take each entity with one and only one html content, then rendering
  9. * to multiple THREE.Object3D in scene with help of xv.ecs.sys.Thrender.
  10. *
  11. * Htmltex is an extension of ECS.subsystems. User must add it to ECS explicitly.
  12. * To create a new instance, entities definition must provided as options arg of
  13. * constructor.
  14. *
  15. * These definition can be generated with help of Htmltex.createEntityDefs()
  16. * For exmaple, see htmltex.case.js
  17. *
  18. * @class Htmltex
  19. */
  20. export default class Htmltex extends XSys {
  21. /**
  22. * @param {ECS} ecs
  23. * @param {object} options
  24. * @constructor Htmltex
  25. */
  26. constructor(ecs, options) {
  27. super(ecs);
  28. this.ecs = ecs;
  29. // keeping canvas map for update later
  30. this.canvas = new Object();
  31. var canvEnts = ecs.queryEntities({iffall});
  32. for(var e of canvEnts) {
  33. this.canvas[e.Canvas.domId] = e.Canvas;
  34. }
  35. }
  36. /**
  37. * @param {int} tick
  38. * @param {Entity[]} entities
  39. * @member Htmltex#refresh
  40. * @function
  41. */
  42. update(tick, entities) {
  43. for (const e of entities) {
  44. var m = e.Obj3.mesh
  45. if (e.Canvas.dirty && m) {
  46. e.Canvas.dirty = false;
  47. e.Canvas.tex.needsUpdate = true;
  48. m.material.map = e.Canvas.tex;
  49. }
  50. }
  51. }
  52. /**
  53. * Reload a Canvas texture from html, which will be updated atuomatically
  54. * when it's ready.
  55. *
  56. * @param {string} htmlId
  57. * @param {function} onRefresh
  58. * @member Htmltex#refresh
  59. * @function
  60. */
  61. refresh(htmlId, onRefresh) {
  62. const canv = this.canvas[htmlId];
  63. if (!canv) {
  64. console.error(`Htmltex.refresh(${htmlId}): component not found.`);
  65. }
  66. else {
  67. AssetKeepr.loadCanvtex(canv, undefined, onRefresh);
  68. }
  69. }
  70. /**
  71. * @param {object} options
  72. * options.objcanvas: array of [{domId, eid, texsize, visual}]<br>
  73. * where<br>
  74. * *objcanvas.domId*: string - canvs id for texture<br>
  75. * *objcanvas.eid*: string - optinal<br>
  76. * *objcanvas.texsize*: {width, height} - optinal, default 256x256<br>
  77. * *objcanvas.visual*: {vtype: AssetType} - optional, default AssetType.DomCanvas<br>
  78. * Other types are not supported.
  79. * @return {array<object>} entity definitions
  80. * @member Htmltex.createEntityDefs
  81. * @function
  82. */
  83. static createEntityDefs(options) {
  84. var {w, h} = options.plane ?
  85. {w: options.plane.w, h: options.plane.h} : {w: 100, h: 100};
  86. const entDefines = [];
  87. options.objcanvas.forEach(function(def, dx) {
  88. if (def.eid === undefined)
  89. def.eid = h5uuid();
  90. const wh = Object.assign({width: 256, height: 256},
  91. def.texsize || def.wh);
  92. const obj3 = Object.assign({
  93. geom: Obj3Type.PLANE,
  94. box: [w, h, 0], // plane size
  95. mesh: undefined }, // Thrender will handle this
  96. options.obj3);
  97. const vis = Object.assign({vtype: AssetType.DomCanvas },
  98. def.visual || def.Visual);
  99. var entidef = { id: def.eid,
  100. Obj3: obj3,
  101. Visual: vis,
  102. Canvas: {domId: def.domId,
  103. options: wh, // buffer texture canvas size
  104. },
  105. };
  106. entDefines.push(entidef);
  107. });
  108. return entDefines;
  109. }
  110. }
  111. Htmltex.query = { has: iffall };
  112. var myH5uuid = 0;
  113. /**
  114. * @memberof Htmltex */
  115. function h5uuid() {
  116. return `htmltex-${myH5uuid++}`;
  117. }