|
|
|
|
@ -0,0 +1,164 @@
|
|
|
|
|
<template>
|
|
|
|
|
<base-container>
|
|
|
|
|
<canvas
|
|
|
|
|
id="canvas-container"
|
|
|
|
|
width="600"
|
|
|
|
|
height="600"
|
|
|
|
|
></canvas>
|
|
|
|
|
</base-container>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { onMounted } from 'vue';
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
startDraw();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const startDraw = function () {
|
|
|
|
|
const canvas = {
|
|
|
|
|
width: 600,
|
|
|
|
|
height: 600,
|
|
|
|
|
el: document.getElementById('canvas-container'),
|
|
|
|
|
};
|
|
|
|
|
const ctx = canvas.el.getContext('2d');
|
|
|
|
|
console.log(ctx);
|
|
|
|
|
|
|
|
|
|
const centerX = canvas.width / 2;
|
|
|
|
|
const centerY = canvas.height / 2;
|
|
|
|
|
|
|
|
|
|
// 画布背景颜色
|
|
|
|
|
function drawBackground() {
|
|
|
|
|
const radialGradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, 600);
|
|
|
|
|
radialGradient.addColorStop(0, 'rgba(248, 239, 229, 1)');
|
|
|
|
|
radialGradient.addColorStop(1, 'rgba(252, 201, 169, 1)');
|
|
|
|
|
|
|
|
|
|
ctx.fillStyle = radialGradient;
|
|
|
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 绘制带圆角的六边形
|
|
|
|
|
function drawHexagon(radius = 50, custom) {
|
|
|
|
|
const cornerRadius = 20; // 圆角半径(可调,控制弧度大小)
|
|
|
|
|
|
|
|
|
|
// 设置样式
|
|
|
|
|
ctx.fillStyle = 'rgba(255, 248, 244, 1)';
|
|
|
|
|
ctx.strokeStyle = 'rgba(253, 201, 171, 1)';
|
|
|
|
|
ctx.lineWidth = 3;
|
|
|
|
|
|
|
|
|
|
ctx.beginPath();
|
|
|
|
|
|
|
|
|
|
if (custom) {
|
|
|
|
|
// === custom 为 true 时 (最外层) ===
|
|
|
|
|
// 绘制虚线边框,且在每个角留出空隙给文字
|
|
|
|
|
const gap = 40; // 避让距离,根据文字大小调整
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < 6; i++) {
|
|
|
|
|
// 当前顶点 (起点)
|
|
|
|
|
const angle1 = (Math.PI / 3) * i + Math.PI / 2;
|
|
|
|
|
const x1 = centerX + radius * Math.cos(angle1);
|
|
|
|
|
const y1 = centerY + radius * Math.sin(angle1);
|
|
|
|
|
|
|
|
|
|
// 下一个顶点 (终点)
|
|
|
|
|
const angle2 = (Math.PI / 3) * (i + 1) + Math.PI / 2;
|
|
|
|
|
const x2 = centerX + radius * Math.cos(angle2);
|
|
|
|
|
const y2 = centerY + radius * Math.sin(angle2);
|
|
|
|
|
|
|
|
|
|
// 计算向量
|
|
|
|
|
const dx = x2 - x1;
|
|
|
|
|
const dy = y2 - y1;
|
|
|
|
|
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
|
|
|
|
|
|
|
|
// 只有当边长大于 2*gap 时才绘制,防止交叉
|
|
|
|
|
if (dist > 2 * gap) {
|
|
|
|
|
const ux = dx / dist;
|
|
|
|
|
const uy = dy / dist;
|
|
|
|
|
|
|
|
|
|
// 计算避让后的起点和终点
|
|
|
|
|
const sx = x1 + ux * gap;
|
|
|
|
|
const sy = y1 + uy * gap;
|
|
|
|
|
const ex = x2 - ux * gap;
|
|
|
|
|
const ey = y2 - uy * gap;
|
|
|
|
|
|
|
|
|
|
ctx.moveTo(sx, sy);
|
|
|
|
|
ctx.lineTo(ex, ey);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 绘制虚线
|
|
|
|
|
ctx.setLineDash([5, 8]);
|
|
|
|
|
ctx.lineDashOffset = 0;
|
|
|
|
|
ctx.stroke();
|
|
|
|
|
ctx.setLineDash([]); // 还原
|
|
|
|
|
} else {
|
|
|
|
|
// === 普通情况 (内部实心六边形) ===
|
|
|
|
|
// 从顶部开始,逆时针绘制
|
|
|
|
|
for (let i = 0; i < 6; i++) {
|
|
|
|
|
const startAngle = (Math.PI / 3) * i + Math.PI / 2; // 当前边的起始角度(从顶部开始)
|
|
|
|
|
|
|
|
|
|
const x1 = centerX + radius * Math.cos(startAngle);
|
|
|
|
|
const y1 = centerY + radius * Math.sin(startAngle);
|
|
|
|
|
|
|
|
|
|
const prevAngle = (Math.PI / 3) * (i - 1) + Math.PI / 2;
|
|
|
|
|
const prevX = centerX + radius * Math.cos(prevAngle);
|
|
|
|
|
const prevY = centerY + radius * Math.sin(prevAngle);
|
|
|
|
|
|
|
|
|
|
// 画圆弧:从 prevX,prevY 到 x1,y1,以 cornerX,cornerY 为中心
|
|
|
|
|
ctx.arcTo(prevX, prevY, x1, y1, cornerRadius);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 最后一段圆弧:连接最后一个点到第一个点
|
|
|
|
|
const lastAngle = (Math.PI / 3) * 5 + Math.PI / 2;
|
|
|
|
|
const firstAngle = (Math.PI / 3) * 0 + Math.PI / 2;
|
|
|
|
|
const lastX = centerX + radius * Math.cos(lastAngle);
|
|
|
|
|
const lastY = centerY + radius * Math.sin(lastAngle);
|
|
|
|
|
const firstX = centerX + radius * Math.cos(firstAngle);
|
|
|
|
|
const firstY = centerY + radius * Math.sin(firstAngle);
|
|
|
|
|
ctx.arcTo(lastX, lastY, firstX, firstY, cornerRadius - cornerRadius / 2);
|
|
|
|
|
|
|
|
|
|
ctx.fill();
|
|
|
|
|
ctx.stroke();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加文本到六边形的角上
|
|
|
|
|
function drawTextAtCorners(radius, textArray) {
|
|
|
|
|
// 文本内容数组,对应六边形的6个角
|
|
|
|
|
const text = textArray || ['医疗险', '定期寿险', '储蓄养老', '家财宠险', '重疾险', '意外险'];
|
|
|
|
|
const textColors = ['#333', '#333', '#333', '#333', '#333', '#333']; // 文本颜色
|
|
|
|
|
const textSizes = [20, 20, 20, 20, 20, 20]; // 文本大小
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < 6; i++) {
|
|
|
|
|
const angle = (Math.PI / 3) * i + Math.PI / 2; // 当前角的角度(从顶部开始)
|
|
|
|
|
const x = centerX + radius * Math.cos(angle);
|
|
|
|
|
const y = centerY + radius * Math.sin(angle);
|
|
|
|
|
|
|
|
|
|
// 设置文本样式
|
|
|
|
|
ctx.font = `bold ${textSizes[i]}px Arial`;
|
|
|
|
|
ctx.fillStyle = textColors[i];
|
|
|
|
|
ctx.textAlign = 'center';
|
|
|
|
|
ctx.textBaseline = 'middle';
|
|
|
|
|
|
|
|
|
|
// 绘制文本
|
|
|
|
|
ctx.fillText(text[i], x, y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drawBackground();
|
|
|
|
|
drawHexagon(200, true);
|
|
|
|
|
drawHexagon(150);
|
|
|
|
|
drawHexagon(100);
|
|
|
|
|
drawHexagon(50);
|
|
|
|
|
|
|
|
|
|
// 在最外层六边形的角上添加文本
|
|
|
|
|
drawTextAtCorners(200, ['医疗险', '定期寿险', '储蓄养老', '家财宠险', '重疾险', '意外险']);
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
#canvas-container {
|
|
|
|
|
width: 600px;
|
|
|
|
|
height: 600px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
}
|
|
|
|
|
</style>
|