TextSprite.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // /**
  2. // * adapted from http://stemkoski.github.io/Three.js/Sprite-Text-Labels.html
  3. // */
  4. import * as THREE from "../libs/three.js/build/three.module.js";
  5. export class TextSprite extends THREE.Object3D{//old
  6. constructor(text){
  7. super();
  8. let texture = new THREE.Texture();
  9. texture.minFilter = THREE.LinearFilter;
  10. texture.magFilter = THREE.LinearFilter;
  11. let spriteMaterial = new THREE.SpriteMaterial({
  12. map: texture,
  13. depthTest: false,
  14. depthWrite: false});
  15. this.texture = texture;
  16. this.material = spriteMaterial;
  17. //this.material = getRawMaterial(texture);
  18. this.sprite = new THREE.Sprite(this.material);
  19. this.add(this.sprite);
  20. this.borderThickness = 4;
  21. this.fontface = 'Arial';
  22. this.fontsize = 28;
  23. this.borderColor = { r: 0, g: 0, b: 0, a: 1.0 };
  24. this.backgroundColor = { r: 255, g: 255, b: 255, a: 1.0 };
  25. this.textColor = {r: 255, g: 255, b: 255, a: 1.0};
  26. this.text = '';
  27. this.setText(text);
  28. }
  29. setText(text){
  30. if (this.text !== text){
  31. this.text = text;
  32. this.update();
  33. }
  34. }
  35. setTextColor(color){
  36. this.textColor = color;
  37. this.update();
  38. }
  39. setBorderColor(color){
  40. this.borderColor = color;
  41. this.update();
  42. }
  43. setBackgroundColor(color){
  44. this.backgroundColor = color;
  45. this.update();
  46. }
  47. update(){
  48. let canvas = document.createElement('canvas');
  49. let context = canvas.getContext('2d');
  50. context.font = 'Bold ' + this.fontsize + 'px ' + this.fontface;
  51. // get size data (height depends only on font size)
  52. let metrics = context.measureText(this.text);
  53. let textWidth = metrics.width;
  54. let margin = 5;
  55. let spriteWidth = 2 * margin + textWidth + 2 * this.borderThickness;
  56. let spriteHeight = this.fontsize * 1.4 + 2 * this.borderThickness;
  57. context.canvas.width = spriteWidth;
  58. context.canvas.height = spriteHeight;
  59. context.font = 'Bold ' + this.fontsize + 'px ' + this.fontface;
  60. // background color
  61. context.fillStyle = 'rgba(' + this.backgroundColor.r + ',' + this.backgroundColor.g + ',' +
  62. this.backgroundColor.b + ',' + this.backgroundColor.a + ')';
  63. // border color
  64. context.strokeStyle = 'rgba(' + this.borderColor.r + ',' + this.borderColor.g + ',' +
  65. this.borderColor.b + ',' + this.borderColor.a + ')';
  66. context.lineWidth = this.borderThickness;
  67. this.roundRect(context, this.borderThickness / 2, this.borderThickness / 2,
  68. textWidth + this.borderThickness + 2 * margin, this.fontsize * 1.4 + this.borderThickness, 6);
  69. // text color
  70. context.strokeStyle = 'rgba(0, 0, 0, 1.0)';
  71. context.strokeText(this.text, this.borderThickness + margin, this.fontsize + this.borderThickness);
  72. context.fillStyle = 'rgba(' + this.textColor.r + ',' + this.textColor.g + ',' +
  73. this.textColor.b + ',' + this.textColor.a + ')';
  74. context.fillText(this.text, this.borderThickness + margin, this.fontsize + this.borderThickness);
  75. let texture = new THREE.Texture(canvas);
  76. texture.minFilter = THREE.LinearFilter;
  77. texture.magFilter = THREE.LinearFilter;
  78. texture.needsUpdate = true;
  79. //this.material.needsUpdate = true;
  80. // { // screen-space sprite
  81. // let [screenWidth, screenHeight] = [1620, 937];
  82. // let uniforms = this.sprite.material.uniforms;
  83. // let aspect = spriteHeight / spriteWidth;
  84. // let factor = 0.5;
  85. // let w = spriteWidth / screenWidth;
  86. // let h = spriteHeight / screenHeight;
  87. // uniforms.uScale.value = [2 * w, 2 * h];
  88. // //uniforms.uScale.value = [factor * 1, factor * aspect];
  89. // this.sprite.material.uniforms.map.value = texture;
  90. // }
  91. this.sprite.material.map = texture;
  92. this.texture = texture;
  93. this.sprite.scale.set(spriteWidth * 0.01, spriteHeight * 0.01, 1.0);
  94. }
  95. roundRect(ctx, x, y, w, h, r){
  96. ctx.beginPath();
  97. ctx.moveTo(x + r, y);
  98. ctx.lineTo(x + w - r, y);
  99. ctx.quadraticCurveTo(x + w, y, x + w, y + r);
  100. ctx.lineTo(x + w, y + h - r);
  101. ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
  102. ctx.lineTo(x + r, y + h);
  103. ctx.quadraticCurveTo(x, y + h, x, y + h - r);
  104. ctx.lineTo(x, y + r);
  105. ctx.quadraticCurveTo(x, y, x + r, y);
  106. ctx.closePath();
  107. ctx.fill();
  108. ctx.stroke();
  109. }
  110. }