tailwind自定义 Web 组件将文本转换为可配置的 SVG 手绘手写文字效果代码

代码语言:html

所属分类:其他

代码描述:tailwind自定义 Web 组件将文本转换为可配置的 SVG 手绘手写文字效果代码

代码标签: tailwind 自定义 Web 组件 文本 转换 配置 SVG 手绘 文字 代码

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/tailwindcss.3.4.3.js"></script>
</head>
<body class="bg-gray-50 p-4">
  <div class="max-w-2xl mx-auto">
		 <div class="text-center">
      <h1 class="text-3xl font-bold text-gray-900 mb-3">&lt;scribble-text&gt;</h1>
      <p class="text-lg text-gray-600 mb-2">A Custom Element for Generating SVG Text Scribbles</p>
      <div class="prose max-w-none text-sm text-gray-600 bg-white rounded-lg p-4 border border-gray-200">
        <p class="font-medium mb-2">TL;DR:</p>
        <p>A Web Component that converts text into randomized, configurable SVG "scribbles" that mimic handwritten text. Created through a conversation between Claude and Netsi1964, who prompted the development of a component that could render text as SVG with adjustable parameters like font size, weight, and wiggle factor. The component separates rendering logic from UI, making it flexible for various use cases.</p>
        <p class="text-xs mt-2 text-gray-500">Created: October 2024 | Prompted by: Netsi1964</p>
      </div>
    </div>
    <!-- Main Container -->
    <div class="bg-white rounded-lg shadow p-6">
      <!-- Text Input -->
      <textarea
        id="text-input"
        class="w-full p-3 mb-4 border border-gray-200 rounded-lg h-24 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 outline-none transition-all"
        placeholder="Type something... (use Enter for new lines)"
      >Hello world&#13;&#10;This is a new line</textarea>
      
      <!-- Controls Grid -->
      <div class="grid grid-cols-2 gap-4 mb-4">
        <!-- Font Size -->
        <div class="space-y-1">
          <label class="block text-sm text-gray-600">Font Size (<span id="fontSize-value">24</span>px)</label>
          <input
            type="range"
            id="font-size"
            min="12"
            max="48"
            value="24"
            class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-500"
          >
        </div>

        <!-- Font Weight -->
        <div class="space-y-1">
          <label class="block text-sm text-gray-600">Font Weight (<span id="fontWeight-value">400</span> - <span id="fontWeight-label">Regular</span>)</label>
          <input
            type="range"
            id="font-weight"
            min="100"
            max="900"
            step="100"
            value="400"
            class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-500"
          >
          <!-- Weight Presets -->
          <div class="flex flex-wrap gap-2 mt-2" id="weight-presets">
          </div>
        </div>

        <!-- Wiggle -->
        <div class="space-y-1">
          <label class="block text-sm text-gray-600">Wiggle (<span id="wiggle-value">0.7</span>)</label>
          <input
            type="range"
            id="wiggle"
            min="0"
            max="1"
            step="0.1"
            value="0.7"
            class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-500"
          >
        </div>

        <!-- Width -->
        <div class="space-y-1">
          <label class="block text-sm text-gray-600">Width (<span id="maxWidth-value">400</span>px)</label>
          <input
            type="range"
            id="max-width"
            min="200"
            max="800"
            step="50"
            value="400"
            class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-500"
          >
        </div>
      </div>

      <!-- SVG Container -->
      <div class="border border-gray-200 rounded-lg bg-white overflow-hidden mb-4">
				<scribble-text 
  id="scribble" 
  max-width="400"
