idcard / index2.html
mistpe's picture
Create index2.html
9ac6a1f verified
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>浙江水利水电学院学风督查工作证</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700&display=swap');
body {
font-family: 'Noto Sans SC', sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.id-card-container {
display: flex;
gap: 30px;
}
.id-card {
width: 255px;
height: 380px;
perspective: 1000px;
cursor: pointer;
}
.id-card-inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.6s;
transform-style: preserve-3d;
}
.id-card:hover .id-card-inner {
transform: rotateY(180deg);
}
.id-card-front, .id-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0,0,0,0.1);
overflow: hidden;
}
.id-card-front {
background-color: #fff;
}
.id-card-back {
background-color: #fff;
transform: rotateY(180deg);
}
.water-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(45deg, rgba(173,216,230,0.2) 0%, rgba(0,191,255,0.2) 100%);
clip-path: polygon(0 0, 100% 0, 100% 75%, 75% 100%, 0 100%);
}
.content {
position: relative;
z-index: 1;
padding: 20px;
display: flex;
flex-direction: column;
height: 100%;
box-sizing: border-box;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.title-container {
text-align: left;
}
.title {
font-size: 14px;
font-weight: bold;
text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
margin-bottom: 2px;
}
.title-en {
font-size: 8px;
color: #666;
}
.logo {
width: 50px;
height: 50px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="45" fill="%230066cc"/><path d="M30 70 Q 50 20, 70 70 T 90 50" stroke="white" fill="none" stroke-width="8"/></svg>') no-repeat center/contain;
}
.info {
display: flex;
flex-direction: column;
align-items: center;
flex-grow: 1;
}
.photo {
width: 90px;
height: 117px;
background-color: #eee;
border-radius: 10px;
margin-bottom: 15px;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.details {
width: 100%;
text-align: left;
padding: 0 10px;
}
.details p {
margin: 8px 0;
font-size: 12px;
color: #333;
}
.footer {
margin-top: auto;
text-align: center;
}
.qr-code {
width: 80px;
height: 80px;
background-color: #fff;
border-radius: 5px;
overflow: hidden;
margin: 0 auto;
}
.qr-code img {
width: 100%;
height: 100%;
object-fit: contain;
}
.watermark {
position: absolute;
bottom: 10px;
right: 10px;
font-size: 30px;
color: rgba(0,102,204,0.1);
transform: rotate(-30deg);
}
.student .water-bg { background: linear-gradient(45deg, rgba(173,216,230,0.3) 0%, rgba(0,191,255,0.3) 100%); }
.staff .water-bg { background: linear-gradient(45deg, rgba(144,238,144,0.3) 0%, rgba(0,255,127,0.3) 100%); }
.student .title, .student .logo { color: #0066cc; }
.staff .title, .staff .logo { color: #009933; }
.back-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 15px;
text-align: center;
}
.student .back-title { color: #0066cc; }
.staff .back-title { color: #009933; }
.back-content {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
flex-grow: 1;
}
.back-text {
font-size: 12px;
color: #333;
text-align: left;
margin-bottom: 15px;
}
.wave-bg {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 50%;
opacity: 0.5;
}
.student .wave-bg {
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="%230066cc" fill-opacity="0.1" d="M0,64L48,80C96,96,192,128,288,128C384,128,480,96,576,85.3C672,75,768,85,864,122.7C960,160,1056,224,1152,245.3C1248,267,1344,245,1392,234.7L1440,224L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg>') no-repeat bottom/cover;
}
.staff .wave-bg {
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="%23009933" fill-opacity="0.1" d="M0,96L48,112C96,128,192,160,288,165.3C384,171,480,149,576,149.3C672,149,768,171,864,165.3C960,160,1056,128,1152,117.3C1248,107,1344,117,1392,122.7L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg>') no-repeat bottom/cover;
}
.back-footer {
font-size: 10px;
color: #666;
margin-top: 10px;
}
.edit-form-container {
position: fixed;
top: 20px;
right: 20px;
width: 340px;
height: 95vh;
background-color: #ffffff;
border-radius: 12px;
box-shadow: 0 0 20px rgba(0,0,0,0.1);
overflow: hidden;
z-index: 1000;
}
.edit-form {
height: 100%;
overflow-y: auto;
padding: 20px;
box-sizing: border-box;
}
.edit-form h2 {
margin-top: 0;
color: #333;
font-size: 24px;
text-align: center;
margin-bottom: 20px;
}
.edit-form label {
display: block;
margin-top: 15px;
color: #555;
font-weight: bold;
}
.edit-form input[type="text"],
.edit-form input[type="file"],
.edit-form select,
.edit-form textarea {
width: 100%;
padding: 8px;
margin-top: 5px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
box-sizing: border-box;
}
.edit-form input[type="file"] {
border: none;
}
.edit-form textarea {
resize: vertical;
min-height: 100px;
}
.edit-form button {
width: 100%;
margin-top: 20px;
padding: 12px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s;
}
.edit-form button:hover {
background-color: #45a049;
}
/* 修改导出按钮样式 */
#export-button {
width: 30vh;
position: fixed;
bottom: 20px;
right: 20px;
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s;
}
#export-button:hover {
background-color: #45a049;
}
</style>
<!-- 只需要 html2canvas 库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.2/html2canvas.min.js"></script>
</head>
<body>
<div class="id-card-container">
<!-- 学生卡片 -->
<div class="id-card student">
<div class="id-card-inner">
<div class="id-card-front">
<div class="water-bg"></div>
<div class="content">
<div class="header">
<div class="title-container">
<div class="title" id="student-title">学生学风督察员</div>
<div class="title-en" id="student-title-en">Student Academic Integrity Inspector</div>
</div>
<div class="logo" id="student-logo"></div>
</div>
<div class="info">
<div class="photo" id="student-photo"></div>
<div class="details">
<p><strong>姓名 / Name:</strong> <span id="student-name">王小明</span></p>
<p><strong>学院 / College:</strong> <span id="student-college">环境科学学院</span></p>
<p><strong>学号 / Student ID:</strong> <span id="student-id">2024002</span></p>
<p><strong>所属部门 / Dept.:</strong> <span id="student-department">学风督察委员会</span></p>
</div>
</div>
<div class="footer">
<div style="font-size: 10px; color: #666;">
<div id="student-school">浙江水利水电学院</div>
<div id="student-school-en">Zhejiang University of Water Resources and Electric Power</div>
</div>
</div>
</div>
<div class="watermark">水利水电</div>
</div>
<div class="id-card-back">
<div class="content">
<div class="back-title">学生学风督察员工作守则</div>
<div class="back-content">
<div class="back-text" id="student-rules">
1. 严格遵守学校规章制度<br>
2. 公正公平,不徇私舞弊<br>
3. 尊重隐私,保护个人信息<br>
4. 及时反馈,协助改进学风<br>
5. 积极参与,推广优良学风
</div>
<div class="qr-code">
<img id="student-qr" src="" alt="QR Code">
</div>
</div>
<div class="back-footer" id="student-footer">
本证件由浙江水利水电学院授权发行<br>
如有遗失,请及时与学生工作处联系<br>
联系电话:0571-88888888
</div>
</div>
<div class="wave-bg"></div>
</div>
</div>
</div>
<!-- 教职工卡片 -->
<div class="id-card staff">
<div class="id-card-inner">
<div class="id-card-front">
<div class="water-bg"></div>
<div class="content">
<div class="header">
<div class="title-container">
<div class="title" id="staff-title">教职工学风督察员</div>
<div class="title-en" id="staff-title-en">Faculty Academic Integrity Inspector</div>
</div>
<div class="logo" id="staff-logo"></div>
</div>
<div class="info">
<div class="photo" id="staff-photo"></div>
<div class="details">
<p><strong>姓名 / Name:</strong> <span id="staff-name">陈教授</span></p>
<p><strong>学院 / College:</strong> <span id="staff-college">环境科学学院</span></p>
<p><strong>工号 / Staff ID:</strong> <span id="staff-id">T2024002</span></p>
<p><strong>所属部门 / Dept.:</strong> <span id="staff-department">教务处</span></p>
</div>
</div>
<div class="footer">
<div style="font-size: 10px; color: #666;">
<div id="staff-school">浙江水利水电学院</div>
<div id="staff-school-en">Zhejiang University of Water Resources and Electric Power</div>
</div>
</div>
</div>
<div class="watermark">水利水电</div>
</div>
<div class="id-card-back">
<div class="content">
<div class="back-title">教职工学风督察员职责</div>
<div class="back-content">
<div class="back-text" id="staff-rules">
1. 引导和督促学生遵守学习纪律<br>
2. 组织开展学风建设相关活动<br>
3. 定期评估并报告学风状况<br>
4. 制定学风改进方案并实施<br>
5. 参与学风评估和奖惩决策
</div>
<div class="qr-code">
<img id="staff-qr" src="" alt="QR Code">
</div>
</div>
<div class="back-footer" id="staff-footer">
本证件由浙江水利水电学院授权发行<br>
如有遗失,请及时与人事处联系<br>
联系电话:0571-99999999
</div>
</div>
<div class="wave-bg"></div>
</div>
</div>
</div>
</div>
<!-- 编辑表单 -->
<div class="edit-form-container">
<div class="edit-form">
<h2>编辑卡片信息</h2>
<label for="card-type">选择卡片类型:</label>
<select id="card-type">
<option value="student">学生卡片</option>
<option value="staff">教职工卡片</option>
</select>
<label for="edit-title">标题:</label>
<input type="text" id="edit-title">
<label for="edit-title-en">英文标题:</label>
<input type="text" id="edit-title-en">
<label for="edit-logo">Logo:</label>
<input type="file" id="edit-logo" accept="image/*">
<label for="edit-photo">照片:</label>
<input type="file" id="edit-photo" accept="image/*">
<label for="edit-name">姓名:</label>
<input type="text" id="edit-name">
<label for="edit-college">学院:</label>
<input type="text" id="edit-college">
<label for="edit-id">学号/工号:</label>
<input type="text" id="edit-id">
<label for="edit-department">所属部门:</label>
<input type="text" id="edit-department">
<label for="edit-school">学校名称:</label>
<input type="text" id="edit-school">
<label for="edit-school-en">学校英文名称:</label>
<input type="text" id="edit-school-en">
<label for="edit-rules">背面规则:</label>
<textarea id="edit-rules" rows="5"></textarea>
<label for="edit-footer">背面页脚:</label>
<textarea id="edit-footer" rows="3"></textarea>
<button id="export-button" onclick="exportToImages()">导出为图片</button>
</div>
</div>
<script>
// 预设文本
const defaultTexts = {
student: {
title: "学生学风督察员",
titleEn: "Student Academic Integrity Inspector",
name: "王小明",
college: "环境科学学院",
id: "2024002",
department: "学风督察委员会",
school: "浙江水利水电学院",
schoolEn: "Zhejiang University of Water Resources and Electric Power",
rules: "1. 严格遵守学校规章制度\n2. 公正公平,不徇私舞弊\n3. 尊重隐私,保护个人信息\n4. 及时反馈,协助改进学风\n5. 积极参与,推广优良学风",
footer: "本证件由浙江水利水电学院授权发行\n如有遗失,请及时与学生工作处联系\n联系电话:0571-88888888"
},
staff: {
title: "教职工学风督察员",
titleEn: "Faculty Academic Integrity Inspector",
name: "陈教授",
college: "环境科学学院",
id: "T2024002",
department: "教务处",
school: "浙江水利水电学院",
schoolEn: "Zhejiang University of Water Resources and Electric Power",
rules: "1. 引导和督促学生遵守学习纪律\n2. 组织开展学风建设相关活动\n3. 定期评估并报告学风状况\n4. 制定学风改进方案并实施\n5. 参与学风评估和奖惩决策",
footer: "本证件由浙江水利水电学院授权发行\n如有遗失,请及时与人事处联系\n联系电话:0571-99999999"
}
};
// 加载时生成初始二维码
window.onload = function() {
generateQRCode('student');
generateQRCode('staff');
loadDefaultValues();
}
function loadDefaultValues() {
const type = document.getElementById('card-type').value;
const defaults = defaultTexts[type];
document.getElementById('edit-title').value = defaults.title;
document.getElementById('edit-title-en').value = defaults.titleEn;
document.getElementById('edit-name').value = defaults.name;
document.getElementById('edit-college').value = defaults.college;
document.getElementById('edit-id').value = defaults.id;
document.getElementById('edit-department').value = defaults.department;
document.getElementById('edit-school').value = defaults.school;
document.getElementById('edit-school-en').value = defaults.schoolEn;
document.getElementById('edit-rules').value = defaults.rules;
document.getElementById('edit-footer').value = defaults.footer;
// 更新卡片显示
updateCard();
}
// 当卡片类型改变时,重新加载默认值
document.getElementById('card-type').addEventListener('change', loadDefaultValues);
function generateQRCode(type) {
const content = JSON.stringify({
name: document.getElementById(`${type}-name`).textContent,
id: document.getElementById(`${type}-id`).textContent,
college: document.getElementById(`${type}-college`).textContent,
department: document.getElementById(`${type}-department`).textContent
});
fetch(`https://mistpe-qr.hf.space/generate_qr/${encodeURIComponent(content)}`)
.then(response => response.blob())
.then(blob => {
const url = URL.createObjectURL(blob);
document.getElementById(`${type}-qr`).src = url;
});
}
function updateCard() {
const type = document.getElementById('card-type').value;
updateIfChanged(`${type}-title`, 'edit-title');
updateIfChanged(`${type}-title-en`, 'edit-title-en');
updateIfChanged(`${type}-name`, 'edit-name');
updateIfChanged(`${type}-college`, 'edit-college');
updateIfChanged(`${type}-id`, 'edit-id');
updateIfChanged(`${type}-department`, 'edit-department');
updateIfChanged(`${type}-school`, 'edit-school');
updateIfChanged(`${type}-school-en`, 'edit-school-en');
// 更新规则和页脚
const rulesElement = document.getElementById(`${type}-rules`);
const newRules = document.getElementById('edit-rules').value;
rulesElement.innerHTML = newRules.replace(/\n/g, '<br>');
const footerElement = document.getElementById(`${type}-footer`);
const newFooter = document.getElementById('edit-footer').value;
footerElement.innerHTML = newFooter.replace(/\n/g, '<br>');
// 更新Logo
updateImage(`${type}-logo`, 'edit-logo');
// 更新照片
updateImage(`${type}-photo`, 'edit-photo');
// 重新生成二维码
generateQRCode(type);
}
function updateIfChanged(targetId, sourceId) {
const targetElement = document.getElementById(targetId);
const newValue = document.getElementById(sourceId).value;
if (targetElement.textContent !== newValue) {
targetElement.textContent = newValue;
}
}
function updateImage(targetId, sourceId) {
const file = document.getElementById(sourceId).files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
const img = new Image();
img.onload = function() {
const targetElement = document.getElementById(targetId);
targetElement.style.backgroundImage = `url(${e.target.result})`;
targetElement.style.backgroundSize = 'cover';
targetElement.style.backgroundPosition = 'center';
}
img.src = e.target.result;
}
reader.readAsDataURL(file);
}
}
// 为所有输入字段添加事件监听器,实现自动更新
document.querySelectorAll('.edit-form input, .edit-form textarea').forEach(input => {
input.addEventListener('input', updateCard);
});
document.getElementById('card-type').addEventListener('change', updateCard);
function exportToImages() {
const type = document.getElementById('card-type').value;
const card = document.querySelector(`.id-card.${type}`);
const cardInner = card.querySelector('.id-card-inner');
const frontSide = card.querySelector('.id-card-front');
const backSide = card.querySelector('.id-card-back');
// 导出正面
html2canvas(frontSide, { scale: 2 }).then(canvas => {
saveAs(canvas.toDataURL(), `${type}_id_card_front.png`);
// 在捕获背面之前,移除翻转效果
cardInner.style.transform = 'rotateY(0deg)';
backSide.style.transform = 'rotateY(0deg)';
// 给DOM一点时间来更新
setTimeout(() => {
// 导出背面
html2canvas(backSide, { scale: 2 }).then(canvas => {
saveAs(canvas.toDataURL(), `${type}_id_card_back.png`);
// 恢复原有的翻转效果
cardInner.style.transform = '';
backSide.style.transform = '';
});
}, 100);
});
}
// 辅助函数:将数据URL保存为文件
function saveAs(uri, filename) {
var link = document.createElement('a');
if (typeof link.download === 'string') {
link.href = uri;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} else {
window.open(uri);
}
}
</script>
</body>
</html>