根据输入汉字生成带拼音的米字格字帖

实现了下面功能:
1、根据输入汉字,自动调整米字格和四线格的行数;
2、给汉字自动加上拼音和声调(暂时不考虑多音字);
3、汉字在米字格,拼音在四线格,
4、第一列用黑色,2-5列四列浅灰以描摹,第6列默写;
5、暂时调整这么多。
在这里插入图片描述

在这里插入图片描述
我的一个发现:用大语言模型写代码,局限性还是太多。要想完成复杂的项目,不但功能、界面设计方面要深度介入,由于当前大模型的局限太多,如何选择模型、如何使用提示词、按照何种次序和起始点来使用大模型和提示词,都是需要练习和反复练习的。

所以,完全否定通过AI生成的作品的“著作权”是不合适的。大模型就是计算机的智能键盘、是画家的智能画布和笔刷。好作品仍然需要付出很多创造性劳动和非创造性劳动。

在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>四线格与米字格生成器(带拼音)</title>
    <style>
        @font-face {
            font-family: 'TeXGyreAdventor';
            src: 
                local('TeX Gyre Adventor'),
                url('fonts/texgyreadventor-regular.woff2') format('woff2'),
                url('fonts/texgyreadventor-regular.otf') format('opentype');
            font-display: swap;
        }
        body {
            font-family: 'TeXGyreAdventor', 'KaiTi', serif;
            text-align: center;
            padding: 20px;
        }
        #input-container {
            margin-bottom: 20px;
        }
        #hanzi-input {
            font-size: 28px;
            padding: 10px;
            width: 300px;
        }
        #generate-btn, #print-btn, #clear-btn {
            font-size: 18px;
            padding: 10px 20px;
            margin: 0 10px;
        }
        #grid-container {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .row {
            display: flex;
            position: relative;
            width: 600px; /* 6列总宽度 */
        }
        /* 四线格样式 */
        .pinyin-row {
            height: 48px; /* 3个16px间距 */
        }
        .pinyin-cell {
            width: 100px;
            height: 48px;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .pinyin-row.first::before, .pinyin-row .line1, .pinyin-row .line2, .pinyin-row::after {
            content: '';
            position: absolute;
            width: 600px; /* 与米字格等宽 */
            height: 0;
            left: 0;
            border: 1px solid red; /* 红色实线 */
            z-index: 0; /* 底层 */
        }
        .pinyin-row.first::before {
            top: 0; /* 第一行四线格第1条 */
        }
        .pinyin-row .line1 {
            top: 16px; /* 第2条 */
        }
        .pinyin-row .line2 {
            top: 32px; /* 第3条 */
        }
        .pinyin-row::after {
            bottom: 0; /* 底部边框,与下方米字格共用 */
        }
        .pinyin-cell span {
            font-family: 'TeXGyreAdventor', 'KaiTi', serif;
            font-size: 28px; /* 调整为28号字体 */
            position: relative;
            z-index: 1; /* 文字在上层 */
        }
        .black span {
            color: black;
            opacity: 1;
        }
        .gray span {
            color: black;
            opacity: 0.25;
        }
        /* 米字格样式 */
        .char-row {
            margin-top: -1px; /* 与上方共用边框 */
        }
        .cell {
            width: 100px;
            height: 100px;
            border-bottom: 1px solid red; /* 底部边框 */
            border-right: 1px solid red; /* 右侧边框 */
            border-left: 1px solid red; /* 左侧边框,首列使用 */
            position: relative;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 72px;
            font-family: '海棠未雨', serif;
        }
        .cell:not(:first-child) {
            border-left: none; /* 水平共用边框 */
        }
        .char-row .cell {
            border-top: 1px solid red; /* 所有米字格保留顶部边框,与上方四线格共用 */
        }
        .cell::before, .cell::after {
            content: '';
            position: absolute;
            border: 1px dashed red; /* 红色虚线 */
            z-index: 0; /* 底层 */
        }
        .cell::before {
            width: 100%;
            height: 0;
            top: 50%;
            left: 0;
            transform: translateY(-50%);
        }
        .cell::after {
            width: 0;
            height: 100%;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
        }
        .diagonal1, .diagonal2 {
            position: absolute;
            width: 141px;
            height: 0;
            border: 1px dashed red; /* 红色虚线 */
            z-index: 0; /* 底层 */
        }
        .diagonal1 {
            top: 0;
            left: 0;
            transform: rotate(45deg);
            transform-origin: 0 0;
        }
        .diagonal2 {
            bottom: 0;
            left: 0;
            transform: rotate(-45deg);
            transform-origin: 0 100%;
        }
        .cell span {
            position: relative;
            z-index: 1; /* 文字在上层 */
        }
        .black span {
            color: black;
            opacity: 1;
        }
        .gray span {
            color: black;
            opacity: 0.25;
        }
        @media print {
            #input-container, #generate-btn, #print-btn, #clear-btn {
                display: none;
            }
            #grid-container {
                display: block;
            }
        }
    </style>
