当前位置: 首页 > news >正文

html5+css3+canvas长文转长图工具支持换行

朋友圈神器长文转图片工具支持自动换行

效果见图,体验见左下角原文链接,原名微博长文转长图工具。

朋友圈(微博)分享文章工具,图文人必备。

另:不依赖服务器,可以自行保存网页局域网浏览器打开使用。

 


<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>增强版文章转图片生成器 chalide.cn</title>
<meta name="author" content="yujianyue, 15058593138@qq.com"><style>body {font-family: 'Arial', sans-serif;max-width: 800px;margin: 0 auto;padding: 20px;background-color: #f5f5f5;}.container {background-color: white;padding: 20px;border-radius: 8px;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);}h1 {text-align: center;color: #333;margin-bottom: 30px;}.form-group {margin-bottom: 15px;}.form-row {display: flex;flex-wrap: wrap;gap: 15px;margin-bottom: 15px;}.form-col {flex: 1;min-width: 150px;}label {display: block;margin-bottom: 5px;font-weight: bold;font-size: 14px;}textarea {width: 100%;height: 200px;padding: 10px;border: 1px solid #ddd;border-radius: 4px;box-sizing: border-box;resize: vertical;font-family: inherit;line-height: 1.5;}input, select {width: 100%;padding: 8px;border: 1px solid #ddd;border-radius: 4px;box-sizing: border-box;font-family: inherit;}.color-input {display: flex;gap: 10px;}.color-input input[type="color"] {width: 40px;height: 40px;padding: 0;border: 1px solid #ddd;}.color-input input[type="text"] {flex: 1;min-width: 100px;}.btn-group {display: flex;justify-content: center;gap: 15px;margin: 25px 0;}button {background-color: #4CAF50;color: white;border: none;padding: 10px 20px;border-radius: 4px;cursor: pointer;font-size: 16px;transition: background-color 0.3s;flex: 1;max-width: 200px;}button:hover {background-color: #45a049;}.download-btn {background-color: #2196F3;}.download-btn:hover {background-color: #0b7dda;}.image-container {text-align: center;margin-top: 30px;background-color: #f9f9f9;padding: 15px;border-radius: 4px;border: 1px dashed #ddd;}.image-preview {max-width: 100%;box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);}.error-message {color: red;text-align: center;margin: 10px 0;min-height: 20px;font-size: 14px;}.loading {text-align: center;margin: 20px 0;display: none;color: #666;}@media (max-width: 600px) {.form-col {min-width: 100%;}.btn-group {flex-direction: column;align-items: center;}button {max-width: 100%;width: 100%;}}</style>
</head>
<body><div class="container"><h1>文章转图片生成器</h1><form id="text-to-image-form"><div class="form-group"><label for="text-content">文章内容:</label><textarea id="text-content" name="text" placeholder="请输入要转换的文章内容..." required></textarea></div><div class="form-row"><div class="form-col"><label for="font-select">字体</label><select id="font-select" name="font"><option value="Arial">Arial</option><option value="Microsoft YaHei" selected>微软雅黑</option><option value="SimSun">宋体</option><option value="SimHei">黑体</option><option value="KaiTi">楷体</option></select></div><div class="form-col"><label for="font-size">字体大小 (px)</label><input type="number" id="font-size" name="font_size" min="12" max="72" value="18"></div><div class="form-col"><label for="line-height">行高 (倍数)</label><input type="number" id="line-height" name="line_height" min="1" max="3" step="0.1" value="1.5"></div></div><div class="form-row"><div class="form-col"><label for="text-color">文字颜色</label><div class="color-input"><input type="color" id="text-color-picker" value="#333333"><input type="text" id="text-color" name="text_color" value="#333333" placeholder="#333333"></div></div><div class="form-col"><label for="bg-color">背景颜色</label><div class="color-input"><input type="color" id="bg-color-picker" value="#FFFFFF"><input type="text" id="bg-color" name="bg_color" value="#FFFFFF" placeholder="#FFFFFF"></div></div><div class="form-col"><label for="padding">内边距 (px)</label><input type="number" id="padding" name="padding" min="0" max="100" value="30"></div></div><div class="btn-group"><button type="submit">生成图片</button><button type="button" id="download-btn" class="download-btn" style="display: none;">下载图片</button></div><div class="error-message" id="error-message"></div><div class="loading" id="loading">生成中,请稍候...</div></form><div class="image-container" id="image-container"><p>生成的图片将显示在这里</p></div></div><script>document.addEventListener('DOMContentLoaded', function() {// 获取DOM元素const textContent = document.getElementById('text-content');const fontSelect = document.getElementById('font-select');const fontSizeInput = document.getElementById('font-size');const textColorPicker = document.getElementById('text-color-picker');const textColorInput = document.getElementById('text-color');const bgColorPicker = document.getElementById('bg-color-picker');const bgColorInput = document.getElementById('bg-color');const lineHeightInput = document.getElementById('line-height');const paddingInput = document.getElementById('padding');const errorMessage = document.getElementById('error-message');const form = document.getElementById('text-to-image-form');const loading = document.getElementById('loading');const imageContainer = document.getElementById('image-container');const downloadBtn = document.getElementById('download-btn');// 颜色选择器和输入框同步textColorPicker.addEventListener('input', function() {textColorInput.value = this.value;});textColorInput.addEventListener('input', function() {if (/^#[0-9A-F]{6}$/i.test(this.value)) {textColorPicker.value = this.value;}});bgColorPicker.addEventListener('input', function() {bgColorInput.value = this.value;});bgColorInput.addEventListener('input', function() {if (/^#[0-9A-F]{6}$/i.test(this.value)) {bgColorPicker.value = this.value;}});// 表单提交form.addEventListener('submit', function(e) {e.preventDefault();generateImage();});// 初始生成一个示例图片textContent.value = "这是一段示例文本,用于展示文章转图片的功能。\n\n支持自动换行、自定义字体大小和颜色。当一行文本超过指定宽度时,系统会自动将其分割为多行,确保所有内容都能完整显示。\n\n图片宽度固定为728像素,高度会根据内容长度自动调整。您可以输入任意长度的文本,系统会智能处理换行和段落分隔。\n\n此外,除了文本输入区域外,其他所有控制项都采用一行三列的布局,并能够自适应不同屏幕尺寸,提供更好的用户体验。";generateImage();// 生成图片函数function generateImage() {const text = textContent.value.trim();if (!text) {errorMessage.textContent = '请输入文章内容';return;}errorMessage.textContent = '';loading.style.display = 'block';imageContainer.innerHTML = '';downloadBtn.style.display = 'none';// 使用setTimeout让UI有机会更新加载状态setTimeout(() => {try {// 创建临时canvas测量高度const measureCanvas = document.createElement('canvas');const measureCtx = measureCanvas.getContext('2d');// 设置canvas宽度const imageWidth = 728;const padding = parseInt(paddingInput.value);const contentWidth = imageWidth - padding * 2;// 设置测量上下文const fontSize = parseInt(fontSizeInput.value);const font = fontSelect.value;measureCtx.font = `${fontSize}px ${font}`;// 计算行高const lineHeight = fontSize * parseFloat(lineHeightInput.value);// 分割文本行为多行(支持段落内自动换行)const paragraphs = text.split('\n');const lines = [];paragraphs.forEach(paragraph => {if (!paragraph.trim()) {lines.push(''); // 空行return;}// 将段落分割为适合宽度的行const words = paragraph.split('');let currentLine = words[0] || '';for (let i = 1; i < words.length; i++) {const word = words[i];const testLine = currentLine + ' ' + word;const metrics = measureCtx.measureText(testLine);if (metrics.width <= contentWidth) {currentLine = testLine;} else {// 如果当前行不为空,先保存当前行if (currentLine) {lines.push(currentLine);}currentLine = word;}}// 添加最后一行if (currentLine) {lines.push(currentLine);}});// 计算总高度const contentHeight = lines.length * lineHeight;const imageHeight = contentHeight + padding * 2;// 创建实际canvasconst canvas = document.createElement('canvas');canvas.width = imageWidth;canvas.height = imageHeight;const ctx = canvas.getContext('2d');// 绘制背景ctx.fillStyle = bgColorInput.value;ctx.fillRect(0, 0, imageWidth, imageHeight);// 设置文本样式ctx.font = `${fontSize}px ${font}`;ctx.fillStyle = textColorInput.value;ctx.textAlign = 'left';ctx.textBaseline = 'top';// 绘制文本let y = padding;lines.forEach(line => {if (line === '') {// 空行处理y += lineHeight;} else {ctx.fillText(line, padding, y);y += lineHeight;}});// 显示图片const img = new Image();img.src = canvas.toDataURL('image/png');img.className = 'image-preview';img.alt = '生成的图片';imageContainer.innerHTML = '';imageContainer.appendChild(img);// 设置下载链接downloadBtn.onclick = function() {const link = document.createElement('a');link.href = canvas.toDataURL('image/png');link.download = `article-image-${Date.now()}.png`;document.body.appendChild(link);link.click();document.body.removeChild(link);};downloadBtn.style.display = 'block';loading.style.display = 'none';} catch (error) {console.error('生成图片出错:', error);errorMessage.textContent = '生成图片时出错: ' + error.message;loading.style.display = 'none';}}, 100);}});</script>
</body>
</html>

 

http://www.dtcms.com/a/310847.html

相关文章:

  • 国产嵌入式调试器之光? RT-Trace 初体验!
  • C++之vector类的代码及其逻辑详解 (中)
  • 电力系统分析学习笔记
  • 谷歌Chrome浏览器安装插件
  • 论文笔记:Bundle Recommendation and Generation with Graph Neural Networks
  • 设计Mock华为昇腾GPU的MindSpore和CANN的库的流程与实现
  • STM32——启动过程浅析
  • 个人电脑部署私有化大语言模型LLM
  • python+pyside6的简易画板
  • 损失函数和调度器相关类代码回顾理解 |nn.CrossEntropyLoss\CosineAnnealingLR
  • Codeforces Round 1040 (Div. 2) A - D题详细题解
  • DP-v2.1-mem-clean学习(3.6.8-3.6.8.1)
  • Java试题-选择题(3)
  • 风光储并离网切换仿真模型(下垂控制一次调频)
  • CORS模块:你的跨域快速通行证 [特殊字符]
  • 第七章 愿景13 CBS升级
  • Git 误删分支怎么恢复
  • 中国不同类型竹林分布数据
  • 一个强大的向量数据库——Milvus
  • 8.1.2 TiDB存储引擎的原理
  • 鹧鸪云:16步精控工商业光伏全流程
  • Au速成班-多轨编辑流程
  • C语言函数指针和结构体
  • 第13届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2022年1月22日真题
  • socket编程-UDP(2)-设计翻译系统
  • 基于线性规划的储能充放电仿真系统
  • 读取数据集及数据集划分
  • 7.苹果ios逆向-目录结构
  • 【vue】Vue 项目创建工具对比:vue create 与 create-vue 的核心区别
  • 安卓开发--LinearLayout(线性布局)