TextToImage.jsx 2.9 KB
Newer Older
fisherdaddy's avatar
fisherdaddy committed
1 2
import React, { useState, useRef, useEffect } from 'react';
import styled from 'styled-components';
fisherdaddy's avatar
fisherdaddy committed
3
import { Title, Wrapper, Container, InputText, PreviewContainer, Preview } from '../js/SharedStyles';
4
import { useTranslation } from '../js/i18n';
fisherdaddy's avatar
fisherdaddy committed
5
import SEO from '../components/SEO';
fisherdaddy's avatar
fisherdaddy committed
6 7

const DownloadButton = styled.button`
fisherdaddy's avatar
fisherdaddy committed
8
  padding: 8px 16px;
fisherdaddy's avatar
fisherdaddy committed
9 10 11
  background-color: #3498db;
  color: white;
  border: none;
fisherdaddy's avatar
fisherdaddy committed
12
  border-radius: 4px;
fisherdaddy's avatar
fisherdaddy committed
13
  cursor: pointer;
fisherdaddy's avatar
fisherdaddy committed
14
  font-size: 14px;
fisherdaddy's avatar
fisherdaddy committed
15 16
  transition: background-color 0.3s ease;
  align-self: flex-end;
fisherdaddy's avatar
fisherdaddy committed
17
  margin-top: 10px;
fisherdaddy's avatar
fisherdaddy committed
18 19 20 21 22 23 24

  &:hover {
    background-color: #2980b9;
  }
`;

function TextToImage() {
25
  const { t } = useTranslation();
fisherdaddy's avatar
fisherdaddy committed
26 27 28 29 30
  const [text, setText] = useState('');
  const previewRef = useRef(null);

  const formatText = (text) => {
    return text
31 32 33
      .replace(/^### (.*$)/gim, '<h4>$1</h4>')
      .replace(/^## (.*$)/gim, '<h3>$1</h3>')
      .replace(/^# (.*$)/gim, '<h2>$1</h2>')
fisherdaddy's avatar
fisherdaddy committed
34
      .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
35
      .replace(/\n{2,}/g, '<br/><br/>') 
fisherdaddy's avatar
fisherdaddy committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
      .replace(/\n/g, '<br/>');
  };

  const handleDownload = async () => {
    const previewClone = previewRef.current.cloneNode(true);
    document.body.appendChild(previewClone);
    previewClone.style.position = 'absolute';
    previewClone.style.left = '-9999px';
    previewClone.style.width = 'auto';
    previewClone.style.maxWidth = '800px';
    previewClone.style.height = 'auto';
    previewClone.style.whiteSpace = 'pre-wrap';
    previewClone.style.backgroundColor = 'white';
    previewClone.style.padding = '40px';
    
    try {
      const html2canvas = (await import('html2canvas')).default;
      const canvas = await html2canvas(previewClone, {
        backgroundColor: 'white',
        scale: 2,
        width: previewClone.offsetWidth,
        height: previewClone.offsetHeight
      });

      const link = document.createElement('a');
      link.download = 'text_image.png';
      link.href = canvas.toDataURL('image/png');
      link.click();
    } catch (error) {
      console.error('Failed to load html2canvas:', error);
    } finally {
      document.body.removeChild(previewClone);
    }
  };

  return (
fisherdaddy's avatar
fisherdaddy committed
72 73 74 75 76 77 78 79 80 81 82 83
    <>
      <SEO
        title={t('tools.text2image.title')}
        description={t('tools.text2image.description')}
      />
      <Wrapper>
        <Title>{t('tools.text2image.title')}</Title>
        <Container>
          <InputText
            placeholder={t('tools.text2image.inputPlaceholder')}
            value={text}
            onChange={(e) => setText(e.target.value)}
fisherdaddy's avatar
fisherdaddy committed
84
          />
fisherdaddy's avatar
fisherdaddy committed
85 86 87 88 89 90 91 92 93 94 95 96
          <PreviewContainer>
            <Preview
              ref={previewRef}
              dangerouslySetInnerHTML={{ __html: formatText(text) }}
            />
            <DownloadButton onClick={handleDownload}>
              {t('tools.text2image.downloadButton')}
            </DownloadButton>
          </PreviewContainer>
        </Container>
      </Wrapper>
    </>
fisherdaddy's avatar
fisherdaddy committed
97 98 99 100
  );
}

export default TextToImage;