ImageTool.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import React, { useRef } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import styled from 'styled-components';
  4. import Button from '../components/Button';
  5. import Icon from '../components/Icon';
  6. import { ANNOTATION_TYPE } from '../constants';
  7. import {
  8. parseAnnotationObject,
  9. appendUserIdAndDate,
  10. } from '../helpers/annotation';
  11. import useStore from '../store';
  12. import useActions from '../actions';
  13. import { BtnWrapper } from '../global/toolStyled';
  14. type Props = {
  15. onClickSidebar: (state: string) => void;
  16. };
  17. const FileInput = styled.input`
  18. display: none;
  19. `;
  20. const ImageTool: React.FC<Props> = ({ onClickSidebar }: Props) => {
  21. const { t } = useTranslation('sidebar');
  22. const inputRef = useRef<HTMLInputElement>(null);
  23. const [{ currentPage, viewport, scale }, dispatch] = useStore();
  24. const { addAnnots } = useActions(dispatch);
  25. const handleClick = () => {
  26. onClickSidebar('add-image');
  27. if (inputRef.current) {
  28. inputRef.current.click();
  29. }
  30. };
  31. const getImgDimension = (url: string): Promise<ViewportType> => {
  32. return new Promise((resolve) => {
  33. const img = new Image();
  34. img.src = url;
  35. img.onload = () => {
  36. resolve({ width: img.width, height: img.height });
  37. };
  38. });
  39. };
  40. const handleFiles = (e: React.FormEvent<EventTarget>) => {
  41. e.stopPropagation();
  42. e.preventDefault();
  43. if (inputRef.current && inputRef.current.files) {
  44. const file = inputRef.current.files[0];
  45. if (file) {
  46. const objectUrl = window.URL.createObjectURL(file);
  47. getImgDimension(objectUrl).then(
  48. ({ width, height }: ViewportType): void => {
  49. let objWidth = width;
  50. let objHeight = height;
  51. if (width > viewport.width || height > viewport.height) {
  52. const widthRate = viewport.width / width;
  53. objWidth = width * widthRate - 100;
  54. objHeight = height * widthRate - 100;
  55. }
  56. const annotData = {
  57. obj_type: ANNOTATION_TYPE.image,
  58. obj_attr: {
  59. page: currentPage,
  60. position: {
  61. top: viewport.height / 2 - objHeight / 2,
  62. left: viewport.width / 2 - objWidth / 2,
  63. bottom: viewport.height / 2 + objHeight / 2,
  64. right: viewport.width / 2 + objWidth / 2,
  65. },
  66. src: objectUrl,
  67. },
  68. };
  69. const imageObj = appendUserIdAndDate(
  70. parseAnnotationObject(annotData, viewport.height, scale),
  71. );
  72. addAnnots([imageObj]);
  73. },
  74. );
  75. }
  76. }
  77. };
  78. return (
  79. <BtnWrapper>
  80. <Button shouldFitContainer align="left" onClick={handleClick}>
  81. <Icon glyph="add-image" style={{ marginRight: '10px' }} />
  82. {t('addImages')}
  83. </Button>
  84. <FileInput
  85. type="file"
  86. ref={inputRef}
  87. accept="image/*"
  88. onChange={handleFiles}
  89. />
  90. </BtnWrapper>
  91. );
  92. };
  93. export default ImageTool;