</head>
<body>
    <div id="input-container">
        <input type="text" id="hanzi-input" value="寳寶氷麤鳯龘">
        <button id="clear-btn">清除</button>
        <button id="generate-btn">生成</button>
        <button id="print-btn">打印</button>
    </div>
    <div id="grid-container"></div>

    <!-- 引入拼音库文件 -->
    <script type="text/javascript" src="./pinyin_dict_withtone.js"></script>
    <script type="text/javascript" src="./pinyinUtil.js"></script>
    <!-- 引入 html2canvas 和 jsPDF 库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>

    <script>
        window.onload = function() {
            generateGrid();
        };

        function generateGrid() {
            const input = document.getElementById('hanzi-input').value;
            const gridContainer = document.getElementById('grid-container');
            gridContainer.innerHTML = ''; // 清空现有内容

            // 获取拼音(带声调)
            const pinyinArray = pinyinUtil.getPinyin(input, ' ', true, false).split(' ');

            for (let i = 0; i < input.length; i++) {
                // 生成四线格行(填充拼音)
                const pinyinRow = document.createElement('div');
                pinyinRow.className = 'row pinyin-row';
                if (i === 0) {
                    pinyinRow.classList.add('first'); // 第一行四线格有3条独立线
                } else {
                    pinyinRow.style.marginTop = '-1px'; // 与上方米字格共用底部边框
                }
                const line1 = document.createElement('div');
                line1.className = 'line1';
                const line2 = document.createElement('div');
                line2.className = 'line2';
                pinyinRow.appendChild(line1);
                pinyinRow.appendChild(line2);
                for (let j = 0; j < 6; j++) {
                    const pinyinCell = document.createElement('div');
                    pinyinCell.className = 'pinyin-cell';
                    const span = document.createElement('span');
                    if (j === 0) {
                        span.textContent = pinyinArray[i] || ''; // 第一列填充拼音
                        span.classList.add('black');
                    } else if (j < 5) {
                        // span.textContent = pinyinArray[i] || ''; // 第二到第五列灰色拼音
                        // span.classList.add('gray');
                    }
                    pinyinCell.appendChild(span);
                    pinyinRow.appendChild(pinyinCell);
                }
                gridContainer.appendChild(pinyinRow);

                // 生成米字格行(填充汉字)
                const charRow = document.createElement('div');
                charRow.className = 'row char-row';
                for (let j = 0; j < 6; j++) {
                    const cell = document.createElement('div');
                    cell.className = 'cell';
                    const diag1 = document.createElement('div');
                    diag1.className = 'diagonal1';
                    const diag2 = document.createElement('div');
                    diag2.className = 'diagonal2';
                    cell.appendChild(diag1);
                    cell.appendChild(diag2);
                    const span = document.createElement('span');
                    if (j === 0) {
                        span.textContent = input[i]; // 每个汉字填充到米字格第一列
                        cell.classList.add('black');
                    } else if (j < 5) {
                        span.textContent = input[i]; // 第二到第五列灰色
                        cell.classList.add('gray');
                    }
                    cell.appendChild(span);
                    charRow.appendChild(cell);
                }
                gridContainer.appendChild(charRow);
            }
        }

        document.getElementById('generate-btn').addEventListener('click', function() {
            generateGrid();
        });

        document.getElementById('print-btn').addEventListener('click', function() {
            const gridContainer = document.getElementById('grid-container');
            
            // 使用 html2canvas 将 grid-container 渲染为图像
            html2canvas(gridContainer, {
                scale: 2, // 提高分辨率,确保清晰度
                useCORS: true, // 处理可能的跨域问题
                backgroundColor: '#ffffff', // 设置背景为白色,避免透明
                logging: true // 启用日志以便调试
            }).then(canvas => {
                const imgData = canvas.toDataURL('image/png'); // 将 Canvas 转换为 PNG 图像数据
                const { jsPDF } = window.jspdf; // 从全局对象中获取 jsPDF
                const doc = new jsPDF({
                    orientation: 'portrait',
                    unit: 'mm',
                    format: 'a4'
                });

                // 计算图像在 PDF 中的尺寸
                const pageWidth = 210; // A4 宽度 (mm)
                const pageHeight = 297; // A4 高度 (mm)
                const margin = 10; // 边距
                const imgWidth = pageWidth - 2 * margin; // PDF 中图像宽度
                const imgHeight = (canvas.height * imgWidth) / canvas.width; // 按比例计算高度
                let heightLeft = imgHeight;
                let position = margin; // 从顶部边距开始

                // 添加第一页图像
                doc.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight);
                heightLeft -= (pageHeight - 2 * margin);

                // 处理分页
                while (heightLeft > 0) {
                    doc.addPage();
                    position = -heightLeft + margin; // 调整位置以显示剩余部分
                    doc.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight);
                    heightLeft -= (pageHeight - 2 * margin);
                }

                // 保存 PDF 文件
                doc.save('字帖.pdf');
            }).catch(error => {
                console.error('html2canvas 渲染失败:', error);
                alert('生成 PDF 失败,请检查控制台错误信息。');
            });
        });

        document.getElementById('clear-btn').addEventListener('click', function() {
            const input = document.getElementById('hanzi-input');
            const gridContainer = document.getElementById('grid-container');
            input.value = '';
            gridContainer.innerHTML = '';
            input.focus();
        });
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值