{"id":203,"date":"2026-02-17T06:03:00","date_gmt":"2026-02-17T06:03:00","guid":{"rendered":"https:\/\/oualator.com\/calculate\/?p=203"},"modified":"2026-02-17T22:04:48","modified_gmt":"2026-02-17T22:04:48","slug":"heart-shape-text-generator","status":"publish","type":"post","link":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/","title":{"rendered":"Heart Shape Text Generator &#8211; Fill Heart Shape With Your Text"},"content":{"rendered":"\n<p>Express your words in the shape of a heart and express what you feel. This free online heart shape text generator tool is easy, fun, and has endless possibilities, whether you are writing a romantic message, creating a special greeting, or doing a typographical experiment!<\/p>\n\n\n\n<p>Just plug in your custom text, select the font style, set the size of the hearts, and change the colors to what feels good for you. Your text will now flow along the heart with just one click, which you can then share or download or <strong>Take a Screen Shot<\/strong> to keep as a souvenir.<\/p>\n\n\n\n<p>Ideal for Valentine cards, love notes, art projects, or just a little sprinkling of cuteness onto your words. For connecting the dots, you can use the <a href=\"https:\/\/oualator.com\/calculate\/dot-to-dot-generator\/\" target=\"_blank\" rel=\"noreferrer noopener\">Dot to dot generator<\/a>.<\/p>\n\n\n\n<p>So start below and let your words pour from the heart! \u2764\ufe0f. Worrying how to create this heart shape text, check the <a href=\"#guide\"><strong>Guide<\/strong><\/a> given below.<\/p>\n\n\n\n<link rel=\"stylesheet\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/@fortawesome\/fontawesome-free@6.4.0\/css\/all.min.css\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Quicksand:wght@300;400;500;600;700&#038;family=Roboto:wght@300;400;500;700&#038;family=Pacifico&#038;family=Lobster&#038;family=Open+Sans:wght@300;400;600;700&#038;family=Indie+Flower&#038;display=swap\" rel=\"stylesheet\">\n<script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n<script>\n  tailwind.config = {\n    corePlugins: {\n      preflight: false, \/\/ This prevents Tailwind from resetting your WP theme styles\n    }\n  }\n<\/script>\n\n<div id=\"heart-text-generator\" style=\"max-width: 100%; margin: 0 auto; font-family: Arial, sans-serif;\">\n  <style>\n    #heart-text-generator * { box-sizing: border-box; }\n    .checkerboard {\n      background-image:\n        linear-gradient(45deg, #f0f0f0 25%, transparent 25%),\n        linear-gradient(-45deg, #f0f0f0 25%, transparent 25%),\n        linear-gradient(45deg, transparent 75%, #f0f0f0 75%),\n        linear-gradient(-45deg, transparent 75%, #f0f0f0 75%);\n      background-size: 20px 20px;\n      background-position: 0 0, 0 10px, 10px -10px, -10px 0px;\n    }\n    .toggle-switch { position: relative; display: inline-block; width: 44px; height: 24px; }\n    .toggle-switch input { opacity: 0; width: 0; height: 0; }\n    .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .4s; border-radius: 24px; }\n    .slider:before { position: absolute; content: \"\"; height: 18px; width: 18px; left: 3px; bottom: 3px; background-color: white; transition: .4s; border-radius: 50%; }\n    input:checked + .slider { background-color: #3b82f6; }\n    input:checked + .slider:before { transform: translateX(20px); }\n\n    .text-instance { border: 2px solid #e5e7eb; border-radius: 8px; margin-bottom: 16px; transition: border-color 0.2s; word-wrap: break-word; overflow-wrap: break-word; }\n    .text-instance.active { border-color: #3b82f6; }\n    .text-instance .truncate { max-width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n\n    .font-quicksand { font-family: 'Quicksand', sans-serif; }\n    .font-roboto { font-family: 'Roboto', sans-serif; }\n    .font-pacifico { font-family: 'Pacifico', cursive; }\n    .font-lobster { font-family: 'Lobster', cursive; }\n    .font-opensans { font-family: 'Open Sans', sans-serif; }\n    .font-indie { font-family: 'Indie Flower', cursive; }\n\n    .canvas-container { position: relative; overflow: hidden; display: flex; justify-content: center; align-items: center; width: 100%; min-height: 300px; background: white; }\n    #heartCanvas { transform-origin: center center; transition: transform 0.2s ease; max-width: 100%; max-height: 100%; width: auto; height: auto; }\n\n    \/* True fullscreen styles *\/\n    .fullscreen-mode {\n      position: fixed !important;\n      top: 0 !important;\n      left: 0 !important;\n      width: 100vw !important;\n      height: 100vh !important;\n      z-index: 9999 !important;\n      background: white;\n      display: flex;\n      flex-direction: column;\n      justify-content: center;\n      align-items: center;\n      padding: 20px;\n    }\n\n    .fullscreen-mode .canvas-container {\n      width: 90vw !important;\n      height: 80vh !important;\n      max-width: none !important;\n      max-height: none !important;\n      min-height: 80vh !important;\n      border: none !important;\n      border-radius: 0 !important;\n    }\n\n    .fullscreen-mode #heartCanvas {\n      width: 100% !important;\n      height: 100% !important;\n      max-width: none !important;\n      max-height: none !important;\n    }\n\n    .fullscreen-exit-btn {\n      position: fixed;\n      top: 20px;\n      right: 20px;\n      background: #ef4444;\n      color: white;\n      border: none;\n      border-radius: 8px;\n      padding: 12px 20px;\n      font-size: 16px;\n      cursor: pointer;\n      display: flex;\n      align-items: center;\n      gap: 8px;\n      transition: all 0.2s ease;\n      z-index: 10001;\n      font-weight: 500;\n    }\n\n    .fullscreen-exit-btn:hover {\n      background: #dc2626;\n      transform: scale(1.05);\n    }\n\n    .fullscreen-title {\n      position: fixed;\n      top: 20px;\n      left: 20px;\n      color: #374151;\n      font-size: 24px;\n      font-weight: bold;\n      z-index: 10001;\n      display: flex;\n      align-items: center;\n      gap: 8px;\n    }\n\n    \/* Mobile responsive tweaks *\/\n    @media (max-width: 768px) {\n      .canvas-container { min-height: 250px; max-height: 60vh; }\n      #heartCanvas { max-width: 95%; max-height: 95%; }\n      .grid-cols-1 { grid-template-columns: 1fr; }\n      .controls-section { max-height: none; overflow-y: visible; }\n      .text-instance .truncate { max-width: 120px; }\n      .flex-col.md\\:flex-row { flex-direction: column; align-items: stretch; gap: 12px; }\n      .flex.flex-col.md\\:flex-row.items-start.md\\:items-center { align-items: stretch; }\n      \n      .fullscreen-mode .canvas-container {\n        width: 95vw !important;\n        height: 85vh !important;\n        min-height: 85vh !important;\n      }\n      .fullscreen-exit-btn {\n        padding: 10px 16px;\n        font-size: 14px;\n      }\n      .fullscreen-title {\n        font-size: 20px;\n      }\n    }\n    @media (max-width: 480px) {\n      .canvas-container { min-height: 200px; max-height: 50vh; }\n      #heartCanvas { max-width: 90%; max-height: 90%; }\n      .text-instance .truncate { max-width: 100px; }\n      \n      .fullscreen-mode .canvas-container {\n        width: 98vw !important;\n        height: 90vh !important;\n        min-height: 90vh !important;\n      }\n      .fullscreen-exit-btn {\n        top: 10px;\n        right: 10px;\n        padding: 8px 12px;\n        font-size: 12px;\n      }\n      .fullscreen-title {\n        top: 10px;\n        left: 10px;\n        font-size: 18px;\n      }\n    }\n    input[type=\"text\"], input[type=\"number\"], textarea, select { min-width: 0; width: 100%; }\n    @media (max-width: 640px) {\n      .btn-group { display: flex; flex-direction: column; gap: 8px; }\n      .btn-group button { width: 100%; }\n    }\n  <\/style>\n\n  <div class=\"max-w-7xl mx-auto p-2 sm:p-4\">\n    <h2 class=\"text-xl sm:text-2xl md:text-3xl font-bold text-center mb-4 sm:mb-6 text-gray-800 px-2\">\n      <i class=\"fas fa-heart text-red-500 mr-2\"><\/i>\n      Heart Shape Text Generator\n    <\/h2>\n\n    <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-3 sm:gap-4 md:gap-6\">\n      <!-- Control Panel -->\n      <div class=\"lg:col-span-1 controls-section space-y-3 sm:space-y-4 md:space-y-6\">\n        <!-- Text Instances -->\n        <div class=\"bg-white rounded-lg shadow-md p-3 sm:p-4 md:p-6\">\n          <div class=\"flex justify-between items-center mb-4\">\n            <h3 class=\"text-base sm:text-lg md:text-xl font-semibold\">Text Instances<\/h3>\n            <button id=\"addTextBtn\" class=\"bg-blue-500 hover:bg-blue-600 text-white px-2 sm:px-3 md:px-4 py-2 rounded-lg transition-colors text-xs sm:text-sm md:text-base\">\n              <i class=\"fas fa-plus mr-1 sm:mr-2\"><\/i>Add\n            <\/button>\n          <\/div>\n          <div id=\"textInstances\"><\/div>\n        <\/div>\n\n        <!-- Current Text Controls -->\n        <div class=\"bg-white rounded-lg shadow-md p-3 sm:p-4 md:p-6\" id=\"textControls\">\n          <h3 class=\"text-base sm:text-lg md:text-xl font-semibold mb-4\">Text Settings<\/h3>\n\n          <!-- Text Input -->\n          <div class=\"mb-4\">\n            <label class=\"block text-sm font-medium text-gray-700 mb-2\">Text Content<\/label>\n            <textarea id=\"textInput\" class=\"flex-1 p-2 sm:p-3 border border-gray-300 rounded-lg resize-none text-sm md:text-base\" rows=\"3\" placeholder=\"Enter a single word...\">I Love You<\/textarea>\n\n            <!-- Repeat Count -->\n            <div class=\"mt-3\">\n              <label class=\"block text-sm font-medium text-gray-700 mb-1\">Repeat Count<\/label>\n              <input type=\"number\" id=\"repeatCount\" value=\"10\" min=\"1\" class=\"w-full p-2 sm:p-3 border border-gray-300 rounded-lg text-sm md:text-base\">\n              <p class=\"text-xs text-gray-500 mt-1\">The word above will be repeated this many times along the heart path.<\/p>\n            <\/div>\n          <\/div>\n\n          <!-- Heart Size Control -->\n          <div class=\"mb-4\">\n            <label class=\"block text-sm font-medium text-gray-700 mb-2\">Heart Size: <span id=\"heartSizeValue\">100<\/span>%<\/label>\n            <input type=\"range\" id=\"heartSize\" min=\"50\" max=\"200\" value=\"100\" class=\"w-full\">\n          <\/div>\n\n          <!-- Font Selection -->\n          <div class=\"mb-4\">\n            <label class=\"block text-sm font-medium text-gray-700 mb-2\">Font Family<\/label>\n            <select id=\"fontFamily\" class=\"w-full p-2 sm:p-3 border border-gray-300 rounded-lg text-sm md:text-base\">\n              <option value=\"Pacifico\">Pacifico<\/option>\n              <option value=\"Quicksand\">Quicksand<\/option>\n              <option value=\"Roboto\">Roboto<\/option>\n              <option value=\"Lobster\">Lobster<\/option>\n              <option value=\"Open Sans\">Open Sans<\/option>\n              <option value=\"Indie Flower\">Indie Flower<\/option>\n            <\/select>\n          <\/div>\n\n          <!-- Font Size -->\n          <div class=\"mb-4\">\n            <label class=\"block text-sm font-medium text-gray-700 mb-2\">Font Size: <span id=\"fontSizeValue\">24<\/span>px<\/label>\n            <input type=\"range\" id=\"fontSize\" min=\"10\" max=\"60\" value=\"24\" class=\"w-full\">\n          <\/div>\n\n          <!-- Character Spacing -->\n          <div class=\"mb-4\">\n            <label class=\"block text-sm font-medium text-gray-700 mb-2\">Character Spacing<\/label>\n            <input type=\"number\" id=\"charSpacing\" value=\"0\" step=\"0.1\" class=\"w-full p-2 sm:p-3 border border-gray-300 rounded-lg text-sm md:text-base\">\n          <\/div>\n\n          <!-- X and Y Offset -->\n          <div class=\"grid grid-cols-2 gap-4 mb-4\">\n            <div>\n              <label class=\"block text-sm font-medium text-gray-700 mb-2\">X Offset<\/label>\n              <input type=\"number\" id=\"xOffset\" value=\"0\" class=\"w-full p-2 sm:p-3 border border-gray-300 rounded-lg text-sm md:text-base\">\n            <\/div>\n            <div>\n              <label class=\"block text-sm font-medium text-gray-700 mb-2\">Y Offset<\/label>\n              <input type=\"number\" id=\"yOffset\" value=\"0\" class=\"w-full p-2 sm:p-3 border border-gray-300 rounded-lg text-sm md:text-base\">\n            <\/div>\n          <\/div>\n\n          <!-- Text Alignment -->\n          <div class=\"mb-4\">\n            <label class=\"block text-sm font-medium text-gray-700 mb-2\">Text Alignment<\/label>\n            <div class=\"grid grid-cols-3 gap-2\">\n              <button class=\"align-btn p-2 md:p-3 border border-gray-300 rounded-lg hover:bg-gray-50 active\" data-align=\"start\">\n                <i class=\"fas fa-align-left\"><\/i>\n              <\/button>\n              <button class=\"align-btn p-2 md:p-3 border border-gray-300 rounded-lg hover:bg-gray-50\" data-align=\"middle\">\n                <i class=\"fas fa-align-center\"><\/i>\n              <\/button>\n              <button class=\"align-btn p-2 md:p-3 border border-gray-300 rounded-lg hover:bg-gray-50\" data-align=\"end\">\n                <i class=\"fas fa-align-right\"><\/i>\n              <\/button>\n            <\/div>\n          <\/div>\n\n          <!-- Background Color -->\n          <div class=\"mb-4\">\n            <div class=\"flex items-center justify-between mb-2\">\n              <label class=\"text-sm font-medium text-gray-700\">Background Color<\/label>\n              <label class=\"toggle-switch\">\n                <input type=\"checkbox\" id=\"backgroundEnabled\">\n                <span class=\"slider\"><\/span>\n              <\/label>\n            <\/div>\n            <div class=\"flex space-x-2\">\n              <input type=\"color\" id=\"backgroundColor\" value=\"#e8e3e3\" class=\"flex-1 h-10 border border-gray-300 rounded-lg\">\n              <button id=\"transparentBg\" class=\"bg-gray-500 hover:bg-gray-600 text-white px-3 py-2 rounded-lg transition-colors text-sm\">\n                <i class=\"fas fa-ban mr-1\"><\/i>Clear\n              <\/button>\n            <\/div>\n          <\/div>\n\n          <!-- Fill Color -->\n          <div class=\"mb-4\">\n            <div class=\"flex items-center justify-between mb-2\">\n              <label class=\"text-sm font-medium text-gray-700\">Fill Color<\/label>\n              <label class=\"toggle-switch\">\n                <input type=\"checkbox\" id=\"fillEnabled\" checked>\n                <span class=\"slider\"><\/span>\n              <\/label>\n            <\/div>\n            <input type=\"color\" id=\"fillColor\" value=\"#ff0000\" class=\"w-full h-10 border border-gray-300 rounded-lg\">\n          <\/div>\n\n          <!-- Stroke Color -->\n          <div class=\"mb-4\">\n            <div class=\"flex items-center justify-between mb-2\">\n              <label class=\"text-sm font-medium text-gray-700\">Stroke Color<\/label>\n              <label class=\"toggle-switch\">\n                <input type=\"checkbox\" id=\"strokeEnabled\">\n                <span class=\"slider\"><\/span>\n              <\/label>\n            <\/div>\n            <input type=\"color\" id=\"strokeColor\" value=\"#000000\" class=\"w-full h-10 border border-gray-300 rounded-lg\">\n          <\/div>\n\n          <!-- Shadow Settings -->\n          <div class=\"mb-4\">\n            <div class=\"flex items-center justify-between mb-2\">\n              <label class=\"text-sm font-medium text-gray-700\">Text Shadow<\/label>\n              <label class=\"toggle-switch\">\n                <input type=\"checkbox\" id=\"shadowEnabled\">\n                <span class=\"slider\"><\/span>\n              <\/label>\n            <\/div>\n            <div id=\"shadowControls\" class=\"space-y-3 hidden\">\n              <input type=\"color\" id=\"shadowColor\" value=\"#000000\" class=\"w-full h-10 border border-gray-300 rounded-lg\">\n              <div>\n                <label class=\"block text-xs text-gray-600 mb-1\">Distance: <span id=\"shadowDistanceValue\">2<\/span>px<\/label>\n                <input type=\"range\" id=\"shadowDistance\" min=\"0\" max=\"20\" value=\"2\" class=\"w-full\">\n              <\/div>\n              <div>\n                <label class=\"block text-xs text-gray-600 mb-1\">Blur: <span id=\"shadowBlurValue\">2<\/span>px<\/label>\n                <input type=\"range\" id=\"shadowBlur\" min=\"0\" max=\"20\" value=\"2\" class=\"w-full\">\n              <\/div>\n              <div>\n                <label class=\"block text-xs text-gray-600 mb-1\">Angle: <span id=\"shadowAngleValue\">45<\/span>\u00b0<\/label>\n                <input type=\"range\" id=\"shadowAngle\" min=\"0\" max=\"360\" value=\"45\" class=\"w-full\">\n              <\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <!-- Canvas Area -->\n      <div class=\"lg:col-span-2\">\n        <div class=\"bg-white rounded-lg shadow-md p-3 sm:p-4 md:p-6\">\n          <div class=\"flex flex-col sm:flex-row justify-between items-start sm:items-center mb-4 space-y-2 sm:space-y-0 sm:space-x-4\">\n            <h2 class=\"text-base sm:text-lg md:text-xl font-semibold\">Preview<\/h2>\n            <div class=\"flex flex-col sm:flex-row items-start sm:items-center space-y-2 sm:space-y-0 sm:space-x-4 w-full sm:w-auto\">\n              <div class=\"text-xs sm:text-sm text-gray-600\">Size: <span id=\"canvasDimensions\">600 \u00d7 600<\/span><\/div>\n              <div class=\"flex items-center space-x-2\">\n                <label class=\"text-xs sm:text-sm text-gray-600\">Zoom:<\/label>\n                <input type=\"range\" id=\"zoomSlider\" min=\"0.25\" max=\"2\" step=\"0.25\" value=\"1\" class=\"w-16 sm:w-20 md:w-24\">\n                <span id=\"zoomValue\" class=\"text-xs sm:text-sm text-gray-600 w-10\">100%<\/span>\n              <\/div>\n              <button id=\"fullscreenBtn\" class=\"bg-purple-500 hover:bg-purple-600 text-white px-2 sm:px-3 md:px-4 py-2 rounded-lg transition-colors text-xs sm:text-sm md:text-base w-full sm:w-auto\">\n                <i class=\"fas fa-expand mr-1 sm:mr-2\"><\/i>Fullscreen\n              <\/button>\n            <\/div>\n          <\/div>\n\n          <div id=\"canvasBackground\" class=\"border border-gray-300 rounded-lg canvas-container\">\n            <svg id=\"heartCanvas\" width=\"600\" height=\"600\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" xmlns:xlink=\"http:\/\/www.w3.org\/1999\/xlink\" viewBox=\"0 0 600 600\">\n              <defs>\n                <!-- per-instance paths & filters are injected here -->\n              <\/defs>\n            <\/svg>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n\n\n  <script>\n    (function () {\n      class HeartTextGenerator {\n        constructor() {\n          this.textInstances = [];\n          this.activeInstanceId = null;\n          this.instanceCounter = 0;\n          this.backgroundEnabled = false;\n          this.backgroundColor = '#ffffff';\n          this.isFullscreen = false;\n          this.fullscreenElement = null;\n          this.init();\n        }\n\n        init() {\n          this.setupEventListeners();\n          this.addTextInstance();\n          this.updateBackground();\n          this.handleResize();\n          window.addEventListener('resize', () => this.handleResize());\n        }\n\n        handleResize() {\n          const canvas = document.getElementById('heartCanvas');\n          const container = document.getElementById('canvasBackground');\n          if (canvas && container) {\n            const containerWidth = container.clientWidth - 20;\n            const maxSize = Math.min(containerWidth, 600);\n            if (window.innerWidth <= 768) {\n              canvas.style.maxWidth = '100%';\n              canvas.style.height = 'auto';\n            }\n          }\n        }\n\n        setupEventListeners() {\n          \/\/ Background controls\n          const backgroundEnabled = document.getElementById('backgroundEnabled');\n          const backgroundColor = document.getElementById('backgroundColor');\n          const transparentBg = document.getElementById('transparentBg');\n\n          if (backgroundEnabled) {\n            backgroundEnabled.addEventListener('change', () => {\n              this.backgroundEnabled = backgroundEnabled.checked;\n              this.updateBackground();\n            });\n          }\n          if (backgroundColor) {\n            backgroundColor.addEventListener('input', (e) => {\n              this.backgroundColor = e.target.value;\n              this.updateBackground();\n            });\n          }\n          if (transparentBg) {\n            transparentBg.addEventListener('click', () => {\n              if (backgroundEnabled) {\n                backgroundEnabled.checked = false;\n                this.backgroundEnabled = false;\n                this.updateBackground();\n              }\n            });\n          }\n\n          \/\/ Add text instance\n          const addTextBtn = document.getElementById('addTextBtn');\n          if (addTextBtn) addTextBtn.addEventListener('click', () => this.addTextInstance());\n\n          \/\/ Text controls\n          const textInput = document.getElementById('textInput');\n          const repeatCount = document.getElementById('repeatCount');\n          const fontFamily = document.getElementById('fontFamily');\n          const fontSize = document.getElementById('fontSize');\n          const heartSize = document.getElementById('heartSize');\n          const charSpacing = document.getElementById('charSpacing');\n          const xOffset = document.getElementById('xOffset');\n          const yOffset = document.getElementById('yOffset');\n\n          if (textInput) textInput.addEventListener('input', () => this.updateCurrentInstance());\n          if (repeatCount) repeatCount.addEventListener('input', () => this.updateCurrentInstance());\n          if (fontFamily) fontFamily.addEventListener('change', () => this.updateCurrentInstance());\n\n          if (fontSize) {\n            fontSize.addEventListener('input', (e) => {\n              const fontSizeValue = document.getElementById('fontSizeValue');\n              if (fontSizeValue) fontSizeValue.textContent = e.target.value;\n              this.updateCurrentInstance();\n            });\n          }\n\n          if (heartSize) {\n            heartSize.addEventListener('input', (e) => {\n              const heartSizeValue = document.getElementById('heartSizeValue');\n              if (heartSizeValue) heartSizeValue.textContent = e.target.value;\n              this.updateCurrentInstance();\n            });\n          }\n\n          if (charSpacing) charSpacing.addEventListener('input', () => this.updateCurrentInstance());\n          if (xOffset) xOffset.addEventListener('input', () => this.updateCurrentInstance());\n          if (yOffset) yOffset.addEventListener('input', () => this.updateCurrentInstance());\n\n          \/\/ Alignment buttons\n          document.querySelectorAll('.align-btn').forEach((btn) => {\n            btn.addEventListener('click', () => {\n              document.querySelectorAll('.align-btn').forEach((b) => b.classList.remove('active', 'bg-blue-500', 'text-white'));\n              btn.classList.add('active', 'bg-blue-500', 'text-white');\n              this.updateCurrentInstance();\n            });\n          });\n\n          \/\/ Color and stroke controls\n          const fillEnabled = document.getElementById('fillEnabled');\n          const fillColor = document.getElementById('fillColor');\n          const strokeEnabled = document.getElementById('strokeEnabled');\n          const strokeColor = document.getElementById('strokeColor');\n\n          if (fillEnabled) fillEnabled.addEventListener('change', () => this.updateCurrentInstance());\n          if (fillColor) fillColor.addEventListener('input', () => this.updateCurrentInstance());\n          if (strokeEnabled) strokeEnabled.addEventListener('change', () => this.updateCurrentInstance());\n          if (strokeColor) strokeColor.addEventListener('input', () => this.updateCurrentInstance());\n\n          \/\/ Shadow controls\n          const shadowEnabled = document.getElementById('shadowEnabled');\n          const shadowControls = document.getElementById('shadowControls');\n          const shadowDistance = document.getElementById('shadowDistance');\n          const shadowBlur = document.getElementById('shadowBlur');\n          const shadowAngle = document.getElementById('shadowAngle');\n          const shadowColor = document.getElementById('shadowColor');\n\n          if (shadowEnabled) {\n            shadowEnabled.addEventListener('change', (e) => {\n              if (shadowControls) shadowControls.classList.toggle('hidden', !e.target.checked);\n              this.updateCurrentInstance();\n            });\n          }\n          if (shadowDistance) {\n            shadowDistance.addEventListener('input', (e) => {\n              const shadowDistanceValue = document.getElementById('shadowDistanceValue');\n              if (shadowDistanceValue) shadowDistanceValue.textContent = e.target.value;\n              this.updateCurrentInstance();\n            });\n          }\n          if (shadowBlur) {\n            shadowBlur.addEventListener('input', (e) => {\n              const shadowBlurValue = document.getElementById('shadowBlurValue');\n              if (shadowBlurValue) shadowBlurValue.textContent = e.target.value;\n              this.updateCurrentInstance();\n            });\n          }\n          if (shadowAngle) {\n            shadowAngle.addEventListener('input', (e) => {\n              const shadowAngleValue = document.getElementById('shadowAngleValue');\n              if (shadowAngleValue) shadowAngleValue.textContent = e.target.value;\n              this.updateCurrentInstance();\n            });\n          }\n          if (shadowColor) shadowColor.addEventListener('input', () => this.updateCurrentInstance());\n\n          \/\/ Zoom control\n          const zoomSlider = document.getElementById('zoomSlider');\n          if (zoomSlider) {\n            zoomSlider.addEventListener('input', (e) => {\n              const zoom = parseFloat(e.target.value);\n              const zoomValue = document.getElementById('zoomValue');\n              if (zoomValue) zoomValue.textContent = Math.round(zoom * 100) + '%';\n              const canvas = document.getElementById('heartCanvas');\n              if (canvas) canvas.style.transform = `scale(${zoom})`;\n            });\n          }\n\n          \/\/ Fullscreen controls\n          const fullscreenBtn = document.getElementById('fullscreenBtn');\n\n          if (fullscreenBtn) {\n            fullscreenBtn.addEventListener('click', () => this.toggleFullscreen());\n          }\n\n          \/\/ Listen for fullscreen changes\n          document.addEventListener('fullscreenchange', () => this.handleFullscreenChange());\n          document.addEventListener('webkitfullscreenchange', () => this.handleFullscreenChange());\n          document.addEventListener('mozfullscreenchange', () => this.handleFullscreenChange());\n          document.addEventListener('MSFullscreenChange', () => this.handleFullscreenChange());\n        }\n\n        async toggleFullscreen() {\n          if (this.isFullscreen) {\n            await this.exitFullscreen();\n          } else {\n            await this.enterFullscreen();\n          }\n        }\n\n        async enterFullscreen() {\n          const canvasSection = document.querySelector('.lg\\\\:col-span-2');\n          if (!canvasSection) return;\n\n          try {\n            \/\/ Try different fullscreen methods for cross-browser compatibility\n            if (canvasSection.requestFullscreen) {\n              await canvasSection.requestFullscreen();\n            } else if (canvasSection.webkitRequestFullscreen) {\n              await canvasSection.webkitRequestFullscreen();\n            } else if (canvasSection.mozRequestFullScreen) {\n              await canvasSection.mozRequestFullScreen();\n            } else if (canvasSection.msRequestFullscreen) {\n              await canvasSection.msRequestFullscreen();\n            }\n          } catch (error) {\n            console.error('Error entering fullscreen:', error);\n            \/\/ Fallback to manual fullscreen mode\n            this.enterManualFullscreen(canvasSection);\n          }\n        }\n\n        enterManualFullscreen(element) {\n          this.fullscreenElement = element;\n          element.classList.add('fullscreen-mode');\n          \n          \/\/ Create exit button\n          const exitBtn = document.createElement('button');\n          exitBtn.className = 'fullscreen-exit-btn';\n          exitBtn.innerHTML = '<i class=\"fas fa-compress\"><\/i> Exit Fullscreen';\n          exitBtn.onclick = () => this.exitManualFullscreen();\n          element.appendChild(exitBtn);\n\n          \/\/ Create title\n          const title = document.createElement('div');\n          title.className = 'fullscreen-title';\n          title.innerHTML = '<i class=\"fas fa-heart text-red-500\"><\/i> Heart Shape Text Generator';\n          element.appendChild(title);\n\n          this.isFullscreen = true;\n          this.updateCanvasBackground();\n          document.body.style.overflow = 'hidden';\n        }\n\n        async exitFullscreen() {\n          try {\n            if (document.exitFullscreen) {\n              await document.exitFullscreen();\n            } else if (document.webkitExitFullscreen) {\n              await document.webkitExitFullscreen();\n            } else if (document.mozCancelFullScreen) {\n              await document.mozCancelFullScreen();\n            } else if (document.msExitFullscreen) {\n              await document.msExitFullscreen();\n            }\n          } catch (error) {\n            console.error('Error exiting fullscreen:', error);\n            this.exitManualFullscreen();\n          }\n        }\n\n        exitManualFullscreen() {\n          if (this.fullscreenElement) {\n            this.fullscreenElement.classList.remove('fullscreen-mode');\n            \n            \/\/ Remove exit button and title\n            const exitBtn = this.fullscreenElement.querySelector('.fullscreen-exit-btn');\n            const title = this.fullscreenElement.querySelector('.fullscreen-title');\n            if (exitBtn) exitBtn.remove();\n            if (title) title.remove();\n            \n            this.fullscreenElement = null;\n          }\n          \n          this.isFullscreen = false;\n          this.updateCanvasBackground();\n          document.body.style.overflow = '';\n        }\n\n        handleFullscreenChange() {\n          const isCurrentlyFullscreen = !!(document.fullscreenElement || \n                                          document.webkitFullscreenElement || \n                                          document.mozFullScreenElement || \n                                          document.msFullscreenElement);\n          \n          if (isCurrentlyFullscreen && !this.isFullscreen) {\n            this.isFullscreen = true;\n            this.updateCanvasBackground();\n          } else if (!isCurrentlyFullscreen && this.isFullscreen) {\n            this.isFullscreen = false;\n            this.updateCanvasBackground();\n          }\n        }\n\n        updateCanvasBackground() {\n          const container = document.getElementById('canvasBackground');\n          if (!container) return;\n          \n          if (this.backgroundEnabled) {\n            container.style.backgroundColor = this.backgroundColor;\n            container.classList.remove('checkerboard');\n          } else {\n            container.style.backgroundColor = 'transparent';\n            container.classList.add('checkerboard');\n          }\n        }\n\n        updateBackground() {\n          this.updateCanvasBackground();\n        }\n\n        addTextInstance() {\n          const instance = {\n            id: ++this.instanceCounter,\n            text: 'I Love You',\n            repeatCount: 8,\n            fontFamily: 'Pacifico',\n            fontSize: 24,\n            heartSize: 100,\n            charSpacing: 0,\n            xOffset: 0,\n            yOffset: 0,\n            alignment: 'start',\n            fillEnabled: true,\n            fillColor: '#ff0000',\n            strokeEnabled: false,\n            strokeColor: '#000000',\n            shadowEnabled: false,\n            shadowColor: '#000000',\n            shadowDistance: 2,\n            shadowBlur: 2,\n            shadowAngle: 45\n          };\n\n          this.textInstances.push(instance);\n          this.renderTextInstancesList();\n          this.setActiveInstance(instance.id);\n          this.updateCanvas();\n        }\n\n        removeTextInstance(id) {\n          const index = this.textInstances.findIndex((instance) => instance.id === id);\n          if (index > -1) {\n            this.textInstances.splice(index, 1);\n            if (this.activeInstanceId === id) {\n              this.activeInstanceId = this.textInstances.length > 0 ? this.textInstances[0].id : null;\n            }\n            this.renderTextInstancesList();\n            if (this.activeInstanceId) this.loadInstanceToControls(this.getActiveInstance());\n            this.updateCanvas();\n          }\n        }\n\n        setActiveInstance(id) {\n          this.activeInstanceId = id;\n          const instance = this.getActiveInstance();\n          if (instance) {\n            this.loadInstanceToControls(instance);\n            this.renderTextInstancesList();\n          }\n        }\n\n        getActiveInstance() { return this.textInstances.find((i) => i.id === this.activeInstanceId); }\n\n        loadInstanceToControls(instance) {\n          const textInput = document.getElementById('textInput');\n          const repeatCount = document.getElementById('repeatCount');\n          const fontFamily = document.getElementById('fontFamily');\n          const fontSize = document.getElementById('fontSize');\n          const fontSizeValue = document.getElementById('fontSizeValue');\n          const heartSize = document.getElementById('heartSize');\n          const heartSizeValue = document.getElementById('heartSizeValue');\n          const charSpacing = document.getElementById('charSpacing');\n          const xOffset = document.getElementById('xOffset');\n          const yOffset = document.getElementById('yOffset');\n\n          if (textInput) textInput.value = instance.text;\n          if (repeatCount) repeatCount.value = instance.repeatCount;\n          if (fontFamily) fontFamily.value = instance.fontFamily;\n          if (fontSize) fontSize.value = instance.fontSize;\n          if (fontSizeValue) fontSizeValue.textContent = instance.fontSize;\n          if (heartSize) heartSize.value = instance.heartSize;\n          if (heartSizeValue) heartSizeValue.textContent = instance.heartSize;\n          if (charSpacing) charSpacing.value = instance.charSpacing;\n          if (xOffset) xOffset.value = instance.xOffset;\n          if (yOffset) yOffset.value = instance.yOffset;\n\n          document.querySelectorAll('.align-btn').forEach((btn) => {\n            btn.classList.remove('active', 'bg-blue-500', 'text-white');\n            if (btn.dataset.align === instance.alignment) btn.classList.add('active', 'bg-blue-500', 'text-white');\n          });\n\n          const fillEnabled = document.getElementById('fillEnabled');\n          const fillColor = document.getElementById('fillColor');\n          const strokeEnabled = document.getElementById('strokeEnabled');\n          const strokeColor = document.getElementById('strokeColor');\n          const shadowEnabled = document.getElementById('shadowEnabled');\n          const shadowColor = document.getElementById('shadowColor');\n          const shadowDistance = document.getElementById('shadowDistance');\n          const shadowDistanceValue = document.getElementById('shadowDistanceValue');\n          const shadowBlur = document.getElementById('shadowBlur');\n          const shadowBlurValue = document.getElementById('shadowBlurValue');\n          const shadowAngle = document.getElementById('shadowAngle');\n          const shadowAngleValue = document.getElementById('shadowAngleValue');\n          const shadowControls = document.getElementById('shadowControls');\n\n          if (fillEnabled) fillEnabled.checked = instance.fillEnabled;\n          if (fillColor) fillColor.value = instance.fillColor;\n          if (strokeEnabled) strokeEnabled.checked = instance.strokeEnabled;\n          if (strokeColor) strokeColor.value = instance.strokeColor;\n          if (shadowEnabled) shadowEnabled.checked = instance.shadowEnabled;\n          if (shadowColor) shadowColor.value = instance.shadowColor;\n          if (shadowDistance) shadowDistance.value = instance.shadowDistance;\n          if (shadowDistanceValue) shadowDistanceValue.textContent = instance.shadowDistance;\n          if (shadowBlur) shadowBlur.value = instance.shadowBlur;\n          if (shadowBlurValue) shadowBlurValue.textContent = instance.shadowBlur;\n          if (shadowAngle) shadowAngle.value = instance.shadowAngle;\n          if (shadowAngleValue) shadowAngleValue.textContent = instance.shadowAngle;\n          if (shadowControls) shadowControls.classList.toggle('hidden', !instance.shadowEnabled);\n        }\n\n        updateCurrentInstance() {\n          const instance = this.getActiveInstance();\n          if (!instance) return;\n\n          const textInput = document.getElementById('textInput');\n          const repeatCount = document.getElementById('repeatCount');\n          const fontFamily = document.getElementById('fontFamily');\n          const fontSize = document.getElementById('fontSize');\n          const heartSize = document.getElementById('heartSize');\n          const charSpacing = document.getElementById('charSpacing');\n          const xOffset = document.getElementById('xOffset');\n          const yOffset = document.getElementById('yOffset');\n\n          if (textInput) instance.text = textInput.value;\n          if (repeatCount) instance.repeatCount = Math.max(1, parseInt(repeatCount.value || '1', 10));\n          if (fontFamily) instance.fontFamily = fontFamily.value;\n          if (fontSize) instance.fontSize = parseInt(fontSize.value);\n          if (heartSize) instance.heartSize = parseInt(heartSize.value);\n          if (charSpacing) instance.charSpacing = parseFloat(charSpacing.value);\n          if (xOffset) instance.xOffset = parseInt(xOffset.value);\n          if (yOffset) instance.yOffset = parseInt(yOffset.value);\n\n          const activeAlignBtn = document.querySelector('.align-btn.active');\n          instance.alignment = activeAlignBtn ? activeAlignBtn.dataset.align : 'start';\n\n          const fillEnabled = document.getElementById('fillEnabled');\n          const fillColor = document.getElementById('fillColor');\n          const strokeEnabled = document.getElementById('strokeEnabled');\n          const strokeColor = document.getElementById('strokeColor');\n          const shadowEnabled = document.getElementById('shadowEnabled');\n          const shadowColor = document.getElementById('shadowColor');\n          const shadowDistance = document.getElementById('shadowDistance');\n          const shadowBlur = document.getElementById('shadowBlur');\n          const shadowAngle = document.getElementById('shadowAngle');\n\n          if (fillEnabled) instance.fillEnabled = fillEnabled.checked;\n          if (fillColor) instance.fillColor = fillColor.value;\n          if (strokeEnabled) instance.strokeEnabled = strokeEnabled.checked;\n          if (strokeColor) instance.strokeColor = strokeColor.value;\n          if (shadowEnabled) instance.shadowEnabled = shadowEnabled.checked;\n          if (shadowColor) instance.shadowColor = shadowColor.value;\n          if (shadowDistance) instance.shadowDistance = parseFloat(shadowDistance.value);\n          if (shadowBlur) instance.shadowBlur = parseFloat(shadowBlur.value);\n          if (shadowAngle) instance.shadowAngle = parseFloat(shadowAngle.value);\n\n          this.renderTextInstancesList();\n          this.updateCanvas();\n        }\n\n        renderTextInstancesList() {\n          const container = document.getElementById('textInstances');\n          if (!container) return;\n\n          container.innerHTML = '';\n\n          this.textInstances.forEach((instance) => {\n            const div = document.createElement('div');\n            div.className = `text-instance p-2 sm:p-3 cursor-pointer ${instance.id === this.activeInstanceId ? 'active' : ''}`;\n            div.innerHTML = `\n              <div class=\"flex justify-between items-start\">\n                <div class=\"flex-1 mr-2 min-w-0\">\n                  <div class=\"font-medium text-sm sm:text-base\">Text ${instance.id}<\/div>\n                  <div class=\"text-xs sm:text-sm text-gray-500 truncate\">${instance.text || 'Empty text'}<\/div>\n                <\/div>\n                <div class=\"flex space-x-1 sm:space-x-2 flex-shrink-0\">\n                  <button class=\"delete-instance-btn text-red-500 hover:text-red-700 p-1\" data-id=\"${instance.id}\" title=\"Delete\">\n                    <i class=\"fas fa-trash text-xs\"><\/i>\n                  <\/button>\n                <\/div>\n              <\/div>\n            `;\n\n            div.addEventListener('click', (e) => {\n              if (!e.target.closest('button') && !e.target.closest('input')) this.setActiveInstance(instance.id);\n            });\n\n            const deleteBtn = div.querySelector('.delete-instance-btn');\n            if (deleteBtn) {\n              deleteBtn.addEventListener('click', (e) => {\n                e.stopPropagation();\n                const instanceId = parseInt(e.currentTarget.dataset.id);\n                this.removeTextInstance(instanceId);\n              });\n            }\n\n            container.appendChild(div);\n          });\n        }\n\n        \/\/ --- Geometry: unit heart path (no squash\/widen) ---\n        generateUnitHeartPath(cx, cy) {\n          const pts = [];\n          const samples = 240;\n          for (let i = 0; i <= samples; i++) {\n            const t = (Math.PI * 2) * (i \/ samples);\n            const x = 16 * Math.pow(Math.sin(t), 3);\n            const y = 13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t);\n            const X = cx + (x * 10);\n            const Y = cy - (y * 10);\n            pts.push([X, Y]);\n          }\n          let d = `M${pts[0][0].toFixed(2)},${pts[0][1].toFixed(2)}`;\n          for (let i = 1; i < pts.length; i++) d += ` L${pts[i][0].toFixed(2)},${pts[i][1].toFixed(2)}`;\n          d += ' Z';\n          return d;\n        }\n\n        \/\/ --- SVG filter-based shadow (stable for export) ---\n        ensureShadowFilter(svg, instanceId, color, distance, blur, angleDeg) {\n          const defs = svg.querySelector('defs') || svg.insertBefore(document.createElementNS('http:\/\/www.w3.org\/2000\/svg','defs'), svg.firstChild);\n          const id = `shadowFilter_${instanceId}`;\n          let f = defs.querySelector(`#${id}`);\n          if (f) f.remove();\n\n          const angle = (angleDeg * Math.PI) \/ 180;\n          const dx = Math.cos(angle) * distance;\n          const dy = Math.sin(angle) * distance;\n\n          f = document.createElementNS('http:\/\/www.w3.org\/2000\/svg','filter');\n          f.setAttribute('id', id);\n          f.setAttribute('x', '-50%');\n          f.setAttribute('y', '-50%');\n          f.setAttribute('width', '200%');\n          f.setAttribute('height', '200%');\n\n          const feFlood = document.createElementNS('http:\/\/www.w3.org\/2000\/svg','feFlood');\n          feFlood.setAttribute('flood-color', color);\n          feFlood.setAttribute('flood-opacity', '1');\n          feFlood.setAttribute('result', 'flood');\n\n          const feComposite = document.createElementNS('http:\/\/www.w3.org\/2000\/svg','feComposite');\n          feComposite.setAttribute('in', 'flood');\n          feComposite.setAttribute('in2', 'SourceAlpha');\n          feComposite.setAttribute('operator', 'in');\n          feComposite.setAttribute('result', 'shadowColor');\n\n          const feOffset = document.createElementNS('http:\/\/www.w3.org\/2000\/svg','feOffset');\n          feOffset.setAttribute('dx', dx.toString());\n          feOffset.setAttribute('dy', dy.toString());\n          feOffset.setAttribute('result', 'offsetShadow');\n\n          const feGaussian = document.createElementNS('http:\/\/www.w3.org\/2000\/svg','feGaussianBlur');\n          feGaussian.setAttribute('in', 'offsetShadow');\n          feGaussian.setAttribute('stdDeviation', blur.toString());\n          feGaussian.setAttribute('result', 'blurredShadow');\n\n          const feMerge = document.createElementNS('http:\/\/www.w3.org\/2000\/svg','feMerge');\n          const m1 = document.createElementNS('http:\/\/www.w3.org\/2000\/svg','feMergeNode');\n          m1.setAttribute('in', 'blurredShadow');\n          const m2 = document.createElementNS('http:\/\/www.w3.org\/2000\/svg','feMergeNode');\n          m2.setAttribute('in', 'SourceGraphic');\n          feMerge.appendChild(m1); feMerge.appendChild(m2);\n\n          f.appendChild(feFlood);\n          f.appendChild(feComposite);\n          f.appendChild(feOffset);\n          f.appendChild(feGaussian);\n          f.appendChild(feMerge);\n          defs.appendChild(f);\n\n          return `url(#${id})`;\n        }\n\n        updateCanvas() {\n          const svg = document.getElementById('heartCanvas');\n          if (!svg) return;\n\n          \/\/ Clear previous instance groups (keep base defs)\n          svg.querySelectorAll('g[data-instance=\"true\"]').forEach(g => g.remove());\n\n          this.textInstances.forEach((instance) => {\n            if (!instance.text) return;\n\n            const scale = instance.heartSize \/ 100;\n            const centerX = 300, centerY = 300; \/\/ true center\n\n            \/\/ Create path in <defs> at unit scale\n            const defs = svg.querySelector('defs') || svg.insertBefore(document.createElementNS('http:\/\/www.w3.org\/2000\/svg','defs'), svg.firstChild);\n            const pathId = `heartPath_${instance.id}`;\n            let path = defs.querySelector(`#${pathId}`);\n            if (path) path.remove();\n            path = document.createElementNS('http:\/\/www.w3.org\/2000\/svg', 'path');\n            path.setAttribute('id', pathId);\n            path.setAttribute('d', this.generateUnitHeartPath(centerX, centerY));\n            defs.appendChild(path);\n\n            \/\/ Group to apply uniform scaling about center\n            const g = document.createElementNS('http:\/\/www.w3.org\/2000\/svg','g');\n            g.setAttribute('data-instance', 'true');\n            g.setAttribute('transform', `translate(${centerX} ${centerY}) scale(${scale}) translate(${-centerX} ${-centerY})`);\n\n            \/\/ Compose repeated text\n            const repeated = Array(Math.max(1, instance.repeatCount)).fill((instance.text||'').trim()).join(' ');\n\n            const textElement = document.createElementNS('http:\/\/www.w3.org\/2000\/svg', 'text');\n            const textPath = document.createElementNS('http:\/\/www.w3.org\/2000\/svg', 'textPath');\n            textPath.setAttributeNS('http:\/\/www.w3.org\/1999\/xlink', 'href', `#${pathId}`);\n            textPath.setAttribute('method', 'align');\n            textPath.setAttribute('spacing', 'auto');\n            textPath.textContent = repeated;\n\n            \/\/ Inline styles for preview & export\n            textElement.setAttribute('font-family', instance.fontFamily);\n            textElement.setAttribute('font-size', `${instance.fontSize}px`);\n            textElement.setAttribute('letter-spacing', `${instance.charSpacing}px`);\n            textElement.setAttribute('fill', instance.fillEnabled ? instance.fillColor : 'none');\n            if (instance.strokeEnabled) {\n              textElement.setAttribute('stroke', instance.strokeColor);\n              textElement.setAttribute('stroke-width', '1');\n            } else {\n              textElement.setAttribute('stroke', 'none');\n            }\n\n            \/\/ Alignment\n            const startOffset = instance.alignment === 'start' ? '0%' : (instance.alignment === 'middle' ? '50%' : '100%');\n            textPath.setAttribute('startOffset', startOffset);\n            textPath.setAttribute('text-anchor', instance.alignment);\n\n            \/\/ Offsets\n            textElement.setAttribute('dx', instance.xOffset);\n            textElement.setAttribute('dy', instance.yOffset);\n\n            \/\/ Shadow via SVG filter (reliable for export)\n            if (instance.shadowEnabled) {\n              const filterUrl = this.ensureShadowFilter(svg, instance.id, instance.shadowColor, instance.shadowDistance, instance.shadowBlur, instance.shadowAngle);\n              textElement.setAttribute('filter', filterUrl);\n            } else {\n              textElement.removeAttribute('filter');\n            }\n\n            textElement.appendChild(textPath);\n            g.appendChild(textElement);\n            svg.appendChild(g);\n          });\n\n\n        }\n      }\n\n      \/\/ Initialize\n      if (document.readyState === 'loading') {\n        document.addEventListener('DOMContentLoaded', () => { window.heartGenerator = new HeartTextGenerator(); });\n      } else {\n        window.heartGenerator = new HeartTextGenerator();\n      }\n    })();\n  <\/script>\n<\/div>\n\n\n\n<p>Here are some of the samples of heart shape text generator:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:100%\">\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"943\" height=\"733\" data-id=\"446\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample-2.png\" alt=\"heart shape text sample\" class=\"wp-image-446\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample-2.png 943w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample-2-300x233.png 300w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample-2-768x597.png 768w\" sizes=\"auto, (max-width: 943px) 100vw, 943px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"834\" height=\"673\" data-id=\"447\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample-3.png\" alt=\"heart shape text sample\" class=\"wp-image-447\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample-3.png 834w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample-3-300x242.png 300w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample-3-768x620.png 768w\" sizes=\"auto, (max-width: 834px) 100vw, 834px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"750\" data-id=\"448\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample1-1024x750.png\" alt=\"heart shape text sample\" class=\"wp-image-448\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample1-1024x750.png 1024w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample1-300x220.png 300w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample1-768x563.png 768w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/09\/sample1.png 1137w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/figure>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"guide\">Step-by-Step Guide on How to Use this Text in Heart Shape Generator <\/h3>\n\n\n\n<p>1. <strong>Open <\/strong>this online<strong> Heart Shape Text Generator<\/strong>.<br><img alt=\"\"><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1290\" height=\"641\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/1.png\" alt=\"step 1\" class=\"wp-image-604\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/1.png 1290w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/1-300x149.png 300w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/1-1024x509.png 1024w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/1-768x382.png 768w\" sizes=\"auto, (max-width: 1290px) 100vw, 1290px\" \/><\/figure>\n\n\n\n<p>2. Click on the <strong>Add<\/strong> button and add multiple <strong>Text Instances<\/strong> as per your choice.<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"357\" height=\"356\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/2.webp\" alt=\"step 2\" class=\"wp-image-605\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/2.webp 357w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/2-300x300.webp 300w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/2-150x150.webp 150w\" sizes=\"auto, (max-width: 357px) 100vw, 357px\" \/><\/figure>\n\n\n\n<p>3. Now, write content in the<strong> Text Content<\/strong> section and add numbers in the<strong> Repeat Count<\/strong> section to repeat the above word several times.<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"385\" height=\"345\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/3.png\" alt=\"step 3\" class=\"wp-image-606\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/3.png 385w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/3-300x269.png 300w\" sizes=\"auto, (max-width: 385px) 100vw, 385px\" \/><\/figure>\n\n\n\n<p>4. <strong>Three<\/strong> different options are available on the screen:<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"389\" height=\"234\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/4.png\" alt=\"step 4\" class=\"wp-image-607\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/4.png 389w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/4-300x180.png 300w\" sizes=\"auto, (max-width: 389px) 100vw, 389px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Heart Size<\/strong>: Using this you can choose the size of the complete structure.<\/li>\n\n\n\n<li><strong>Font Family<\/strong>: This option allows you to select font for the word mentioned above.<\/li>\n\n\n\n<li><strong>Font Size<\/strong>: It changes the size of the font as per your requirements.<\/li>\n<\/ul>\n\n\n\n<p>5. Next, in the <strong>Character Spacing<\/strong> section, you can adjust the words by making space between them and also <strong>Change<\/strong> <strong>the Alignment<\/strong> of text to Right, Middle &amp; Left.<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"338\" height=\"247\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/5.webp\" alt=\"step 5\" class=\"wp-image-608\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/5.webp 338w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/5-300x219.webp 300w\" sizes=\"auto, (max-width: 338px) 100vw, 338px\" \/><\/figure>\n\n\n\n<p>6. Here, again <strong>four<\/strong> interesting options are shown:<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"344\" height=\"300\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/6.webp\" alt=\"step 6\" class=\"wp-image-609\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/6.webp 344w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/6-300x262.webp 300w\" sizes=\"auto, (max-width: 344px) 100vw, 344px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Background Colour<\/strong>: Using this you can choose different colors for the background area.<\/li>\n\n\n\n<li><strong>Fill Colour<\/strong>: This allows you to add colour in the word written in text instances.<\/li>\n\n\n\n<li><strong>Stroke Colour<\/strong>: It helps to highlight or bold the Text.<\/li>\n\n\n\n<li><strong>Text Shadow<\/strong>: This option creates a shadow of the written text.<\/li>\n<\/ul>\n\n\n\n<p>7. All in all, tap on the<strong> Full Screen<\/strong> option to <strong>view<\/strong> the text clearly.<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"731\" height=\"609\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/7.webp\" alt=\"step 7\" class=\"wp-image-610\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/7.webp 731w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/7-300x250.webp 300w\" sizes=\"auto, (max-width: 731px) 100vw, 731px\" \/><\/figure>\n\n\n\n<p>8. Lastly, to view the text on your computer, you need to take a <strong>Screenshot <\/strong>of the Generated Heart by you.<br><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1364\" height=\"693\" src=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/8.webp\" alt=\"step 8\" class=\"wp-image-611\" srcset=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/8.webp 1364w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/8-300x152.webp 300w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/8-1024x520.webp 1024w, https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/10\/8-768x390.webp 768w\" sizes=\"auto, (max-width: 1364px) 100vw, 1364px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Features of Our Tool<\/h2>\n\n\n\n<p>Our <strong>heart shape text generator<\/strong> is designed to be simple, fast, and user-friendly. Here are the key features that make it stand out:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Instant Conversion<\/strong> \u2013 Generate text art in seconds with no waiting time.<\/li>\n\n\n\n<li><strong>100% Free<\/strong> \u2013 Enjoy unlimited usage without hidden fees.<\/li>\n\n\n\n<li><strong>Mobile Friendly<\/strong> \u2013 Works smoothly on Android, iOS, tablets, and desktop devices.<\/li>\n\n\n\n<li><strong>One-Click Copy<\/strong> \u2013 Easily copy your generated heart text to your clipboard.<\/li>\n\n\n\n<li><strong>Multiple Heart Styles<\/strong> \u2013 Choose from emoji hearts, ASCII hearts, decorative symbols, and creative layouts.<\/li>\n\n\n\n<li><strong>Customizable Options<\/strong> \u2013 Different fonts, symbols, and spacing options available.<\/li>\n\n\n\n<li><strong>Unicode Compatible<\/strong> \u2013 Works across most apps and platforms.<\/li>\n<\/ul>\n\n\n\n<p>Our advanced <strong>text to heart converter<\/strong> ensures that your message keeps its formatting when pasted onto social media platforms.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Why Use a Heart Shape Text Generator?<\/h3>\n\n\n\n<p>In today\u2019s digital world, visual appeal matters more than ever. A simple text message can easily get ignored, but a beautifully designed <strong>name in heart shape<\/strong> instantly captures attention. Whether you are expressing love, celebrating a special moment, or simply decorating your profile, heart text art adds personality and creativity.<\/p>\n\n\n\n<p>Using a <strong>love text generator<\/strong> also saves time compared to manually designing ASCII art. You don\u2019t need technical skills or design knowledge. The tool automatically arranges symbols to create balanced and visually pleasing heart shapes.<\/p>\n\n\n\n<p>Additionally, heart-shaped text enhances engagement on social media. Creative bios and captions often attract more clicks, likes, and comments.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Best Platforms to Use Heart Text<\/h3>\n\n\n\n<p>One of the biggest advantages of our <strong>heart shape text generator<\/strong> is compatibility. Here are some popular places where users love to share their designs:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Instagram Bio<\/h4>\n\n\n\n<p>Make your profile unique with stylish <strong>Instagram heart text<\/strong>. A decorated bio instantly stands out and reflects your personality.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">TikTok Captions<\/h4>\n\n\n\n<p>Add heart text art to your video captions for a creative touch.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">WhatsApp Status<\/h4>\n\n\n\n<p>Share romantic messages or friendship quotes using <strong>copy and paste heart symbols<\/strong> that work perfectly on WhatsApp.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Facebook Posts<\/h4>\n\n\n\n<p>Decorate your timeline with creative <strong>love symbol text art<\/strong> to celebrate anniversaries or birthdays.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Gaming Usernames<\/h4>\n\n\n\n<p>Use a <strong>name in heart shape<\/strong> for games like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Free Fire<\/li>\n\n\n\n<li>PUBG<\/li>\n\n\n\n<li>Roblox<\/li>\n<\/ul>\n\n\n\n<p>Stylish usernames often grab attention in gaming communities.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Special Occasions<\/h4>\n\n\n\n<p>Heart text is perfect for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Valentine\u2019s Day \ud83d\udc96<\/li>\n\n\n\n<li>Anniversaries \ud83d\udc8d<\/li>\n\n\n\n<li>Birthdays \ud83c\udf82<\/li>\n\n\n\n<li>Proposals \ud83d\udc8c<\/li>\n\n\n\n<li>Friendship Day \ud83e\udd1d<\/li>\n<\/ul>\n\n\n\n<p>By using our <strong>emoji heart generator<\/strong>, you can personalize your messages for every occasion.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Types of Heart Text Styles You Can Create<\/h3>\n\n\n\n<p>Our tool supports multiple creative variations, including:<\/p>\n\n\n\n<p>1. ASCII Heart Art<\/p>\n\n\n\n<p>Classic text-based heart patterns made using characters like <code>*<\/code>, <code>.<\/code>, and <code>&lt;3<\/code>.<\/p>\n\n\n\n<p>2. Unicode Heart Symbols<\/p>\n\n\n\n<p>Decorative heart shapes created with special Unicode characters for better compatibility.<\/p>\n\n\n\n<p>3. Emoji Heart Designs<\/p>\n\n\n\n<p>Colorful heart emojis arranged in patterns to form larger heart shapes.<\/p>\n\n\n\n<p>4. Minimalist Heart Text<\/p>\n\n\n\n<p>Clean and simple designs ideal for professional bios.<\/p>\n\n\n\n<p>This variety ensures that our <strong>heart shape text generator<\/strong> fits every mood and platform requirement.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Frequently Asked Questions (FAQ)<\/h3>\n\n\n\n<p><strong>Q1<\/strong>: Is this heart text generator free?<\/p>\n\n\n\n<p>Yes, our heart shape text generator is 100% free. You can generate unlimited heart text designs without paying anything.<\/p>\n\n\n\n<p><strong>Q2<\/strong>: Will the heart text work on WhatsApp?<\/p>\n\n\n\n<p>Yes. The generated text uses Unicode symbols that are compatible with WhatsApp and most messaging apps.<\/p>\n\n\n\n<p><strong>Q3<\/strong>: Can I use this for my Instagram Bio?<\/p>\n\n\n\n<p>Absolutely! Many users create Instagram heart text for stylish bios and captions.<\/p>\n\n\n\n<p><strong>Q4<\/strong>: Does it work on mobile devices?<\/p>\n\n\n\n<p>Yes. The tool is fully optimized for Android, iOS, and desktop browsers.<\/p>\n\n\n\n<p><strong>Q5<\/strong>: Can I create a name in heart shape?<\/p>\n\n\n\n<p>Yes. Simply enter any name, and our name in heart shape feature will generate a beautiful heart layout instantly.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tips to Create the Best Heart Text<\/h3>\n\n\n\n<p>To make the most of our <strong>emoji heart generator<\/strong>, consider these tips:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Keep your message short for better alignment.<\/li>\n\n\n\n<li>Test different heart styles for the best visual impact.<\/li>\n\n\n\n<li>Use colored emoji hearts for festive occasions.<\/li>\n\n\n\n<li>Preview your text before posting to ensure proper spacing.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Final Thoughts<\/h4>\n\n\n\n<p>Our <strong>Heart Shape Text Generator<\/strong> is the perfect solution for anyone looking to create stylish and romantic text art online. Whether you need <strong>copy and paste heart symbols<\/strong> for social media, want a decorative <strong>name in heart shape<\/strong>, or simply wish to express love creatively, this tool delivers instant results.<\/p>\n\n\n\n<p>With its fast processing, mobile compatibility, and multiple heart styles, it stands out as a powerful <strong>text to heart converter<\/strong> and <strong>love text generator<\/strong>. Try it today and turn your simple words into beautiful heart-shaped designs that capture attention everywhere you post. \ud83d\udc96<\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":204,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-generator","infinite-scroll-item","generate-columns","tablet-grid-50","mobile-grid-100","grid-parent","grid-33"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Heart Shape Text Generator - Create Text in Heart Shape | Oualator<\/title>\n<meta name=\"description\" content=\"Generate custom text in a heart shape with any font, size, and colors. Create beautiful, shareable heart designs with our free online tool.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Heart Shape Text Generator - Create Text in Heart Shape | Oualator\" \/>\n<meta property=\"og:description\" content=\"Generate custom text in a heart shape with any font, size, and colors. Create beautiful, shareable heart designs with our free online tool.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/\" \/>\n<meta property=\"og:site_name\" content=\"Oualator\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-17T06:03:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-17T22:04:48+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png\" \/>\n\t<meta property=\"og:image:width\" content=\"968\" \/>\n\t<meta property=\"og:image:height\" content=\"639\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"mikarmiaura\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"mikarmiaura\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/\"},\"author\":{\"name\":\"mikarmiaura\",\"@id\":\"https:\/\/oualator.com\/calculate\/#\/schema\/person\/4ea451aa69c0b6773dc729ab8e30a78a\"},\"headline\":\"Heart Shape Text Generator &#8211; Fill Heart Shape With Your Text\",\"datePublished\":\"2026-02-17T06:03:00+00:00\",\"dateModified\":\"2026-02-17T22:04:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/\"},\"wordCount\":1198,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/oualator.com\/calculate\/#organization\"},\"image\":{\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png\",\"articleSection\":[\"Generator\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/\",\"url\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/\",\"name\":\"Heart Shape Text Generator - Create Text in Heart Shape | Oualator\",\"isPartOf\":{\"@id\":\"https:\/\/oualator.com\/calculate\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png\",\"datePublished\":\"2026-02-17T06:03:00+00:00\",\"dateModified\":\"2026-02-17T22:04:48+00:00\",\"description\":\"Generate custom text in a heart shape with any font, size, and colors. Create beautiful, shareable heart designs with our free online tool.\",\"breadcrumb\":{\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#primaryimage\",\"url\":\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png\",\"contentUrl\":\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png\",\"width\":968,\"height\":639,\"caption\":\"heart text generator | text on heart shape\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/oualator.com\/calculate\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Heart Shape Text Generator &#8211; Fill Heart Shape With Your Text\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/oualator.com\/calculate\/#website\",\"url\":\"https:\/\/oualator.com\/calculate\/\",\"name\":\"Oualator\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/oualator.com\/calculate\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/oualator.com\/calculate\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/oualator.com\/calculate\/#organization\",\"name\":\"Oualator\",\"url\":\"https:\/\/oualator.com\/calculate\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oualator.com\/calculate\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/03\/cropped-oualator-1.png\",\"contentUrl\":\"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/03\/cropped-oualator-1.png\",\"width\":500,\"height\":167,\"caption\":\"Oualator\"},\"image\":{\"@id\":\"https:\/\/oualator.com\/calculate\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/oualator.com\/calculate\/#\/schema\/person\/4ea451aa69c0b6773dc729ab8e30a78a\",\"name\":\"mikarmiaura\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oualator.com\/calculate\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/70d88366569bf8d9508ed6385a52290c21d112d7f9f8e8ba174309f9cd69e484?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/70d88366569bf8d9508ed6385a52290c21d112d7f9f8e8ba174309f9cd69e484?s=96&d=mm&r=g\",\"caption\":\"mikarmiaura\"},\"sameAs\":[\"https:\/\/oualator.com\/calculate\"],\"url\":\"https:\/\/oualator.com\/calculate\/author\/mikarmiaura\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Heart Shape Text Generator - Create Text in Heart Shape | Oualator","description":"Generate custom text in a heart shape with any font, size, and colors. Create beautiful, shareable heart designs with our free online tool.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/","og_locale":"en_US","og_type":"article","og_title":"Heart Shape Text Generator - Create Text in Heart Shape | Oualator","og_description":"Generate custom text in a heart shape with any font, size, and colors. Create beautiful, shareable heart designs with our free online tool.","og_url":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/","og_site_name":"Oualator","article_published_time":"2026-02-17T06:03:00+00:00","article_modified_time":"2026-02-17T22:04:48+00:00","og_image":[{"width":968,"height":639,"url":"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png","type":"image\/png"}],"author":"mikarmiaura","twitter_card":"summary_large_image","twitter_misc":{"Written by":"mikarmiaura","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#article","isPartOf":{"@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/"},"author":{"name":"mikarmiaura","@id":"https:\/\/oualator.com\/calculate\/#\/schema\/person\/4ea451aa69c0b6773dc729ab8e30a78a"},"headline":"Heart Shape Text Generator &#8211; Fill Heart Shape With Your Text","datePublished":"2026-02-17T06:03:00+00:00","dateModified":"2026-02-17T22:04:48+00:00","mainEntityOfPage":{"@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/"},"wordCount":1198,"commentCount":1,"publisher":{"@id":"https:\/\/oualator.com\/calculate\/#organization"},"image":{"@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#primaryimage"},"thumbnailUrl":"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png","articleSection":["Generator"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/","url":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/","name":"Heart Shape Text Generator - Create Text in Heart Shape | Oualator","isPartOf":{"@id":"https:\/\/oualator.com\/calculate\/#website"},"primaryImageOfPage":{"@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#primaryimage"},"image":{"@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#primaryimage"},"thumbnailUrl":"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png","datePublished":"2026-02-17T06:03:00+00:00","dateModified":"2026-02-17T22:04:48+00:00","description":"Generate custom text in a heart shape with any font, size, and colors. Create beautiful, shareable heart designs with our free online tool.","breadcrumb":{"@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#primaryimage","url":"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png","contentUrl":"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/04\/heart-text-generator.png","width":968,"height":639,"caption":"heart text generator | text on heart shape"},{"@type":"BreadcrumbList","@id":"https:\/\/oualator.com\/calculate\/heart-shape-text-generator\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/oualator.com\/calculate\/"},{"@type":"ListItem","position":2,"name":"Heart Shape Text Generator &#8211; Fill Heart Shape With Your Text"}]},{"@type":"WebSite","@id":"https:\/\/oualator.com\/calculate\/#website","url":"https:\/\/oualator.com\/calculate\/","name":"Oualator","description":"","publisher":{"@id":"https:\/\/oualator.com\/calculate\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/oualator.com\/calculate\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/oualator.com\/calculate\/#organization","name":"Oualator","url":"https:\/\/oualator.com\/calculate\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oualator.com\/calculate\/#\/schema\/logo\/image\/","url":"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/03\/cropped-oualator-1.png","contentUrl":"https:\/\/oualator.com\/calculate\/wp-content\/uploads\/2025\/03\/cropped-oualator-1.png","width":500,"height":167,"caption":"Oualator"},"image":{"@id":"https:\/\/oualator.com\/calculate\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/oualator.com\/calculate\/#\/schema\/person\/4ea451aa69c0b6773dc729ab8e30a78a","name":"mikarmiaura","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oualator.com\/calculate\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/70d88366569bf8d9508ed6385a52290c21d112d7f9f8e8ba174309f9cd69e484?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/70d88366569bf8d9508ed6385a52290c21d112d7f9f8e8ba174309f9cd69e484?s=96&d=mm&r=g","caption":"mikarmiaura"},"sameAs":["https:\/\/oualator.com\/calculate"],"url":"https:\/\/oualator.com\/calculate\/author\/mikarmiaura\/"}]}},"_links":{"self":[{"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/posts\/203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/comments?post=203"}],"version-history":[{"count":13,"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/posts\/203\/revisions"}],"predecessor-version":[{"id":680,"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/posts\/203\/revisions\/680"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/media\/204"}],"wp:attachment":[{"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/media?parent=203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/categories?post=203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oualator.com\/calculate\/wp-json\/wp\/v2\/tags?post=203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}