6 Star 31 Fork 12

lanchny/Wetemp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
number-labels.html 39.78 KB
一键复制 编辑 原始数据 按行查看 历史
lanchny 提交于 2025-09-28 14:32 +08:00 . 微信公众号文章编辑工具
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>微信风格数字标号</title>
<link href="css/all.min.css" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #fff;
font-family: 'Inter', system-ui, sans-serif;
color: #1e293b;
line-height: 1.5;
}
.container {
margin: 0 auto;
display: flex;
gap: 2rem;
padding: 1rem;
}
.left-panel {
flex: 0 0 400px;
}
.right-panel {
flex: 1;
}
.control-panel {
background: white;
border-radius: 0.75rem;
padding: 1.5rem;
margin-bottom: 2rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.control-group {
margin-bottom: 1rem;
display: flex;
flex-wrap: wrap;
gap: 1rem;
align-items: center;
}
.control-label {
font-weight: 600;
min-width: 120px;
}
.control-options {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
flex: 1;
}
button, select, input[type="color"], input[type="number"], input[type="range"] {
padding: 0.5rem 1rem;
border-radius: 0.5rem;
border: 1px solid #d1d5db;
background: white;
cursor: pointer;
transition: all 0.2s;
}
button:hover, select:hover {
border-color: #9ca3af;
}
button.active {
background: #2D7FF9;
color: white;
border-color: #2D7FF9;
}
input[type="color"] {
width: 40px;
height: 40px;
padding: 0;
border: none;
}
input[type="number"] {
width: 80px;
}
.range-container {
display: flex;
align-items: center;
gap: 0.5rem;
width: 100%;
max-width: 200px;
}
input[type="range"] {
flex: 1;
}
.range-value {
min-width: 30px;
text-align: center;
}
.preview-section {
background: white;
border-radius: 0.75rem;
padding: 2rem;
margin-bottom: 2rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
text-align: center;
}
.preview-title {
font-weight: 600;
margin-bottom: 1.5rem;
font-size: 1.2rem;
}
.preview-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 200px;
background-color: #f3f4f6;
border-radius: 0.75rem;
margin-bottom: 1.5rem;
}
.preview-icon {
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
transition: all 0.3s ease;
}
.style-library {
margin-top: 3rem;
}
.library-title {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 1.5rem;
text-align: center;
}
.grid {
display: grid;
gap: 1.5rem;
}
@media (min-width: 640px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(5, 1fr);
}
}
@media (max-width: 1024px) {
.container {
flex-direction: column;
}
.left-panel {
flex: none;
width: 100%;
max-width: none;
}
}
.flex {
display: flex;
}
.flex-col {
flex-direction: column;
}
.items-center {
align-items: center;
}
.number-shadow {
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
.number-hover {
transition: all 0.3s ease;
}
.number-hover:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
.w-16 {
width: 4rem;
}
.h-16 {
height: 4rem;
}
.w-18 {
width: 4.5rem;
}
.h-18 {
height: 4.5rem;
}
.rounded-full {
border-radius: 9999px;
}
.rounded-lg {
border-radius: 0.5rem;
}
.rounded-none {
border-radius: 0;
}
.justify-center {
justify-content: center;
}
.text-2xl {
font-size: 1.5rem;
}
.font-bold {
font-weight: 700;
}
.cursor-pointer {
cursor: pointer;
}
.text-sm {
font-size: 0.875rem;
}
.text-gray-500 {
color: #64748b;
}
.mt-2 {
margin-top: 0.5rem;
}
.mb-6 {
margin-bottom: 1.5rem;
}
.bg-white {
background-color: white;
}
/* 微信风格配色 */
.blue-gradient-1 {
background-color: #1A5FDB;
color: #ffffff;
}
.blue-gradient-2 {
background-color: #2D7FF9;
color: #ffffff;
}
.blue-gradient-3 {
background-color: #5294FF;
color: #ffffff;
}
.shadow-stroke-1 {
border: 3px solid #1A5FDB;
color: #1A5FDB;
background-color: white;
}
.shadow-stroke-2 {
border: 3px solid #2D7FF9;
color: #2D7FF9;
background-color: white;
box-shadow: 0 4px 10px rgba(45, 127, 249, 0.2);
}
.shadow-stroke-3 {
border: 3px solid #5294FF;
color: #5294FF;
background-color: white;
box-shadow: 0 4px 10px rgba(82, 148, 255, 0.3);
}
.blend-gradient-1 {
background: linear-gradient(135deg, #1A5FDB 0%, #2D7FF9 100%);
color: #ffffff;
}
.blend-gradient-2 {
background: linear-gradient(135deg, #2D7FF9 0%, #5294FF 100%);
color: #ffffff;
}
.blend-stroke-1 {
border: 3px solid transparent;
background-image: linear-gradient(white, white),
linear-gradient(135deg, #1A5FDB, #2D7FF9);
background-origin: border-box;
background-clip: content-box, border-box;
color: #1A5FDB;
}
.blend-stroke-2 {
border: 3px solid transparent;
background-image: linear-gradient(white, white),
linear-gradient(135deg, #2D7FF9, #5294FF);
background-origin: border-box;
background-clip: content-box, border-box;
color: #2D7FF9;
box-shadow: 0 4px 10px rgba(45, 127, 249, 0.2);
}
.text-white {
color: #ffffff;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.border-2 {
border-width: 2px;
}
.border-3 {
border-width: 3px;
}
.border-dashed {
border-style: dashed;
}
.bg-primary\/10 {
background-color: rgba(45, 127, 249, 0.1);
}
.border-primary\/30 {
border-color: rgba(45, 127, 249, 0.3);
}
.shadow-inner {
box-shadow: inset 0 2px 4px 0 rgba(0, 0, 0, 0.1);
}
@keyframes bounce {
0%, 100% {
transform: translateY(-25%);
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
}
50% {
transform: translateY(0);
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
}
.animate-bounce-slow {
animation: bounce 3s infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.animate-spin {
animation: spin 1s linear infinite;
}
.notification {
position: fixed;
bottom: 20px;
right: 20px;
background: #0f172a;
color: white;
padding: 10px 20px;
border-radius: 5px;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
font-weight: 500;
}
.notification.show {
opacity: 1;
}
.action-buttons {
display: flex;
justify-content: center;
gap: 1rem;
margin-top: 2rem;
}
.action-buttons button {
padding: 0.75rem 1.5rem;
font-weight: 600;
}
</style>
</head>
<body class="bg-gray-50 font-sans text-dark">
<div class="container">
<div class="left-panel">
<div class="control-panel">
<div class="control-group">
<div class="control-label">数字内容:</div>
<div class="control-options">
<input type="number" id="numberValue" value="1" min="0" max="999">
<button id="randomNumber">随机数字</button>
</div>
</div>
<div class="control-group">
<div class="control-label">图标形状:</div>
<div class="control-options">
<button class="shape-btn active" data-shape="rounded-full">圆形</button>
<button class="shape-btn" data-shape="rounded-lg">圆角方形</button>
<button class="shape-btn" data-shape="rounded-none">方形</button>
<button class="shape-btn" data-shape="organic">自然形状</button>
</div>
</div>
<div class="control-group">
<div class="control-label">图标大小:</div>
<div class="control-options">
<div class="range-container">
<input type="range" id="iconSize" min="40" max="200" value="64">
<span class="range-value" id="sizeValue">64px</span>
</div>
</div>
</div>
<div class="control-group">
<div class="control-label">背景样式:</div>
<div class="control-options">
<button class="style-btn active" data-style="solid">纯色填充</button>
<button class="style-btn" data-style="gradient">渐变填充</button>
<button class="style-btn" data-style="stroke">描边样式</button>
<button class="style-btn" data-style="blend">混合样式</button>
</div>
</div>
<div class="control-group">
<div class="control-label">背景颜色:</div>
<div class="control-options">
<input type="color" id="bgColorPicker" value="#2D7FF9">
<input type="color" id="bgColorPicker2" value="#1A5FDB" style="display:none;">
<button id="randomBgColor">随机颜色</button>
</div>
</div>
<div class="control-group">
<div class="control-label">文字颜色:</div>
<div class="control-options">
<input type="color" id="textColorPicker" value="#ffffff">
<button id="autoContrast" class="active">自动对比度</button>
<button id="randomTextColor">随机颜色</button>
</div>
</div>
<div class="control-group">
<div class="control-label">边框样式:</div>
<div class="control-options">
<button class="border-btn active" data-border="none">无边框</button>
<button class="border-btn" data-border="solid">实线</button>
<button class="border-btn" data-border="dashed">虚线</button>
</div>
</div>
<div class="control-group">
<div class="control-label">边框宽度:</div>
<div class="control-options">
<div class="range-container">
<input type="range" id="borderWidth" min="0" max="10" value="2">
<span class="range-value" id="borderWidthValue">2px</span>
</div>
</div>
</div>
<div class="control-group">
<div class="control-label">边框颜色:</div>
<div class="control-options">
<input type="color" id="borderColorPicker" value="#1A5FDB">
</div>
</div>
<div class="control-group">
<div class="control-label">阴影效果:</div>
<div class="control-options">
<button class="shadow-btn active" data-shadow="none">无阴影</button>
<button class="shadow-btn" data-shadow="outer">外阴影</button>
<button class="shadow-btn" data-shadow="inner">内阴影</button>
</div>
</div>
<div class="control-group">
<div class="control-label">动画效果:</div>
<div class="control-options">
<button class="animation-btn active" data-animation="none">无动画</button>
<button class="animation-btn" data-animation="bounce">弹跳</button>
<button class="animation-btn" data-animation="spin">旋转</button>
</div>
</div>
</div>
</div>
<div class="right-panel">
<div class="preview-section">
<div class="preview-title">实时预览</div>
<div class="preview-container">
<div id="previewIcon" class="preview-icon blue-gradient-2 rounded-full w-16 h-16 text-2xl font-bold">
<span id="previewNumber">1</span>
</div>
</div>
<div class="action-buttons">
<button id="resetAll">重置所有</button>
<button id="exportImage" class="active">导出图片</button>
</div>
</div>
<div class="style-library">
<div class="library-title">微信风格样式库</div>
<div class="grid">
<div class="flex flex-col items-center">
<div class="number-shadow number-hover blue-gradient-1 w-16 h-16 rounded-full flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="blue-gradient-1" data-shape="rounded-full">1</div>
<span class="text-sm text-gray-500 mt-2">微信蓝1</span>
</div>
<div class="flex flex-col items-center">
<div class="number-shadow number-hover blue-gradient-2 w-16 h-16 rounded-full flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="blue-gradient-2" data-shape="rounded-full">2</div>
<span class="text-sm text-gray-500 mt-2">微信蓝2</span>
</div>
<div class="flex flex-col items-center">
<div class="number-shadow number-hover blue-gradient-3 w-16 h-16 rounded-full flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="blue-gradient-3" data-shape="rounded-full">3</div>
<span class="text-sm text-gray-500 mt-2">微信蓝3</span>
</div>
<div class="flex flex-col items-center">
<div class="number-shadow number-hover shadow-stroke-1 w-16 h-16 rounded-full flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="shadow-stroke-1" data-shape="rounded-full">4</div>
<span class="text-sm text-gray-500 mt-2">描边样式1</span>
</div>
<div class="flex flex-col items-center">
<div class="number-shadow number-hover shadow-stroke-2 w-16 h-16 rounded-full flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="shadow-stroke-2" data-shape="rounded-full">5</div>
<span class="text-sm text-gray-500 mt-2">描边样式2</span>
</div>
<div class="flex flex-col items-center">
<div class="number-shadow number-hover shadow-stroke-3 w-16 h-16 rounded-full flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="shadow-stroke-3" data-shape="rounded-full">6</div>
<span class="text-sm text-gray-500 mt-2">描边样式3</span>
</div>
<div class="flex flex-col items-center">
<div class="number-shadow number-hover blend-gradient-1 w-16 h-16 rounded-lg flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="blend-gradient-1" data-shape="rounded-lg">7</div>
<span class="text-sm text-gray-500 mt-2">渐变样式1</span>
</div>
<div class="flex flex-col items-center">
<div class="number-shadow number-hover blend-gradient-2 w-16 h-16 rounded-lg flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="blend-gradient-2" data-shape="rounded-lg">8</div>
<span class="text-sm text-gray-500 mt-2">渐变样式2</span>
</div>
<div class="flex flex-col items-center">
<div class="number-shadow number-hover blend-stroke-1 w-16 h-16 rounded-lg flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="blend-stroke-1" data-shape="rounded-lg">9</div>
<span class="text-sm text-gray-500 mt-2">混合样式1</span>
</div>
<div class="flex flex-col items-center">
<div class="number-shadow number-hover blend-stroke-2 w-16 h-16 rounded-lg flex items-center justify-center text-2xl font-bold cursor-pointer library-item" data-style="blend-stroke-2" data-shape="rounded-lg">10</div>
<span class="text-sm text-gray-500 mt-2">混合样式2</span>
</div>
</div>
</div>
</div>
</div>
<div class="notification" id="notification"></div>
<canvas id="canvas" style="display: none;"></canvas>
<script>
const previewIcon = document.getElementById('previewIcon');
const previewNumber = document.getElementById('previewNumber');
const numberValue = document.getElementById('numberValue');
const randomNumber = document.getElementById('randomNumber');
const iconSize = document.getElementById('iconSize');
const sizeValue = document.getElementById('sizeValue');
const bgColorPicker = document.getElementById('bgColorPicker');
const bgColorPicker2 = document.getElementById('bgColorPicker2');
const randomBgColor = document.getElementById('randomBgColor');
const textColorPicker = document.getElementById('textColorPicker');
const autoContrast = document.getElementById('autoContrast');
const randomTextColor = document.getElementById('randomTextColor');
const borderWidth = document.getElementById('borderWidth');
const borderWidthValue = document.getElementById('borderWidthValue');
const borderColorPicker = document.getElementById('borderColorPicker');
const resetAll = document.getElementById('resetAll');
const exportImage = document.getElementById('exportImage');
const notification = document.getElementById('notification');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const libraryItems = document.querySelectorAll('.library-item');
const shapeButtons = document.querySelectorAll('.shape-btn');
const styleButtons = document.querySelectorAll('.style-btn');
const borderButtons = document.querySelectorAll('.border-btn');
const shadowButtons = document.querySelectorAll('.shadow-btn');
const animationButtons = document.querySelectorAll('.animation-btn');
let currentShape = 'rounded-full';
let currentStyle = 'solid';
let currentBorder = 'none';
let currentShadow = 'none';
let currentAnimation = 'none';
let useAutoContrast = true;
let originalClasses = previewIcon.className;
numberValue.addEventListener('input', () => {
previewNumber.textContent = numberValue.value;
});
randomNumber.addEventListener('click', () => {
const random = Math.floor(Math.random() * 100);
numberValue.value = random;
previewNumber.textContent = random;
});
iconSize.addEventListener('input', () => {
const size = iconSize.value;
sizeValue.textContent = `${size}px`;
previewIcon.style.width = `${size}px`;
previewIcon.style.height = `${size}px`;
previewIcon.style.fontSize = `${size * 0.6}px`;
});
shapeButtons.forEach(button => {
button.addEventListener('click', () => {
shapeButtons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
previewIcon.classList.remove(currentShape);
currentShape = button.getAttribute('data-shape');
if (currentShape === 'organic') {
previewIcon.classList.add('rounded-none');
previewIcon.style.borderRadius = '20% 80% 30% 70% / 70% 30% 80% 20%';
} else {
previewIcon.style.borderRadius = '';
previewIcon.classList.add(currentShape);
}
});
});
styleButtons.forEach(button => {
button.addEventListener('click', () => {
styleButtons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
resetStyleClasses();
currentStyle = button.getAttribute('data-style');
switch(currentStyle) {
case 'solid':
previewIcon.style.backgroundColor = bgColorPicker.value;
bgColorPicker2.style.display = 'none';
break;
case 'gradient':
previewIcon.style.background = `linear-gradient(135deg, ${bgColorPicker.value}, ${bgColorPicker2.value})`;
bgColorPicker2.style.display = 'inline-block';
break;
case 'stroke':
previewIcon.style.backgroundColor = 'transparent';
previewIcon.style.border = `3px solid ${bgColorPicker.value}`;
previewIcon.style.color = bgColorPicker.value;
bgColorPicker2.style.display = 'none';
break;
case 'blend':
previewIcon.style.backgroundColor = 'transparent';
previewIcon.style.border = '3px solid transparent';
previewIcon.style.backgroundImage = `linear-gradient(white, white), linear-gradient(135deg, ${bgColorPicker.value}, ${bgColorPicker2.value})`;
previewIcon.style.backgroundOrigin = 'border-box';
previewIcon.style.backgroundClip = 'content-box, border-box';
previewIcon.style.color = bgColorPicker.value;
bgColorPicker2.style.display = 'inline-block';
break;
}
if (useAutoContrast) {
updateTextColorBasedOnBackground();
}
});
});
bgColorPicker.addEventListener('input', () => {
updateBackgroundStyle();
if (useAutoContrast) {
updateTextColorBasedOnBackground();
}
});
bgColorPicker2.addEventListener('input', () => {
updateBackgroundStyle();
if (useAutoContrast) {
updateTextColorBasedOnBackground();
}
});
randomBgColor.addEventListener('click', () => {
const randomColor1 = getRandomColor();
const randomColor2 = getRandomColor();
bgColorPicker.value = randomColor1;
bgColorPicker2.value = randomColor2;
updateBackgroundStyle();
if (useAutoContrast) {
updateTextColorBasedOnBackground();
}
});
textColorPicker.addEventListener('input', () => {
previewIcon.style.color = textColorPicker.value;
});
autoContrast.addEventListener('click', () => {
useAutoContrast = !useAutoContrast;
autoContrast.classList.toggle('active', useAutoContrast);
if (useAutoContrast) {
updateTextColorBasedOnBackground();
}
});
randomTextColor.addEventListener('click', () => {
textColorPicker.value = getRandomColor();
previewIcon.style.color = textColorPicker.value;
useAutoContrast = false;
autoContrast.classList.remove('active');
});
borderButtons.forEach(button => {
button.addEventListener('click', () => {
borderButtons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
currentBorder = button.getAttribute('data-border');
updateBorderStyle();
});
});
borderWidth.addEventListener('input', () => {
const width = borderWidth.value;
borderWidthValue.textContent = `${width}px`;
updateBorderStyle();
});
borderColorPicker.addEventListener('input', () => {
updateBorderStyle();
});
shadowButtons.forEach(button => {
button.addEventListener('click', () => {
shadowButtons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
currentShadow = button.getAttribute('data-shadow');
updateShadowStyle();
});
});
animationButtons.forEach(button => {
button.addEventListener('click', () => {
animationButtons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
previewIcon.classList.remove('animate-bounce-slow', 'animate-spin');
currentAnimation = button.getAttribute('data-animation');
if (currentAnimation === 'bounce') {
previewIcon.classList.add('animate-bounce-slow');
} else if (currentAnimation === 'spin') {
previewIcon.classList.add('animate-spin');
}
});
});
resetAll.addEventListener('click', () => {
numberValue.value = '1';
previewNumber.textContent = '1';
iconSize.value = '64';
sizeValue.textContent = '64px';
previewIcon.style.width = '64px';
previewIcon.style.height = '64px';
previewIcon.style.fontSize = '38.4px';
resetButtons(shapeButtons, 'rounded-full');
resetButtons(styleButtons, 'solid');
resetButtons(borderButtons, 'none');
resetButtons(shadowButtons, 'none');
resetButtons(animationButtons, 'none');
currentShape = 'rounded-full';
currentStyle = 'solid';
currentBorder = 'none';
currentShadow = 'none';
currentAnimation = 'none';
bgColorPicker.value = '#2D7FF9';
bgColorPicker2.value = '#1A5FDB';
bgColorPicker2.style.display = 'none';
textColorPicker.value = '#ffffff';
useAutoContrast = true;
autoContrast.classList.add('active');
borderWidth.value = '2';
borderWidthValue.textContent = '2px';
borderColorPicker.value = '#1A5FDB';
resetStyleClasses();
previewIcon.className = originalClasses;
previewIcon.style.borderRadius = '';
previewIcon.classList.add(currentShape);
updateBackgroundStyle();
updateBorderStyle();
updateShadowStyle();
showNotification('已重置所有设置');
});
exportImage.addEventListener('click', () => {
exportAsPNG();
});
libraryItems.forEach(item => {
item.addEventListener('click', () => {
const style = item.getAttribute('data-style');
const shape = item.getAttribute('data-shape');
resetButtons(styleButtons, getStyleCategory(style));
resetButtons(shapeButtons, shape);
currentStyle = getStyleCategory(style);
currentShape = shape;
resetStyleClasses();
previewIcon.classList.add(style, shape);
if (shape === 'organic') {
previewIcon.style.borderRadius = '20% 80% 30% 70% / 70% 30% 80% 20%';
} else {
previewIcon.style.borderRadius = '';
}
numberValue.value = item.textContent;
previewNumber.textContent = item.textContent;
updateColorPickersFromStyle(style);
if (useAutoContrast) {
updateTextColorBasedOnBackground();
}
showNotification('已应用样式');
});
});
function resetButtons(buttons, activeValue) {
buttons.forEach(btn => {
if (btn.getAttribute('data-shape') === activeValue ||
btn.getAttribute('data-style') === activeValue ||
btn.getAttribute('data-border') === activeValue ||
btn.getAttribute('data-shadow') === activeValue ||
btn.getAttribute('data-animation') === activeValue) {
btn.classList.add('active');
} else {
btn.classList.remove('active');
}
});
}
function resetStyleClasses() {
const classesToRemove = [
'blue-gradient-1', 'blue-gradient-2', 'blue-gradient-3',
'shadow-stroke-1', 'shadow-stroke-2', 'shadow-stroke-3',
'blend-gradient-1', 'blend-gradient-2',
'blend-stroke-1', 'blend-stroke-2',
'animate-bounce-slow', 'animate-spin'
];
classesToRemove.forEach(className => {
previewIcon.classList.remove(className);
});
previewIcon.style.background = '';
previewIcon.style.backgroundColor = '';
previewIcon.style.backgroundImage = '';
previewIcon.style.backgroundOrigin = '';
previewIcon.style.backgroundClip = '';
previewIcon.style.border = '';
previewIcon.style.color = '';
}
function updateBackgroundStyle() {
switch(currentStyle) {
case 'solid':
previewIcon.style.backgroundColor = bgColorPicker.value;
break;
case 'gradient':
previewIcon.style.background = `linear-gradient(135deg, ${bgColorPicker.value}, ${bgColorPicker2.value})`;
break;
case 'stroke':
previewIcon.style.border = `3px solid ${bgColorPicker.value}`;
previewIcon.style.color = bgColorPicker.value;
break;
case 'blend':
previewIcon.style.backgroundImage = `linear-gradient(white, white), linear-gradient(135deg, ${bgColorPicker.value}, ${bgColorPicker2.value})`;
previewIcon.style.color = bgColorPicker.value;
break;
}
}
function updateBorderStyle() {
if (currentBorder === 'none') {
previewIcon.style.borderWidth = '0';
previewIcon.style.borderStyle = 'none';
} else {
previewIcon.style.borderWidth = `${borderWidth.value}px`;
previewIcon.style.borderStyle = currentBorder;
previewIcon.style.borderColor = borderColorPicker.value;
}
}
function updateShadowStyle() {
if (currentShadow === 'none') {
previewIcon.style.boxShadow = 'none';
} else if (currentShadow === 'outer') {
previewIcon.style.boxShadow = '0 4px 15px rgba(0, 0, 0, 0.2)';
} else if (currentShadow === 'inner') {
previewIcon.style.boxShadow = 'inset 0 2px 8px rgba(0, 0, 0, 0.2)';
}
}
function updateTextColorBasedOnBackground() {
const bgColor = getComputedStyle(previewIcon).backgroundColor;
const isDark = isColorDark(bgColor);
const textColor = isDark ? '#ffffff' : '#000000';
previewIcon.style.color = textColor;
textColorPicker.value = textColor;
}
function isColorDark(color) {
let r, g, b;
if (color.startsWith('rgb')) {
const rgb = color.match(/\d+/g);
r = parseInt(rgb[0]);
g = parseInt(rgb[1]);
b = parseInt(rgb[2]);
} else if (color.startsWith('#')) {
const hex = color.slice(1);
r = parseInt(hex.substring(0, 2), 16);
g = parseInt(hex.substring(2, 4), 16);
b = parseInt(hex.substring(4, 6), 16);
}
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
return luminance < 0.5;
}
function getRandomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
function exportAsPNG() {
const rect = previewIcon.getBoundingClientRect();
canvas.width = rect.width * 2;
canvas.height = rect.height * 2;
ctx.scale(2, 2);
html2canvas(previewIcon).then(canvas => {
const link = document.createElement('a');
link.download = `wechat-number-icon-${Date.now()}.png`;
link.href = canvas.toDataURL('image/png');
link.click();
showNotification('PNG图片已导出');
}).catch(err => {
console.error('导出失败:', err);
showNotification('导出失败,请重试');
});
}
function showNotification(message) {
notification.textContent = message;
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
}, 2000);
}
function getStyleCategory(style) {
if (style.includes('blue-gradient')) return 'solid';
if (style.includes('shadow-stroke')) return 'stroke';
if (style.includes('blend-gradient')) return 'gradient';
if (style.includes('blend-stroke')) return 'blend';
return 'solid';
}
function updateColorPickersFromStyle(style) {
const styleMap = {
'blue-gradient-1': { bg: '#1A5FDB', text: '#ffffff' },
'blue-gradient-2': { bg: '#2D7FF9', text: '#ffffff' },
'blue-gradient-3': { bg: '#5294FF', text: '#ffffff' },
'shadow-stroke-1': { bg: '#ffffff', text: '#1A5FDB', border: '#1A5FDB' },
'shadow-stroke-2': { bg: '#ffffff', text: '#2D7FF9', border: '#2D7FF9' },
'shadow-stroke-3': { bg: '#ffffff', text: '#5294FF', border: '#5294FF' },
'blend-gradient-1': { bg: '#1A5FDB', bg2: '#2D7FF9', text: '#ffffff' },
'blend-gradient-2': { bg: '#2D7FF9', bg2: '#5294FF', text: '#ffffff' },
'blend-stroke-1': { bg: '#1A5FDB', bg2: '#2D7FF9', text: '#1A5FDB' },
'blend-stroke-2': { bg: '#2D7FF9', bg2: '#5294FF', text: '#2D7FF9' }
};
if (styleMap[style]) {
bgColorPicker.value = styleMap[style].bg;
if (styleMap[style].bg2) {
bgColorPicker2.value = styleMap[style].bg2;
}
textColorPicker.value = styleMap[style].text;
if (styleMap[style].border) {
borderColorPicker.value = styleMap[style].border;
}
}
}
</script>
<script src="js/html2canvas.min.js"></script>
</body>
</html>
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
HTML
1
https://gitee.com/lanchny/Wetemp.git
git@gitee.com:lanchny/Wetemp.git
lanchny
Wetemp
Wetemp
master

搜索帮助