vue+微信小程序 五角星

在这里插入图片描述
说明:这个是先画出一个72度菱形,长中长线和短中长线按照一定比例,然后把菱形分层十份,最后再把菱形进行旋转形成五角星,最后显示标签,因为一直对不上所以对标签做了点操作

<template><view class="container"><canvas canvas-id="diamondCanvas" class="canvas":style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas></view>
</template><script lang="ts">
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';interface DiamondItem {name: string;value: number;
}@Component
export default class DiamondCanvas extends Vue {private canvasWidth: number = 350;private canvasHeight: number = 350;private scale: number = 40;private longAxis: number = 3;private shortAxis: number = 1.5;private distance: number = 1;private colors: string[] = ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF','#FF9F40', '#8AC249', '#EA5F89', '#0D98BA', '#D27D46'];// 新增:定义橙红色边框颜色private borderColor: string = '#FF6B35'; // 橙红色private borderWidth: number = 3; // 线条粗细(默认3px,可按需调整)@Prop({type: Array,default: () => [{ name: '指标1', value: 5 },{ name: '指标2', value: 7 },{ name: '指标3', value: 6 },{ name: '指标4', value: 8 },{ name: '指标5', value: 4 }],validator: (items: DiamondItem[]) =>items.length === 5 && items.every(item =>item.value >= 0 && item.value <= 10 && Number.isInteger(item.value))}) readonly diamondData!: DiamondItem[];mounted() {this.drawDiamondsWithLabels();}@Watch('diamondData', { deep: true })onDiamondDataChange() {this.drawDiamondsWithLabels();}private drawDiamondsWithLabels() {const ctx = wx.createCanvasContext('diamondCanvas', this);ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);const centerX = this.canvasWidth / 2;const centerY = this.canvasHeight / 2;const pivotY = (this.longAxis / 2) * this.scale;const labelRadius = this.scale * 3.2;const initialRotation = -36 * Math.PI / 180;const angleInterval = 72 * Math.PI / 180;for (let i = 0; i < 5; i++) {const diamondAngle = initialRotation + (i * angleInterval);ctx.save();ctx.translate(centerX, centerY);ctx.rotate(diamondAngle);ctx.translate(0, pivotY);this.drawSingleDiamond(ctx, this.diamondData[i].value, this.colors[i]);ctx.restore();const prevIndex = (i - 1 + 5) % 5;const labelAngle = initialRotation + (prevIndex * angleInterval) + Math.PI;ctx.save();ctx.translate(centerX, centerY);const labelX = Math.cos(labelAngle) * labelRadius;const labelY = Math.sin(labelAngle) * labelRadius;ctx.setFontSize(12);ctx.setFillStyle('#333333');ctx.setTextAlign('center');ctx.setTextBaseline('middle');ctx.fillText(this.diamondData[i].name, labelX, labelY - 10);ctx.setFontSize(14);ctx.setFillStyle(this.colors[i]);ctx.fillText(this.diamondData[i].value.toString(), labelX, labelY + 10);ctx.restore();}ctx.draw();}private drawSingleDiamond(ctx: any, value: number, color: string) {const top = { x: 0, y: this.longAxis / 2 };const bottom = { x: 0, y: -this.longAxis / 2 };const right = { x: this.shortAxis / 2, y: top.y - this.distance };const left = { x: -this.shortAxis / 2, y: top.y - this.distance };// 绘制边框 - 使用橙红色ctx.beginPath();ctx.moveTo(top.x * this.scale, -top.y * this.scale);ctx.lineTo(right.x * this.scale, -right.y * this.scale);ctx.lineTo(bottom.x * this.scale, -bottom.y * this.scale);ctx.lineTo(left.x * this.scale, -left.y * this.scale);ctx.closePath();ctx.setStrokeStyle(this.borderColor); // 关键修改:使用橙红色边框ctx.setLineWidth(this.borderWidth); // 关键:设置线条粗细ctx.stroke();// 分段计算(保持不变)const h1 = top.y - right.y;const h2 = right.y - bottom.y;const totalSegments = 10;const ratio = h1 / (h1 + h2);const n1 = Math.max(1, Math.round(totalSegments * ratio));const n2 = totalSegments - n1;const segmentH1 = h1 / n1;const segmentH2 = h2 / n2;// 上半部分绘制(修正边缘衔接)for (let i = 0; i < n1; i++) {// 关键修正:让当前段的y2与下一段的y1完全一致(避免缝隙)const y1 = top.y - i * segmentH1;const y2 = top.y - (i + 1) * segmentH1; // 精确计算,无偏差const width1 = this.shortAxis * ((top.y - y1) / h1);const width2 = this.shortAxis * ((top.y - y2) / h1);const segmentColor = i < value ? color : '#FFFFFF';// 绘制时增加0.5px偏移,抵消抗锯齿导致的白边this.drawDiamondSegment(ctx, y1, y2, width1, width2, segmentColor);}// 下半部分绘制(修正边缘衔接)for (let i = 0; i < n2; i++) {// 关键修正:让当前段的y2与下一段的y1完全一致const y1 = right.y - i * segmentH2;const y2 = right.y - (i + 1) * segmentH2; // 精确计算,无偏差const width1 = this.shortAxis * ((y1 - bottom.y) / h2);const width2 = this.shortAxis * ((y2 - bottom.y) / h2);const segmentColor = (n1 + i) < value ? color : '#FFFFFF';// 绘制时增加0.5px偏移,抵消抗锯齿导致的白边this.drawDiamondSegment(ctx, y1, y2, width1, width2, segmentColor);}}// 绘制单个颜色块(增加偏移抵消白边)private drawDiamondSegment(ctx: any, y1: number, y2: number, width1: number, width2: number, color: string) {ctx.beginPath();// 关键修正:y坐标增加0.5px偏移,避免Canvas抗锯齿产生的白边const offset = 0.5;ctx.moveTo(-width1 / 2 * this.scale, -y1 * this.scale + offset);ctx.lineTo(width1 / 2 * this.scale, -y1 * this.scale + offset);ctx.lineTo(width2 / 2 * this.scale, -y2 * this.scale + offset);ctx.lineTo(-width2 / 2 * this.scale, -y2 * this.scale + offset);ctx.closePath();ctx.setFillStyle(color);ctx.fill();// 确保没有隐藏的线条绘制(如果有stroke()会导致边缘线,这里保持注释)// ctx.stroke(); // 彻底移除线条绘制,避免产生边界线}
}
</script><style scoped>
.container {display: flex;justify-content: center;align-items: center;width: 100%;height: 100vh;
}.canvas {border: 1px solid #eee;background-color: #f9f9f9;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93332.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93332.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Prometheus + Grafana 深度玩法:从零到智能化监控体系

0. 写在前面&#xff1a;为什么你需要“神器”而非“常用命令老杨折腾监控系统可是有年头了&#xff0c;最早还用过 Cacti、Zabbix&#xff0c;那会儿做个仪表盘都得像雕花一样慢慢刻。后来 Prometheus 出来之后&#xff0c;我的第一反应是&#xff1a;这玩意儿的时间序列和标签…

YOLO、DarkNet和深度学习如何让自动驾驶看得清?

【导读】 本文提出 DarkNet-YOLO 工业级实践框架&#xff0c;通过引入 残差优化结构 与 多尺度特征融合技术&#xff0c;在保持实时检测精度同时显著提升复杂场景适应性。 目录 一、目标检测的进化之路&#xff1a;从“两步走”到“一眼定乾坤” YOLO的核心思想&#xff1a…

使用 HTML5 Canvas 打造炫酷的数字时钟动画

在 Web 开发中&#xff0c;HTML5 的 canvas 元素为我们带来了强大的绘图能力&#xff0c;结合 JavaScript&#xff0c;可以实现各种酷炫的效果。今天&#xff0c;我们将深入剖析一段经典的 彩色数字时钟动画 代码&#xff0c;并理解它是如何通过物理模拟实现数字切换时的炫酷粒…

XCZU6CG-2FFVC900I Xilinx FPGA AMD ZynqUltraScale+ MPSoC

XCZU6CG-2FFVC900I Xilinx FPGA&#xff08; AMD&#xff09;Zynq UltraScale MPSoC 。在处理系统&#xff08;PS&#xff09;方面&#xff0c;XCZU6CG 系列通常集成了 ARM Cortex-A53 应用核与 Cortex-R5 实时核的组合&#xff08;典型为 A53 多核 R5 双核组合&#xff09;&…

Navicat 询问 AI | 优化 SQL 查询

近期&#xff0c;我们发布了 Navicat 17.3 版本。这一版本实现了全方位升级&#xff0c;包括对 AI 功能大升级、支持达梦、金仓、瀚高、支持阿里通义千问等 AI 大模型&#xff0c;支持凝思 OS 以及多项 UI 改进。今天&#xff0c;我们将深入介绍 Navicat AI 功能之“询问 AI ”…

4.6 Vue 3 中的模板引用 (Template Refs)

在 Vue 3 中&#xff0c;ref 是一个核心的响应式 API&#xff0c;但它在模板中还有另一个非常重要的用途&#xff1a;获取对 DOM 元素或子组件实例的直接引用。这就是我们所说的“模板引用”。核心概念目的&#xff1a;让你在父组件中能够直接访问并操作特定的 DOM 元素或子组件…

模式匹配自动机全面理论分析

模式匹配是什么 模式匹配是计算机科学中一个基础且重要的问题&#xff0c;广泛应用于文本编辑、信息检索、网络安全、生物信息学等多个领域。简单来说&#xff0c;模式匹配就是在一个主文本中查找一个或多个特定模式串的出现位置。随着计算机处理能力的提升和数据规模的扩大&am…

AI 搜索时代:引领变革,重塑您的 SEO 战略

随着谷歌转向人工智能驱动的答案&#xff0c;使用以关键字和反向链接为中心的过时和传统的 SEO 策略不再起到任何作用。 由于 Google AI Overviews 和零点击搜索的兴起&#xff0c;自然点击量正在下降&#xff0c;用户无需点击任何网站即可直接在 Google 的搜索结果页面上获得答…

【网站深入seo方法】

目录 ①对于更成熟的网站&#xff0c;简单的index.html的入口文件的seo已经无法满足&#xff0c;需要在商品详情不同商品被搜索时赋予不同的title和description。 ②通过设置站点所有页面都新增Canonical标签&#xff0c;指定规范链接地址给谷歌并规避联盟的重复内容页面。 ③…

ROS move_base 混合功能导航 RealSense D435i + 3D 点云地图 + 楼层切换 + 路径录制 + 路径规划

Mixed-Navigation 这个博客也是记录我们的一个开源项目&#xff0c;其作用是混合功能导航。由于现有的 Fast-Lio-Localization 只实现了定位功能&#xff0c;但对于路径规划和楼层切换没有具体实现&#xff0c;因此我们开出了这个仓库作为参考。该仓库的核心功能如下&#xff…

初识c语言————宏定义和调用

目录&#xff1a;一.不带参数的宏二.带参数宏一.不带参数的宏不带参数的宏是指用#define指令定义的简单文本替换规则&#xff0c;它没有参数列表&#xff0c;直接替换标识符为相应的文本其一般形式为&#xff1a;#define 宏名 文本例如&#xff1a;#define pi 3.14这个代…

数据结构:满二叉树 (Full Binary Tree) 和 完全二叉树 (Complete Binary Tree)

目录 重要的术语澄清 完美二叉树 (Perfect Binary Tree) 完全二叉树 (Complete Binary Tree) 大比拼 (Comparison) 相互关系的第一性推导 我们来深入探讨两种在算法中非常重要的、具有特定“形状”的二叉树&#xff1a;满二叉树 (Full Binary Tree) 和 完全二叉树 (Compl…

OpenJDK 17的C1和C2编译器实现中,方法返回前插入安全点(Safepoint Poll)的机制

OpenJDK 17 JIT编译器堆栈分析-CSDN博客 在OpenJDK 17的C1和C2编译器实现中&#xff0c;方法返回前插入安全点&#xff08;Safepoint Poll&#xff09;的机制主要涉及以下关键步骤&#xff0c;结合源代码进行分析&#xff1a; 1. 安全点轮询桩&#xff08;Safepoint Poll Stu…

【论文笔记】STORYWRITER: A Multi-Agent Framework for Long Story Generation

论文信息 论文标题&#xff1a;StoryWriter: A Multi-Agent Framework for Long Story Generation 论文作者&#xff1a;Haotian Xia, Hao Peng et al. (Tsinghua University) 论文链接&#xff1a;https://arxiv.org/abs/2506.16445 代码链接&#xff1a;https://github.com/…

Cohere 开发企业级大型语言模型(LLM)

Cohere 是一家专注于开发企业级大型语言模型&#xff08;LLM&#xff09;的公司。该公司推出了一系列名为 “Command” 的模型&#xff0c;其中最强大的 “Command A” 于今年三月首次亮相 Cohere 还提供嵌入模型&#xff0c;这是一种将文件转化为神经网络可以理解的紧凑数值形…

Rust Web框架Axum学习指南之入门初体验

一、准备阶段 确保已经安装 rust&#xff0c;开发环境使用 vscode 或者 rustrover 都可以。接着就可以创建项目&#xff0c;通过编辑器创建或者命令行创建都可以&#xff1a; cargo new axum-admin二、添加依赖 添加依赖如下&#xff1a; [package] name "axum-admin&quo…

autofit.js: 自动调整HTML元素大小的JavaScript库

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

RocketMQ 命名服务器(NameServer)详解

&#x1f680; RocketMQ 命名服务器&#xff08;NameServer&#xff09;详解 NameServer 是 RocketMQ 架构中的轻量级路由发现服务&#xff0c;它不参与消息的收发&#xff0c;但承担着整个集群的“地址簿”和“导航系统”的关键角色。 理解 NameServer 的设计与工作原理&#…

代码随想录算法训练营四十三天|图论part01

深度优先搜索&#xff08;dfs&#xff09;理论基础 dfs就是可一个方向去搜直到尽头再换方向&#xff0c;换方向的过程就涉及到了回溯。 代码框架 因为dfs搜索可一个方向&#xff0c;并需要回溯&#xff0c;所以用递归的方式来实现是最方便的。 先来回顾一下回溯法的代码框架…

飞算JavaAI金融风控场景实践:从实时监测到智能决策的全链路安全防护

目录一、金融风控核心场景的技术突破1.1 实时交易风险监测系统1.1.1 高并发交易数据处理1.2 智能反欺诈系统架构1.2.1 多维度欺诈风险识别1.3 动态风控规则引擎1.3.1 风控规则动态管理二、金融风控系统效能升级实践2.1 风控模型迭代加速机制2.1.1 自动化特征工程结语&#xff1…