feat: 图形测试
This commit is contained in:
@@ -35,14 +35,68 @@ Page({
|
|||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
console.log('形状绘制页面加载完成');
|
console.log('形状绘制页面加载完成');
|
||||||
|
|
||||||
|
// 为可选形状生成SVG内容
|
||||||
|
const shapesWithSVG = this.data.availableShapes.map((shape) => ({
|
||||||
|
...shape,
|
||||||
|
svgContent: this.createSVGElement(shape, 'transparent', '#333', 50),
|
||||||
|
}));
|
||||||
|
|
||||||
// 初始化临时选择列表
|
// 初始化临时选择列表
|
||||||
this.setData({
|
this.setData({
|
||||||
|
availableShapes: shapesWithSVG,
|
||||||
tempSelectedShapeIds: this.data.selectedShapes.map(
|
tempSelectedShapeIds: this.data.selectedShapes.map(
|
||||||
(shape) => shape.id,
|
(shape) => shape.id,
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 生成带颜色的SVG字符串
|
||||||
|
generateColoredSVG(shape, fillColor = '#666', borderColor = '#333') {
|
||||||
|
if (!shape || !shape.svg) return '';
|
||||||
|
|
||||||
|
let svg = shape.svg;
|
||||||
|
|
||||||
|
// 替换stroke属性
|
||||||
|
svg = svg.replace(/stroke="[^"]*"/g, `stroke="${borderColor}"`);
|
||||||
|
|
||||||
|
// 处理fill属性
|
||||||
|
if (fillColor && fillColor !== 'transparent') {
|
||||||
|
svg = svg.replace(/fill="[^"]*"/g, `fill="${fillColor}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保stroke-width存在
|
||||||
|
if (!svg.includes('stroke-width')) {
|
||||||
|
svg = svg.replace(
|
||||||
|
/(<(?:circle|rect|polygon|ellipse|path|line)[^>]*?)>/g,
|
||||||
|
'$1 stroke-width="2">',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return svg;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 创建SVG的base64数据URL
|
||||||
|
createSVGElement(shape, fillColor, borderColor, size = 60) {
|
||||||
|
const coloredSVG = this.generateColoredSVG(
|
||||||
|
shape,
|
||||||
|
fillColor,
|
||||||
|
borderColor,
|
||||||
|
);
|
||||||
|
|
||||||
|
const svgContent = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="${size}" height="${size}">${coloredSVG}</svg>`;
|
||||||
|
|
||||||
|
// 转换为base64
|
||||||
|
const base64 = wx.arrayBufferToBase64(
|
||||||
|
new TextEncoder().encode(svgContent),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 可选:调试日志(发布时移除)
|
||||||
|
// console.log(`Creating SVG for ${shape.name}:`, { svgContent });
|
||||||
|
|
||||||
|
return `data:image/svg+xml;base64,${base64}`;
|
||||||
|
},
|
||||||
|
|
||||||
// 打开形状选择器
|
// 打开形状选择器
|
||||||
openShapeSelector() {
|
openShapeSelector() {
|
||||||
this.setData({
|
this.setData({
|
||||||
@@ -107,8 +161,17 @@ Page({
|
|||||||
(s) => s.shapeId === shapeId,
|
(s) => s.shapeId === shapeId,
|
||||||
);
|
);
|
||||||
if (existingShape) {
|
if (existingShape) {
|
||||||
// 保持原有颜色
|
// 保持原有颜色,更新SVG内容
|
||||||
newSelectedShapes.push(existingShape);
|
const updatedShape = {
|
||||||
|
...existingShape,
|
||||||
|
svgContent: this.createSVGElement(
|
||||||
|
shape,
|
||||||
|
existingShape.fillColor,
|
||||||
|
'#333',
|
||||||
|
60,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
newSelectedShapes.push(updatedShape);
|
||||||
const colorIndex = this.data.basic12Colors.findIndex(
|
const colorIndex = this.data.basic12Colors.findIndex(
|
||||||
(c) => c.hex === existingShape.fillColor,
|
(c) => c.hex === existingShape.fillColor,
|
||||||
);
|
);
|
||||||
@@ -119,14 +182,21 @@ Page({
|
|||||||
// 新形状,分配随机颜色
|
// 新形状,分配随机颜色
|
||||||
const randomColor =
|
const randomColor =
|
||||||
this.getRandomUnusedColor(usedColorIndexes);
|
this.getRandomUnusedColor(usedColorIndexes);
|
||||||
newSelectedShapes.push({
|
const newShape = {
|
||||||
id: Date.now() + index,
|
id: Date.now() + index,
|
||||||
shapeId: shape.id,
|
shapeId: shape.id,
|
||||||
name: shape.name,
|
name: shape.name,
|
||||||
fillColor: randomColor.hex,
|
fillColor: randomColor.hex,
|
||||||
colorName: randomColor.name,
|
colorName: randomColor.name,
|
||||||
drawFunction: shape.drawFunction,
|
drawFunction: shape.drawFunction,
|
||||||
});
|
svgContent: this.createSVGElement(
|
||||||
|
shape,
|
||||||
|
randomColor.hex,
|
||||||
|
'#333',
|
||||||
|
60,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
newSelectedShapes.push(newShape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -250,6 +320,10 @@ Page({
|
|||||||
|
|
||||||
if (currentEditingIndex >= 0) {
|
if (currentEditingIndex >= 0) {
|
||||||
const newSelectedShapes = [...selectedShapes];
|
const newSelectedShapes = [...selectedShapes];
|
||||||
|
const currentShape = newSelectedShapes[currentEditingIndex];
|
||||||
|
const shapeDefinition = this.data.availableShapes.find(
|
||||||
|
(s) => s.id === currentShape.shapeId,
|
||||||
|
);
|
||||||
const colorInfo = basic12Colors.find((c) => c.hex === color) ||
|
const colorInfo = basic12Colors.find((c) => c.hex === color) ||
|
||||||
WATER_COLORS.extended24.find((c) => c.hex === color) || {
|
WATER_COLORS.extended24.find((c) => c.hex === color) || {
|
||||||
name: '自定义色',
|
name: '自定义色',
|
||||||
@@ -257,9 +331,15 @@ Page({
|
|||||||
};
|
};
|
||||||
|
|
||||||
newSelectedShapes[currentEditingIndex] = {
|
newSelectedShapes[currentEditingIndex] = {
|
||||||
...newSelectedShapes[currentEditingIndex],
|
...currentShape,
|
||||||
fillColor: color,
|
fillColor: color,
|
||||||
colorName: colorInfo.name,
|
colorName: colorInfo.name,
|
||||||
|
svgContent: this.createSVGElement(
|
||||||
|
shapeDefinition,
|
||||||
|
color,
|
||||||
|
'#333',
|
||||||
|
60,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setData(
|
this.setData(
|
||||||
@@ -338,19 +418,29 @@ Page({
|
|||||||
this.drawPracticeArea(ctx, width, height);
|
this.drawPracticeArea(ctx, width, height);
|
||||||
|
|
||||||
// 导出图片
|
// 导出图片
|
||||||
const tempFilePath = canvas.toTempFilePathSync({
|
wx.canvasToTempFilePath({
|
||||||
|
canvas: canvas,
|
||||||
fileType: 'png',
|
fileType: 'png',
|
||||||
quality: 1,
|
quality: 1,
|
||||||
});
|
success: (res) => {
|
||||||
|
this.setData({
|
||||||
|
generatedImage: res.tempFilePath,
|
||||||
|
isGenerating: false,
|
||||||
|
});
|
||||||
|
|
||||||
this.setData({
|
wx.showToast({
|
||||||
generatedImage: tempFilePath,
|
title: '生成完成',
|
||||||
isGenerating: false,
|
icon: 'success',
|
||||||
});
|
});
|
||||||
|
},
|
||||||
wx.showToast({
|
fail: (error) => {
|
||||||
title: '生成完成',
|
console.error('导出图片失败:', error);
|
||||||
icon: 'success',
|
this.setData({ isGenerating: false });
|
||||||
|
wx.showToast({
|
||||||
|
title: '生成失败,请重试',
|
||||||
|
icon: 'none',
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('生成图片失败:', error);
|
console.error('生成图片失败:', error);
|
||||||
|
|||||||
@@ -271,502 +271,21 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shape-icon {
|
/* SVG 样式 */
|
||||||
|
.shape-svg {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shape-svg-small {
|
||||||
width: 50rpx;
|
width: 50rpx;
|
||||||
height: 50rpx;
|
height: 50rpx;
|
||||||
border: 2rpx solid #666;
|
display: block;
|
||||||
|
|
||||||
&.shape-icon-circle {
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--fill-color, transparent);
|
|
||||||
border-color: var(--border-color, #666);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.shape-icon-square {
|
|
||||||
border-radius: 5rpx;
|
|
||||||
background: var(--fill-color, transparent);
|
|
||||||
border-color: var(--border-color, #666);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.shape-icon-rectangle {
|
|
||||||
width: 60rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
border-radius: 5rpx;
|
|
||||||
background: var(--fill-color, transparent);
|
|
||||||
border-color: var(--border-color, #666);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.shape-icon-triangle {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border: none;
|
|
||||||
border-left: 25rpx solid transparent;
|
|
||||||
border-right: 25rpx solid transparent;
|
|
||||||
border-bottom: 45rpx solid var(--fill-color, red);
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.shape-icon-oval {
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 60rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
background: var(--fill-color, transparent);
|
|
||||||
border-color: var(--border-color, #666);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.shape-icon-diamond {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border: none;
|
|
||||||
border-left: 25rpx solid transparent;
|
|
||||||
border-right: 25rpx solid transparent;
|
|
||||||
border-top: 25rpx solid transparent;
|
|
||||||
border-bottom: 25rpx solid var(--fill-color, #666);
|
|
||||||
background: transparent;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 修正星形 */
|
|
||||||
&.shape-icon-star {
|
|
||||||
position: relative;
|
|
||||||
width: 80rpx;
|
|
||||||
height: 80rpx;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
--star-fill-color: var(--fill-color, red);
|
|
||||||
--star-border-color: var(--border-color, #333);
|
|
||||||
--star-border-width: 2rpx;
|
|
||||||
|
|
||||||
/* 边框层 */
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
width: 66rpx;
|
|
||||||
height: 66rpx;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
background: transparent;
|
|
||||||
border: var(--star-border-width, 2rpx) solid var(--star-border-color, #333);
|
|
||||||
clip-path: polygon(50% 0%,
|
|
||||||
61% 35%,
|
|
||||||
98% 35%,
|
|
||||||
68% 57%,
|
|
||||||
79% 91%,
|
|
||||||
50% 70%,
|
|
||||||
21% 91%,
|
|
||||||
32% 57%,
|
|
||||||
2% 35%,
|
|
||||||
39% 35%);
|
|
||||||
z-index: 1;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
background: var(--star-fill-color, red);
|
|
||||||
clip-path: polygon(50% 0%,
|
|
||||||
61% 35%,
|
|
||||||
98% 35%,
|
|
||||||
68% 57%,
|
|
||||||
79% 91%,
|
|
||||||
50% 70%,
|
|
||||||
21% 91%,
|
|
||||||
32% 57%,
|
|
||||||
2% 35%,
|
|
||||||
39% 35%);
|
|
||||||
z-index: 2;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 爱心形状 */
|
|
||||||
&.shape-icon-heart {
|
|
||||||
position: relative;
|
|
||||||
width: 44rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
/* 主体部分(三角形) */
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
bottom: 0;
|
|
||||||
transform: translateX(-50%) rotate(-45deg);
|
|
||||||
width: 32rpx;
|
|
||||||
height: 32rpx;
|
|
||||||
background: var(--fill-color, #f00);
|
|
||||||
border-left: 2rpx solid var(--border-color, #333);
|
|
||||||
border-bottom: 2rpx solid var(--border-color, #333);
|
|
||||||
border-bottom-left-radius: 20rpx;
|
|
||||||
border-bottom-right-radius: 20rpx;
|
|
||||||
z-index: 1;
|
|
||||||
clip-path: polygon(0 0, 100% 0, 50% 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 左半圆 */
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 4rpx;
|
|
||||||
top: 0;
|
|
||||||
width: 24rpx;
|
|
||||||
height: 24rpx;
|
|
||||||
background: var(--fill-color, #f00);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
border-bottom: none;
|
|
||||||
border-right: none;
|
|
||||||
border-radius: 50% 50% 0 0;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 右半圆 */
|
|
||||||
.heart-right {
|
|
||||||
position: absolute;
|
|
||||||
right: 4rpx;
|
|
||||||
top: 0;
|
|
||||||
width: 24rpx;
|
|
||||||
height: 24rpx;
|
|
||||||
background: var(--fill-color, #f00);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
border-bottom: none;
|
|
||||||
border-left: none;
|
|
||||||
border-radius: 50% 50% 0 0;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.shape-icon-hexagon {
|
|
||||||
width: 40rpx;
|
|
||||||
height: 22rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&::before,
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 20rpx solid transparent;
|
|
||||||
border-right: 20rpx solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
bottom: 100%;
|
|
||||||
border-bottom: 11rpx solid var(--fill-color, #666);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
top: 100%;
|
|
||||||
border-top: 11rpx solid var(--fill-color, #666);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 修正五边形 */
|
|
||||||
&.shape-icon-pentagon {
|
|
||||||
position: relative;
|
|
||||||
width: 40rpx;
|
|
||||||
height: 38rpx;
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 40rpx;
|
|
||||||
height: 38rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
clip-path: polygon(50% 0%,
|
|
||||||
100% 38%,
|
|
||||||
81% 100%,
|
|
||||||
19% 100%,
|
|
||||||
0% 38%);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 修正半圆 */
|
|
||||||
&.shape-icon-semicircle {
|
|
||||||
width: 50rpx;
|
|
||||||
height: 25rpx;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 50rpx;
|
|
||||||
height: 50rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
border-radius: 50%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 修正梯形 */
|
|
||||||
&.shape-icon-trapezoid {
|
|
||||||
width: 50rpx;
|
|
||||||
height: 30rpx;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
position: relative;
|
|
||||||
overflow: visible;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 50rpx;
|
|
||||||
height: 30rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
clip-path: polygon(15% 100%,
|
|
||||||
85% 100%,
|
|
||||||
100% 0%,
|
|
||||||
0% 0%);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// === 3D 形状样式 ===
|
|
||||||
|
|
||||||
/* 圆柱体 */
|
|
||||||
&.shape-icon-cylinder {
|
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
/* 顶部椭圆 */
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 50rpx;
|
|
||||||
height: 16rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
border-radius: 50%;
|
|
||||||
z-index: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 主体圆柱 */
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 8rpx;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 50rpx;
|
|
||||||
height: 44rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border-left: 2rpx solid var(--border-color, #333);
|
|
||||||
border-right: 2rpx solid var(--border-color, #333);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 底部椭圆 */
|
|
||||||
.cylinder-bottom {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 50rpx;
|
|
||||||
height: 16rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
border-radius: 50%;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 正方体 */
|
|
||||||
&.shape-icon-cube {
|
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
/* 正面 */
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
z-index: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 顶面 */
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
transform: skewX(-30deg) scaleY(0.6);
|
|
||||||
transform-origin: bottom left;
|
|
||||||
z-index: 2;
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 右面 */
|
|
||||||
.cube-right {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 20rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
border-left: none;
|
|
||||||
transform: skewY(-30deg);
|
|
||||||
transform-origin: bottom left;
|
|
||||||
z-index: 1;
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 球体 */
|
|
||||||
&.shape-icon-sphere {
|
|
||||||
width: 50rpx;
|
|
||||||
height: 50rpx;
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
/* 高光 */
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 12rpx;
|
|
||||||
left: 16rpx;
|
|
||||||
width: 12rpx;
|
|
||||||
height: 8rpx;
|
|
||||||
background: rgba(255, 255, 255, 0.6);
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 纬线 */
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
width: 46rpx;
|
|
||||||
height: 20rpx;
|
|
||||||
border: 1rpx solid var(--border-color, #333);
|
|
||||||
border-radius: 50%;
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 圆锥体 */
|
|
||||||
&.shape-icon-cone {
|
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
/* 圆锥主体 */
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 25rpx solid transparent;
|
|
||||||
border-right: 25rpx solid transparent;
|
|
||||||
border-bottom: 45rpx solid var(--fill-color, #666);
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 圆锥边框 */
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: -1rpx;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 26rpx solid transparent;
|
|
||||||
border-right: 26rpx solid transparent;
|
|
||||||
border-bottom: 46rpx solid var(--border-color, #333);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 底部椭圆 */
|
|
||||||
.cone-bottom {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
width: 50rpx;
|
|
||||||
height: 16rpx;
|
|
||||||
background: var(--fill-color, #666);
|
|
||||||
border: 2rpx solid var(--border-color, #333);
|
|
||||||
border-radius: 50%;
|
|
||||||
z-index: 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 保留基础样式,移除所有形状相关的CSS */
|
||||||
|
|
||||||
.shape-name {
|
.shape-name {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #666;
|
color: #666;
|
||||||
|
|||||||
@@ -37,32 +37,11 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- 形状预览 -->
|
<!-- 形状预览 -->
|
||||||
<view class="shape-preview-container">
|
<view class="shape-preview-container">
|
||||||
<canvas
|
<image
|
||||||
type="2d"
|
src="{{item.svgContent}}"
|
||||||
id="preview-canvas-{{index}}"
|
class="shape-svg"
|
||||||
class="shape-preview-canvas"
|
mode="aspectFit">
|
||||||
style="background-color: {{item.fillColor}};">
|
</image>
|
||||||
</canvas>
|
|
||||||
<view
|
|
||||||
class="shape-icon shape-icon-{{item.id}}"
|
|
||||||
style="--fill-color: {{item.fillColor}}; --border-color: #333333;">
|
|
||||||
<!-- 圆柱体底部 -->
|
|
||||||
<view
|
|
||||||
wx:if="{{item.id === 'cylinder'}}"
|
|
||||||
class="cylinder-bottom"></view>
|
|
||||||
<!-- 正方体右面 -->
|
|
||||||
<view
|
|
||||||
wx:if="{{item.id === 'cube'}}"
|
|
||||||
class="cube-right"></view>
|
|
||||||
<!-- 圆锥底部 -->
|
|
||||||
<view
|
|
||||||
wx:if="{{item.id === 'cone'}}"
|
|
||||||
class="cone-bottom"></view>
|
|
||||||
<!-- 爱心右半圆 -->
|
|
||||||
<view
|
|
||||||
wx:if="{{item.id === 'heart'}}"
|
|
||||||
class="heart-right"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<!-- 形状名称 -->
|
<!-- 形状名称 -->
|
||||||
<text class="shape-name">{{item.name}}</text>
|
<text class="shape-name">{{item.name}}</text>
|
||||||
@@ -158,24 +137,11 @@
|
|||||||
</view>
|
</view>
|
||||||
<!-- 形状预览 -->
|
<!-- 形状预览 -->
|
||||||
<view class="shape-preview-box">
|
<view class="shape-preview-box">
|
||||||
<view class="shape-icon shape-icon-{{item.id}}">
|
<image
|
||||||
<!-- 圆柱体底部 -->
|
src="{{item.svgContent}}"
|
||||||
<view
|
class="shape-svg-small"
|
||||||
wx:if="{{item.id === 'cylinder'}}"
|
mode="aspectFit">
|
||||||
class="cylinder-bottom"></view>
|
</image>
|
||||||
<!-- 正方体右面 -->
|
|
||||||
<view
|
|
||||||
wx:if="{{item.id === 'cube'}}"
|
|
||||||
class="cube-right"></view>
|
|
||||||
<!-- 圆锥底部 -->
|
|
||||||
<view
|
|
||||||
wx:if="{{item.id === 'cone'}}"
|
|
||||||
class="cone-bottom"></view>
|
|
||||||
<!-- 爱心右半圆 -->
|
|
||||||
<view
|
|
||||||
wx:if="{{item.id === 'heart'}}"
|
|
||||||
class="heart-right"></view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<text class="shape-name">{{item.name}}</text>
|
<text class="shape-name">{{item.name}}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
Reference in New Issue
Block a user