diff --git a/miniprogram/demoPages/shapePrint/index.js b/miniprogram/demoPages/shapePrint/index.js
index 69af751..8e56018 100644
--- a/miniprogram/demoPages/shapePrint/index.js
+++ b/miniprogram/demoPages/shapePrint/index.js
@@ -504,6 +504,18 @@ Page({
case 'drawTrapezoid':
this.drawTrapezoid(ctx, x, y, size, color, '#333', filled);
break;
+ case 'drawCylinder':
+ this.drawCylinder(ctx, x, y, size, color, '#333', filled);
+ break;
+ case 'drawCube':
+ this.drawCube(ctx, x, y, size, color, '#333', filled);
+ break;
+ case 'drawSphere':
+ this.drawSphere(ctx, x, y, size, color, '#333', filled);
+ break;
+ case 'drawCone':
+ this.drawCone(ctx, x, y, size, color, '#333', filled);
+ break;
}
},
@@ -762,6 +774,192 @@ Page({
ctx.restore();
},
+ // === 3D形状绘制函数 ===
+
+ // 绘制圆柱体
+ drawCylinder(ctx, x, y, size, fillColor, borderColor, filled = true) {
+ ctx.save();
+ const radius = size * 0.3;
+ const height = size * 0.6;
+
+ // 绘制主体
+ if (filled && fillColor !== 'transparent') {
+ ctx.fillStyle = fillColor;
+ ctx.fillRect(x - radius, y - height / 2, radius * 2, height);
+ }
+
+ // 绘制主体边框
+ ctx.strokeStyle = borderColor;
+ ctx.lineWidth = 3;
+ ctx.beginPath();
+ ctx.moveTo(x - radius, y - height / 2);
+ ctx.lineTo(x - radius, y + height / 2);
+ ctx.moveTo(x + radius, y - height / 2);
+ ctx.lineTo(x + radius, y + height / 2);
+ ctx.stroke();
+
+ // 绘制顶部椭圆
+ ctx.beginPath();
+ ctx.ellipse(x, y - height / 2, radius, radius * 0.3, 0, 0, Math.PI * 2);
+ if (filled && fillColor !== 'transparent') {
+ ctx.fillStyle = fillColor;
+ ctx.fill();
+ }
+ ctx.stroke();
+
+ // 绘制底部椭圆
+ ctx.beginPath();
+ ctx.ellipse(x, y + height / 2, radius, radius * 0.3, 0, 0, Math.PI * 2);
+ if (filled && fillColor !== 'transparent') {
+ ctx.fillStyle = fillColor;
+ ctx.fill();
+ }
+ ctx.stroke();
+
+ ctx.restore();
+ },
+
+ // 绘制正方体
+ drawCube(ctx, x, y, size, fillColor, borderColor, filled = true) {
+ ctx.save();
+ const cubeSize = size * 0.4;
+ const offset = cubeSize * 0.3; // 3D偏移量
+
+ // 绘制后面(右侧面)
+ if (filled && fillColor !== 'transparent') {
+ ctx.fillStyle = fillColor;
+ ctx.globalAlpha = 0.6; // 较暗
+ ctx.fillRect(
+ x - cubeSize / 2 + offset,
+ y - cubeSize / 2 - offset,
+ cubeSize,
+ cubeSize,
+ );
+ ctx.globalAlpha = 1;
+ }
+
+ ctx.strokeStyle = borderColor;
+ ctx.lineWidth = 2;
+ ctx.strokeRect(
+ x - cubeSize / 2 + offset,
+ y - cubeSize / 2 - offset,
+ cubeSize,
+ cubeSize,
+ );
+
+ // 绘制前面(正面)
+ if (filled && fillColor !== 'transparent') {
+ ctx.fillStyle = fillColor;
+ ctx.fillRect(
+ x - cubeSize / 2,
+ y - cubeSize / 2,
+ cubeSize,
+ cubeSize,
+ );
+ }
+
+ ctx.strokeRect(x - cubeSize / 2, y - cubeSize / 2, cubeSize, cubeSize);
+
+ // 绘制连接线
+ ctx.beginPath();
+ // 左上角连接线
+ ctx.moveTo(x - cubeSize / 2, y - cubeSize / 2);
+ ctx.lineTo(x - cubeSize / 2 + offset, y - cubeSize / 2 - offset);
+ // 右上角连接线
+ ctx.moveTo(x + cubeSize / 2, y - cubeSize / 2);
+ ctx.lineTo(x + cubeSize / 2 + offset, y - cubeSize / 2 - offset);
+ // 右下角连接线
+ ctx.moveTo(x + cubeSize / 2, y + cubeSize / 2);
+ ctx.lineTo(x + cubeSize / 2 + offset, y + cubeSize / 2 - offset);
+ ctx.stroke();
+
+ ctx.restore();
+ },
+
+ // 绘制球体
+ drawSphere(ctx, x, y, size, fillColor, borderColor, filled = true) {
+ ctx.save();
+ const radius = size * 0.4;
+
+ // 绘制主体圆形
+ ctx.beginPath();
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
+
+ if (filled && fillColor !== 'transparent') {
+ // 创建径向渐变模拟3D效果
+ const gradient = ctx.createRadialGradient(
+ x - radius * 0.3,
+ y - radius * 0.3,
+ 0,
+ x,
+ y,
+ radius,
+ );
+ gradient.addColorStop(0, '#ffffff');
+ gradient.addColorStop(0.3, fillColor);
+ gradient.addColorStop(1, '#000000');
+ ctx.fillStyle = gradient;
+ ctx.fill();
+ }
+
+ ctx.strokeStyle = borderColor;
+ ctx.lineWidth = 3;
+ ctx.stroke();
+
+ // 绘制纬线
+ ctx.strokeStyle = borderColor;
+ ctx.lineWidth = 1;
+ ctx.globalAlpha = 0.5;
+
+ // 水平纬线
+ ctx.beginPath();
+ ctx.ellipse(x, y, radius, radius * 0.3, 0, 0, Math.PI * 2);
+ ctx.stroke();
+
+ // 垂直经线
+ ctx.beginPath();
+ ctx.ellipse(x, y, radius * 0.3, radius, 0, 0, Math.PI * 2);
+ ctx.stroke();
+
+ ctx.restore();
+ },
+
+ // 绘制圆锥体
+ drawCone(ctx, x, y, size, fillColor, borderColor, filled = true) {
+ ctx.save();
+ const radius = size * 0.3;
+ const height = size * 0.6;
+
+ // 绘制圆锥主体
+ ctx.beginPath();
+ ctx.moveTo(x, y - height / 2); // 顶点
+ ctx.lineTo(x - radius, y + height / 2); // 左下
+ ctx.lineTo(x + radius, y + height / 2); // 右下
+ ctx.closePath();
+
+ if (filled && fillColor !== 'transparent') {
+ ctx.fillStyle = fillColor;
+ ctx.fill();
+ }
+
+ ctx.strokeStyle = borderColor;
+ ctx.lineWidth = 3;
+ ctx.stroke();
+
+ // 绘制底部椭圆
+ ctx.beginPath();
+ ctx.ellipse(x, y + height / 2, radius, radius * 0.3, 0, 0, Math.PI * 2);
+
+ if (filled && fillColor !== 'transparent') {
+ ctx.fillStyle = fillColor;
+ ctx.fill();
+ }
+
+ ctx.stroke();
+
+ ctx.restore();
+ },
+
// 保存到相册
saveToAlbum() {
if (!this.data.generatedImage) {
diff --git a/miniprogram/demoPages/shapePrint/index.less b/miniprogram/demoPages/shapePrint/index.less
index 03cb644..336d1b9 100644
--- a/miniprogram/demoPages/shapePrint/index.less
+++ b/miniprogram/demoPages/shapePrint/index.less
@@ -447,8 +447,6 @@
border-left: none;
border-radius: 50% 50% 0 0;
z-index: 2;
- content: '';
- display: block;
}
}
@@ -557,6 +555,216 @@
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;
+ }
+ }
}
.shape-name {
diff --git a/miniprogram/demoPages/shapePrint/index.wxml b/miniprogram/demoPages/shapePrint/index.wxml
index e0e25a4..1c95cf0 100644
--- a/miniprogram/demoPages/shapePrint/index.wxml
+++ b/miniprogram/demoPages/shapePrint/index.wxml
@@ -46,6 +46,22 @@
+
+
+
+
+
+
+
+
@@ -142,7 +158,24 @@
-
+
+
+
+
+
+
+
+
+
+
{{item.name}}
diff --git a/miniprogram/demoPages/shapePrint/shapes.js b/miniprogram/demoPages/shapePrint/shapes.js
index 90384ff..61316e0 100644
--- a/miniprogram/demoPages/shapePrint/shapes.js
+++ b/miniprogram/demoPages/shapePrint/shapes.js
@@ -84,6 +84,35 @@ const shapes = [
svg: '',
drawFunction: 'drawTrapezoid',
},
+ // 新增3D形状
+ {
+ id: 'cylinder',
+ name: '圆柱体',
+ type: '3d-cylinder',
+ svg: '',
+ drawFunction: 'drawCylinder',
+ },
+ {
+ id: 'cube',
+ name: '正方体',
+ type: '3d-cube',
+ svg: '',
+ drawFunction: 'drawCube',
+ },
+ {
+ id: 'sphere',
+ name: '球体',
+ type: '3d-sphere',
+ svg: '',
+ drawFunction: 'drawSphere',
+ },
+ {
+ id: 'cone',
+ name: '圆锥体',
+ type: '3d-cone',
+ svg: '',
+ drawFunction: 'drawCone',
+ },
];
// 颜色选项