Map0.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. export class Map {
  2. private mapData: any;
  3. private container: any;
  4. private div: any;
  5. private canvas: HTMLCanvasElement | undefined;
  6. private ctx: CanvasRenderingContext2D | undefined;
  7. private initialised = false;
  8. private unit = 10;
  9. private xCount = 0;
  10. private yCount = 0;
  11. private margin = 20;
  12. private xMax: number = Number.MIN_VALUE;
  13. private xMin: number = Number.MAX_VALUE;
  14. private yMax: number = Number.MIN_VALUE;
  15. private yMin: number = Number.MAX_VALUE;
  16. private scale: number;
  17. constructor(container: any) {
  18. this.container = container;
  19. }
  20. show(data?: any): void {
  21. this.mapData = data;
  22. this.initPanel(data);
  23. this.draw(data);
  24. }
  25. private initPanel(data: any): void{
  26. const walls = data.EntityList[0].Elements.Walls;
  27. const cols = data.EntityList[0].Elements.Columns;
  28. const doors = data.EntityList[0].Elements.Doors;
  29. for(const w of walls){
  30. if(w.OutLine.length > 0){
  31. this.findEdge(w.OutLine);
  32. } else {
  33. for(const p of w.Location.Points){
  34. this.xMax = Math.max(p.X, this.xMax);
  35. this.xMin = Math.min(p.X, this.xMin);
  36. this.yMax = Math.max(p.Y, this.yMax);
  37. this.yMin = Math.min(p.Y, this.yMin);
  38. }
  39. }
  40. }
  41. for(const c of cols){
  42. this.findEdge(c.OutLine);
  43. }
  44. for(const d of doors){
  45. this.findEdge(d.OutLine);
  46. }
  47. for(const w of walls){
  48. if(w.OutLine.length > 0){
  49. this.moveToOrigin(w.OutLine);
  50. }
  51. for(const p of w.Location.Points){
  52. p.X -= this.xMin;
  53. p.Y -= this.yMin;
  54. }
  55. }
  56. for(const c of cols){
  57. this.moveToOrigin(c.OutLine);
  58. }
  59. for(const d of doors){
  60. this.moveToOrigin(d.OutLine);
  61. }
  62. this.xMax -= this.xMin;
  63. this.xMin = 0;
  64. this.yMax -= this.yMin;
  65. this.yMin = 0;
  66. this.scale = 10;
  67. const w = this.container.clientWidth;
  68. const h = this.container.clientHeight;
  69. this.div = document.createElement('div');
  70. this.div.style.width = (this.trans(this.xMax, this.margin) + this.margin) + 'px';
  71. this.div.style.height = (this.trans(this.yMax, this.margin) + this.margin) + 'px';
  72. this.container.appendChild(this.div);
  73. // this.scale = 5;
  74. // const w = 5000;
  75. // const h = 5000;
  76. const canvas = document.createElement('canvas');
  77. var ratio = 1; //window.devicePixelRatio || 1;
  78. canvas.width = w * ratio; // 实际渲染像素
  79. canvas.height = h * ratio; // 实际渲染像素
  80. canvas.style.width = w + 'px'; // 控制显示大小
  81. canvas.style.height = h + 'px'; // 控制显示大小
  82. canvas.style.pointerEvents = 'none';
  83. canvas.style.position = 'relative';
  84. this.div.appendChild(canvas);
  85. this.canvas = canvas;
  86. this.container.addEventListener("scroll", ()=>{this.redrawOnScroll(this)});
  87. const ctx = canvas.getContext('2d');
  88. // ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
  89. if (ctx) {
  90. ctx.translate(0.5, 0.5);
  91. this.ctx = ctx;
  92. } else {
  93. throw new Error('Canvas 2D context not found, please check it is running in Browser environment.');
  94. }
  95. this.paintBg();
  96. this.initialised = true;
  97. }
  98. private paintBg(){
  99. for(var x = this.unit; x < this.canvas.width; x += this.unit){
  100. this.xCount++;
  101. if(this.xCount % 5 == 0)
  102. this.ctx.strokeStyle = "#f1f1f1";
  103. else
  104. this.ctx.strokeStyle = "#f7f7f7";
  105. this.ctx.beginPath();
  106. this.ctx.moveTo(x, 0);
  107. this.ctx.lineTo(x, this.canvas.height);
  108. this.ctx.stroke();
  109. }
  110. for(var y = this.unit; y < this.canvas.height; y += this.unit){
  111. this.yCount++;
  112. if(this.yCount % 5 == 0)
  113. this.ctx.strokeStyle = "#f4f4f4";
  114. else
  115. this.ctx.strokeStyle = "#fafafa";
  116. this.ctx.beginPath();
  117. this.ctx.moveTo(0, y);
  118. this.ctx.lineTo(this.canvas.width, y);
  119. this.ctx.stroke();
  120. }
  121. }
  122. private redrawOnScroll(_this) {
  123. _this.ctx.clearRect(-1, -1, _this.canvas.width + 1, _this.canvas.height + 1);
  124. const top = _this.container.scrollTop;
  125. const left = _this.container.scrollLeft;
  126. _this.canvas.style.top = top + 'px';
  127. _this.canvas.style.left = left + 'px';
  128. _this.paintBg();
  129. _this.draw(_this.mapData);
  130. }
  131. private findEdge(outlines: any): void{
  132. for(const o of outlines){
  133. for(const p of o){
  134. this.xMax = Math.max(p.X, this.xMax);
  135. this.xMin = Math.min(p.X, this.xMin);
  136. this.yMax = Math.max(p.Y, this.yMax);
  137. this.yMin = Math.min(p.Y, this.yMin);
  138. }
  139. }
  140. }
  141. private moveToOrigin(outlines: any): void{
  142. for(const o of outlines){
  143. for(const p of o){
  144. p.X -= this.xMin;
  145. p.Y -= this.yMin;
  146. }
  147. }
  148. }
  149. private paintOutlines(outlines: any): void{
  150. for(const o of outlines){
  151. var pre = null;
  152. for(const p of o){
  153. if(pre)
  154. this.drawLine(pre, p);
  155. pre = p;
  156. }
  157. }
  158. }
  159. private draw(data: any):void {
  160. const walls = data.EntityList[0].Elements.Walls;
  161. for(const w of walls){
  162. if(w.OutLine.length > 0){
  163. this.ctx.strokeStyle = "#cccccc";
  164. this.ctx.beginPath();
  165. this.paintOutlines(w.OutLine);
  166. this.ctx.stroke();
  167. // var p = w.OutLine[0][0];
  168. // this.drawText(w.Id, p);
  169. }
  170. /* else */
  171. {
  172. this.ctx.strokeStyle = "#78e28d";
  173. this.ctx.beginPath();
  174. var pre = null;
  175. for(const p of w.Location.Points){
  176. if(pre)
  177. this.drawLine(pre, p);
  178. pre = p;
  179. }
  180. this.ctx.stroke();
  181. }
  182. }
  183. this.ctx.strokeStyle = "#000000";
  184. const cols = data.EntityList[0].Elements.Columns;
  185. for(const c of cols){
  186. if(!c.RoomBoundary)
  187. continue;
  188. this.ctx.beginPath();
  189. this.paintOutlines(c.OutLine);
  190. this.ctx.stroke();
  191. }
  192. this.ctx.strokeStyle = "#b65b00";
  193. const doors = data.EntityList[0].Elements.Doors;
  194. for(const d of doors){
  195. this.ctx.beginPath();
  196. this.paintOutlines(d.OutLine);
  197. this.ctx.stroke();
  198. }
  199. }
  200. private drawLine(p1: any, p2: any) {
  201. this.ctx.moveTo(this.transX(p1.X), this.transY(p1.Y));
  202. this.ctx.lineTo(this.transX(p2.X), this.transY(p2.Y));
  203. }
  204. private trans(x: number, offset: number): number {
  205. return Math.round(x/this.scale + offset);
  206. }
  207. private transX(x: number): number {
  208. return Math.round(x/this.scale + this.margin - this.container.scrollLeft);
  209. }
  210. private transY(y: number): number {
  211. return Math.round(y/this.scale + this.margin - this.container.scrollTop);
  212. }
  213. private drawText(text: string, point: any):void{
  214. const fontSize = 10;
  215. this.ctx.font = "lighter " + fontSize + "px Microsoft YaHei";
  216. this.ctx.textBaseline = "bottom";
  217. this.ctx.strokeStyle = "#000000";
  218. this.ctx.strokeText(text, this.transX(point.X), this.transY(point.Y));
  219. }
  220. }