vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
5.0 KiB

  1. import NodeBase from '../util/NodeBase'
  2. /**
  3. * NOTE: This is a bad base class
  4. *
  5. * Child classes are:
  6. *
  7. * Image - uses *only* image methods
  8. * Circle - uses *only* _drawRawCircle
  9. * CircleImage - uses all
  10. *
  11. * TODO: Refactor, move _drawRawCircle to different module, derive Circle from NodeBase
  12. * Rename this to ImageBase
  13. * Consolidate common code in Image and CircleImage to base class
  14. */
  15. class CircleImageBase extends NodeBase {
  16. constructor(options, body, labelModule) {
  17. super(options, body, labelModule);
  18. this.labelOffset = 0;
  19. this.selected = false;
  20. }
  21. setOptions(options, imageObj, imageObjAlt) {
  22. this.options = options;
  23. this.setImages(imageObj, imageObjAlt);
  24. }
  25. setImages(imageObj, imageObjAlt) {
  26. if (imageObjAlt && this.selected) {
  27. this.imageObj = imageObjAlt;
  28. this.imageObjAlt = imageObj;
  29. } else {
  30. this.imageObj = imageObj;
  31. this.imageObjAlt = imageObjAlt;
  32. }
  33. }
  34. /**
  35. * Switch between the base and the selected image.
  36. */
  37. switchImages(selected) {
  38. if ((selected && !this.selected) || (!selected && this.selected)) {
  39. let imageTmp = this.imageObj;
  40. this.imageObj = this.imageObjAlt;
  41. this.imageObjAlt = imageTmp;
  42. }
  43. // keep current state in memory
  44. this.selected = selected;
  45. }
  46. /**
  47. * Adjust the node dimensions for a loaded image.
  48. *
  49. * Pre: this.imageObj is valid
  50. */
  51. _resizeImage() {
  52. var width, height;
  53. if (this.options.shapeProperties.useImageSize === false) {
  54. // Use the size property
  55. var ratio_width = 1;
  56. var ratio_height = 1;
  57. // Only calculate the proper ratio if both width and height not zero
  58. if (this.imageObj.width && this.imageObj.height) {
  59. if (this.imageObj.width > this.imageObj.height) {
  60. ratio_width = this.imageObj.width / this.imageObj.height;
  61. }
  62. else {
  63. ratio_height = this.imageObj.height / this.imageObj.width;
  64. }
  65. }
  66. width = this.options.size * 2 * ratio_width;
  67. height = this.options.size * 2 * ratio_height;
  68. }
  69. else {
  70. // Use the image size
  71. width = this.imageObj.width;
  72. height = this.imageObj.height;
  73. }
  74. this.width = width;
  75. this.height = height;
  76. this.radius = 0.5 * this.width;
  77. }
  78. _drawRawCircle(ctx, x, y, values) {
  79. var borderWidth = values.borderWidth / this.body.view.scale;
  80. ctx.lineWidth = Math.min(this.width, borderWidth);
  81. ctx.strokeStyle = values.borderColor;
  82. ctx.fillStyle = values.color;
  83. ctx.circle(x, y, values.size);
  84. // draw shadow if enabled
  85. this.enableShadow(ctx, values);
  86. // draw the background
  87. ctx.fill();
  88. // disable shadows for other elements.
  89. this.disableShadow(ctx, values);
  90. //draw dashed border if enabled, save and restore is required for firefox not to crash on unix.
  91. ctx.save();
  92. // if borders are zero width, they will be drawn with width 1 by default. This prevents that
  93. if (borderWidth > 0) {
  94. this.enableBorderDashes(ctx, values);
  95. //draw the border
  96. ctx.stroke();
  97. //disable dashed border for other elements
  98. this.disableBorderDashes(ctx, values);
  99. }
  100. ctx.restore();
  101. }
  102. _drawImageAtPosition(ctx, values) {
  103. if (this.imageObj.width != 0) {
  104. // draw the image
  105. ctx.globalAlpha = 1.0;
  106. // draw shadow if enabled
  107. this.enableShadow(ctx, values);
  108. let factor = (this.imageObj.width / this.width) / this.body.view.scale;
  109. if (factor > 2 && this.options.shapeProperties.interpolation === true) {
  110. let w = this.imageObj.width;
  111. let h = this.imageObj.height;
  112. var can2 = document.createElement('canvas');
  113. can2.width = w;
  114. can2.height = w;
  115. var ctx2 = can2.getContext('2d');
  116. factor *= 0.5;
  117. w *= 0.5;
  118. h *= 0.5;
  119. ctx2.drawImage(this.imageObj, 0, 0, w, h);
  120. let distance = 0;
  121. let iterations = 1;
  122. while (factor > 2 && iterations < 4) {
  123. ctx2.drawImage(can2, distance, 0, w, h, distance+w, 0, w/2, h/2);
  124. distance += w;
  125. factor *= 0.5;
  126. w *= 0.5;
  127. h *= 0.5;
  128. iterations += 1;
  129. }
  130. ctx.drawImage(can2, distance, 0, w, h, this.left, this.top, this.width, this.height);
  131. }
  132. else {
  133. // draw image
  134. ctx.drawImage(this.imageObj, this.left, this.top, this.width, this.height);
  135. }
  136. // disable shadows for other elements.
  137. this.disableShadow(ctx, values);
  138. }
  139. }
  140. _drawImageLabel(ctx, x, y, selected, hover) {
  141. var yLabel;
  142. var offset = 0;
  143. if (this.height !== undefined) {
  144. offset = this.height * 0.5;
  145. var labelDimensions = this.labelModule.getTextSize(ctx, selected, hover);
  146. if (labelDimensions.lineCount >= 1) {
  147. offset += labelDimensions.height / 2;
  148. }
  149. }
  150. yLabel = y + offset;
  151. if (this.options.label) {
  152. this.labelOffset = offset;
  153. }
  154. this.labelModule.draw(ctx, x, yLabel, selected, hover, 'hanging');
  155. }
  156. }
  157. export default CircleImageBase;