></scribble-text>
      </div>

      <!-- Export Controls -->
      <div class="flex gap-3">
        <button
          id="copy-btn"
          class="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition-colors flex-1 text-sm font-medium"
        >Copy SVG</button>
        <button
          id="download-btn"
          class="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition-colors flex-1 text-sm font-medium"
        >Download SVG</button>
      </div>
    </div>
  </div>

  <script>
    const weightPresets = [
  { value: 100, label: 'Thin', tw: 'font-thin' },
  { value: 200, label: 'Extra Light', tw: 'font-extralight' },
  { value: 300, label: 'Light', tw: 'font-light' },
  { value: 400, label: 'Regular', tw: 'font-normal' },
  { value: 500, label: 'Medium', tw: 'font-medium' },
  { value: 600, label: 'Semi Bold', tw: 'font-semibold' },
  { value: 700, label: 'Bold', tw: 'font-bold' },
  { value: 800, label: 'Extra Bold', tw: 'font-extrabold' },
  { value: 900, label: 'Black', tw: 'font-black' },
];

    // Initialize weight preset buttons
    const presetContainer = document.getElementById('weight-presets');
    weightPresets.forEach(preset => {
      const button = document.createElement('button');
      button.className = 'px-2 py-1 text-xs rounded-md transition-colors';
      button.dataset.weight = preset.value;
      button.textContent = preset.value;
      button.addEventListener('click', () => {
        const weightInput = document.getElementById('font-weight');
        weightInput.value = preset.value;
        updateConfig('fontWeight', preset.value);
        updateWeightPresetButtons();
      });
      presetContainer.appendChild(button);
    });

    function updateWeightPresetButtons() {
  const currentWeight = document.getElementById('font-weight').value;
  const buttons = presetContainer.querySelectorAll('button');

  buttons.forEach(button => {
    const buttonWeight = button.dataset.weight;

    // Find the preset matching the button's weight
    const preset = weightPresets.find(item => item.value.toString() === buttonWeight);

    if (buttonWeight === currentWeight) {
      // Active button styles
      button.className = `px-2 py-1 text-xs rounded-md bg-blue-500 text-white transition-colors ${preset ? preset.tw : ''}`;
    } else {
      // Inactive button styles
      button.className = `px-2 py-1 text-xs rounded-md bg-gray-100 hover:bg-gray-200 transition-colors ${preset ? preset.tw : ''}`;
    }
  });
}

    // Initialize UI
    const scribble = document.getElementById('scribble');
    const textInput = document.getElementById('text-input');
    const copyBtn = document.getElementById('copy-btn');
    const downloadBtn = document.getElementById('download-btn');

    // Update text
    textInput.addEventListener('input', (e) => {
      scribble.setText(e.target.value);
    });

    // Update settings with label updates
    const updateConfig = (param, value) => {
      scribble.setConfig({ [param]: Number(value) });
      document.getElementById(`${param}-value`).textContent = value;
      
      if (param === 'fontWeight') {
        const weightLabel = weightPresets.find(w => w.value == parseInt(value))?.label;
        document.getElementById('fontWeight-label').textContent = weightLabel;
        updateWeightPresetButtons();
      }
    };

    // Setup all range inputs
    ['font-size', 'font-weight', 'wiggle', 'max-width'].forEach(id => {
      const input = document.getElementById(id);
      const param = id.replace(/-./g, x => x[1].toUpperCase());
      input.addEventListener('input', (e) => updateConfig(param, e.target.value));
    });

    // Export actions
    copyBtn.addEventListener('click', async () => {
      try {
        await scribble.copyToClipboard({ prettyPrint: true });
        copyBtn.textContent = 'Copied!';
        setTimeout(() => { copyBtn.textContent = 'Copy SVG'; }, 2000);
      } catch (err) {
        copyBtn.textContent = 'Error!';
        setTimeout(() => { copyBtn.textContent = 'Copy SVG'; }, 2000);
      }
    });

    downloadBtn.addEventListener('click', () => {
      scribble.downloadSVG('scribble', { prettyPrint: true });
    });

    // Initialize weight presets
    updateWeightPresetButtons();

    // Set initial text
    scribble.setText(textInput.value);
  </script>

<!-- partial -->
  <script  >
      
      /**
 * ScribbleText Custom Element
 * A component that converts text into SVG scribbles with configurable parameters
 * Created by: Netsi1964 (prompt) and Claude (implementation)
 * October 2024.........完整代码请登录后点击上方下载按钮下载查看

网友评论0