ImageTool.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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) => {
  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(({ width, height }: any) => {
  48. let objWidth = width;
  49. let objHeight = height;
  50. if (width > viewport.width || height > viewport.height) {
  51. const widthRate = viewport.width / width;
  52. objWidth = width * widthRate - 100;
  53. objHeight = height * widthRate - 100;
  54. }
  55. const annotData = {
  56. obj_type: ANNOTATION_TYPE.image,
  57. obj_attr: {
  58. page: currentPage,
  59. position: {
  60. top: viewport.height / 2 - objHeight / 2,
  61. left: viewport.width / 2 - objWidth / 2,
  62. bottom: viewport.height / 2 + objHeight / 2,
  63. right: viewport.width / 2 + objWidth / 2,
  64. },
  65. src: objectUrl,
  66. },
  67. };
  68. const imageObj = appendUserIdAndDate(
  69. parseAnnotationObject(annotData, viewport.height, scale)
  70. );
  71. addAnnots([imageObj]);
  72. });
  73. }
  74. }
  75. };
  76. return (
  77. <BtnWrapper>
  78. <Button shouldFitContainer align="left" onClick={handleClick}>
  79. <Icon glyph="add-image" style={{ marginRight: '10px' }} />
  80. {t('addImages')}
  81. </Button>
  82. <FileInput
  83. type="file"
  84. ref={inputRef}
  85. accept="image/*"
  86. onChange={handleFiles}
  87. />
  88. </BtnWrapper>
  89. );
  90. };
  91. export default ImageTool;