如何实现文字自动生成封面,使用纯色背景或者图片上填充文字

161 阅读1分钟
  1. 最基础的纯色背景 + 文字:
function createCover(text, width = 800, height = 400) {
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');
    
    // 绘制背景
    ctx.fillStyle = '#f0f0f0';  // 背景色
    ctx.fillRect(0, 0, width, height);
    
    // 设置文字样式
    ctx.fillStyle = '#333';  // 文字颜色
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    
    // 自动调整文字大小
    let fontSize = 100;
    do {
        ctx.font = `${fontSize}px Arial`;
        fontSize -= 5;
    } while (ctx.measureText(text).width > width * 0.8);
    
    // 绘制文字
    ctx.fillText(text, width/2, height/2);
    
    return canvas.toDataURL();
}
  1. 带渐变背景的版本:
function createGradientCover(text, width = 800, height = 400) {
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');
    
    // 创建渐变背景
    const gradient = ctx.createLinearGradient(0, 0, width, height);
    gradient.addColorStop(0, '#ff6b6b');
    gradient.addColorStop(1, '#4ecdc4');
    
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);
    
    // 文字样式
    ctx.fillStyle = '#fff';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    
    // 自动换行处理
    function wrapText(text, maxWidth) {
        const words = text.split(' ');
        const lines = [];
        let currentLine = words[0];

        for(let i = 1; i < words.length; i++) {
            const word = words[i];
            const width = ctx.measureText(currentLine + " " + word).width;
            if(width < maxWidth) {
                currentLine += " " + word;
            } else {
                lines.push(currentLine);
                currentLine = word;
            }
        }
        lines.push(currentLine);
        return lines;
    }
    
    // 绘制文字
    let fontSize = 100;
    let lines;
    do {
        ctx.font = `${fontSize}px Arial`;
        lines = wrapText(text, width * 0.8);
        fontSize -= 5;
    } while (lines.length * fontSize > height * 0.8);
    
    const lineHeight = fontSize * 1.2;
    const startY = height/2 - (lines.length - 1) * lineHeight/2;
    
    lines.forEach((line, i) => {
        ctx.fillText(line, width/2, startY + i * lineHeight);
    });
    
    return canvas.toDataURL();
}
  1. 使用背景图片的版本:
async function createImageCover(text, imageUrl, width = 800, height = 400) {
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');
    
    // 加载背景图片
    const img = new Image();
    img.crossOrigin = 'anonymous';  // 如果需要跨域
    
    await new Promise((resolve, reject) => {
        img.onload = resolve;
        img.onerror = reject;
        img.src = imageUrl;
    });
    
    // 绘制并调整背景图片
    const scale = Math.max(width / img.width, height / img.height);
    const scaledWidth = img.width * scale;
    const scaledHeight = img.height * scale;
    const x = (width - scaledWidth) / 2;
    const y = (height - scaledHeight) / 2;
    
    ctx.drawImage(img, x, y, scaledWidth, scaledHeight);
    
    // 添加半透明遮罩使文字更清晰
    ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';
    ctx.fillRect(0, 0, width, height);
    
    // 文字样式
    ctx.fillStyle = '#fff';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
    ctx.shadowBlur = 10;
    
    // 自动调整文字大小和换行
    let fontSize = 100;
    let lines;
    do {
        ctx.font = `bold ${fontSize}px Arial`;
        const words = text.split(' ');
        lines = [];
        let currentLine = words[0];
        
        for(let i = 1; i < words.length; i++) {
            const word = words[i];
            const testLine = currentLine + " " + word;
            const metrics = ctx.measureText(testLine);
            if(metrics.width > width * 0.8) {
                lines.push(currentLine);
                currentLine = word;
            } else {
                currentLine = testLine;
            }
        }
        lines.push(currentLine);
        fontSize -= 5;
    } while (lines.length * fontSize > height * 0.8);
    
    // 绘制文字
    const lineHeight = fontSize * 1.2;
    const startY = height/2 - (lines.length - 1) * lineHeight/2;
    
    lines.forEach((line, i) => {
        ctx.fillText(line, width/2, startY + i * lineHeight);
    });
    
    return canvas.toDataURL();
}

// 使用示例
async function test() {
    // 纯色背景
    const cover1 = createCover('Hello World');
    document.body.innerHTML += `<img src="${cover1}"><br>`;
    
    // 渐变背景
    const cover2 = createGradientCover('Hello World with Gradient');
    document.body.innerHTML += `<img src="${cover2}"><br>`;
    
    // 图片背景
    const cover3 = await createImageCover(
        'Hello World with Image Background',
        'https://example.com/background.jpg'
    );
    document.body.innerHTML += `<img src="${cover3}"><br>`;
}

主要功能:

  1. 自动调整文字大小以适应画布
  2. 支持文字自动换行
  3. 支持多种背景样式
  4. 文字阴影和遮罩层提升可读性
  5. 居中对齐

可以根据需要调整:

  • 字体样式
  • 颜色搭配
  • 边距比例
  • 文字效果
  • 背景处理方式

注意事项:

  1. 使用背景图片时需要注意跨域问题
  2. 图片加载可能需要错误处理
  3. 文字大小的计算可能需要根据具体需求调整
  4. 考虑添加缓存机制提升性能