Image.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import Displayable, { DisplayableProps,
  2. CommonStyleProps,
  3. DEFAULT_COMMON_STYLE,
  4. DisplayableStatePropNames,
  5. DEFAULT_COMMON_ANIMATION_PROPS
  6. } from './Displayable';
  7. import BoundingRect from '../core/BoundingRect';
  8. import { ImageLike, MapToType } from '../core/types';
  9. import { defaults, createObject } from '../core/util';
  10. import { ElementCommonState } from '../Element';
  11. export interface ImageStyleProps extends CommonStyleProps {
  12. image?: string | ImageLike
  13. x?: number
  14. y?: number
  15. width?: number
  16. height?: number
  17. sx?: number
  18. sy?: number
  19. sWidth?: number
  20. sHeight?: number
  21. }
  22. export const DEFAULT_IMAGE_STYLE: CommonStyleProps = defaults({
  23. x: 0,
  24. y: 0
  25. }, DEFAULT_COMMON_STYLE);
  26. export const DEFAULT_IMAGE_ANIMATION_PROPS: MapToType<ImageProps, boolean> = {
  27. style: defaults<MapToType<ImageStyleProps, boolean>, MapToType<ImageStyleProps, boolean>>({
  28. x: true,
  29. y: true,
  30. width: true,
  31. height: true,
  32. sx: true,
  33. sy: true,
  34. sWidth: true,
  35. sHeight: true
  36. }, DEFAULT_COMMON_ANIMATION_PROPS.style)
  37. };
  38. export interface ImageProps extends DisplayableProps {
  39. style?: ImageStyleProps
  40. onload?: (image: ImageLike) => void
  41. }
  42. export type ImageState = Pick<ImageProps, DisplayableStatePropNames> & ElementCommonState
  43. function isImageLike(source: unknown): source is HTMLImageElement {
  44. return !!(source
  45. && typeof source !== 'string'
  46. // Image source is an image, canvas, video.
  47. && (source as HTMLImageElement).width && (source as HTMLImageElement).height);
  48. }
  49. class ZRImage extends Displayable<ImageProps> {
  50. style: ImageStyleProps
  51. // FOR CANVAS RENDERER
  52. __image: ImageLike
  53. // FOR SVG RENDERER
  54. __imageSrc: string
  55. onload: (image: ImageLike) => void
  56. /**
  57. * Create an image style object with default values in it's prototype.
  58. * @override
  59. */
  60. createStyle(obj?: ImageStyleProps) {
  61. return createObject(DEFAULT_IMAGE_STYLE, obj);
  62. }
  63. private _getSize(dim: 'width' | 'height') {
  64. const style = this.style;
  65. let size = style[dim];
  66. if (size != null) {
  67. return size;
  68. }
  69. const imageSource = isImageLike(style.image)
  70. ? style.image : this.__image;
  71. if (!imageSource) {
  72. return 0;
  73. }
  74. const otherDim = dim === 'width' ? 'height' : 'width';
  75. let otherDimSize = style[otherDim];
  76. if (otherDimSize == null) {
  77. return imageSource[dim];
  78. }
  79. else {
  80. return imageSource[dim] / imageSource[otherDim] * otherDimSize;
  81. }
  82. }
  83. getWidth(): number {
  84. return this._getSize('width');
  85. }
  86. getHeight(): number {
  87. return this._getSize('height');
  88. }
  89. getAnimationStyleProps() {
  90. return DEFAULT_IMAGE_ANIMATION_PROPS;
  91. }
  92. getBoundingRect(): BoundingRect {
  93. const style = this.style;
  94. if (!this._rect) {
  95. this._rect = new BoundingRect(
  96. style.x || 0, style.y || 0, this.getWidth(), this.getHeight()
  97. );
  98. }
  99. return this._rect;
  100. }
  101. }
  102. ZRImage.prototype.type = 'image';
  103. export default ZRImage;