<uniapp><指针组件>基于uniapp,编写一个自定义箭头指针组件

前言

本专栏是关于uniapp的相关介绍,如果你对uniapp感兴趣,不妨来看看。

环境配置

系统:windows10

平台:HBuilderX4.76

语言:vue、javascript

库:uni

概述

本文是基于uniapp,编写一个自定义组件,一个直线带箭头的指针组件,效果图如下:

1、组件简介

这个组件的功能就是生成一个带箭头的直线指针,可以设置长度、颜色、角度等参数,内部是使用了svg封装的,之所以要写这样的组件,是因为我为了实现时钟的效果,想着添加时针、秒针这样的元素,而且为了模拟时钟,秒针还需要每秒变化,效果如下:

所以想着,为了方便调用,将指针单独写成一个组件,这样不仅制作秒针等场景时可以使用,如果有其他场景,需要这样的一个指针,也可以直接调用。

2、组件实现

如上所述,组件内部就是一个svg,分为两部分,直线、箭头。

我们先来看下内部svg的结构:

1、箭头部分

箭头部分即marker包裹的内容,箭头当然可以是任意形状,但我们此处使用的是比较通用的三角形箭头,箭头包括了图形的长度、宽度、顶点坐标等,如下:

js 复制代码
<marker
					id="arrow"
					:markerWidth="10"
					:markerHeight="10"
					:refX="9"
					:refY="5"
					orient="auto"
				>
					<polygon points="0 0,10 5,0 10" fill="#000000"></polygon>
				</marker>

不过,我们可以将这些参数用变量来表示,我们设置三种规格的箭头:small、normal、big,通过属性markerMode来选择:

js 复制代码
//根据模式选择marker配置
	const getMarkerConfig = (mode)=>{
		const config = {
			small: { id:'small', markerWidth:6,  markerHeight:6,   refX:5,  refY:3,   },
			normal:{ id:'normal', markerWidth:10, markerHeight:10,  refX:9,  refY:5,   },
			big:   { id:'big', markerWidth:15, markerHeight:15,  refX:14,  refY:7.5,},
		};
		return config[mode] || config.normal;
	};
	const polygonPoints= computed(()=>{
		if (props.markerMode === 'normal'){
			return "0 0,10 5,0 10"
		} else if(props.markerMode === 'small'){
			return "0 0,6 3,0 6"
		} else if(props.markerMode == 'big'){
			return "0 0,15 7.5,0 15"
		} else{
			return "0 0,10 5,0 10"
		}
		
	});

如上,我们添加getMarkerConfig函数来根据mode返回不同配置,然后我们使用v-bind绑定它:

js 复制代码
<marker 
						v-bind="getMarkerConfig(props.markerMode)"
						orient="auto"
					>
						<polygon :points="polygonPoints" fill="#000000" />
					</marker>

这样,我们调用组件时,只需要设置markerMode即可:

js 复制代码
<linePointer
						:startP="startP"
						:lineDistance="100"
						lineColor="#55aaff"
						:isDashed="true"
						markerMode="big"
					></linePointer>

箭头效果:

2、直线部分

直线部分用于渲染直线,先看结构:

js 复制代码
	<line
					:x1="xx1"
					:y1="yy1"
					:x2="xx2"
					:y2="yy2"
					:stroke-width="lineWidth"
					:stroke="lineColor"
					:stroke-dasharray="isDashed? '10,5' : 'none'"
					:marker-end="`url(#${props.markerMode})`"
					>
				</line>

要显示直线,需要知道直线的起点、终点,还需要设置直线的宽度、颜色、是否虚线,marker-end是将箭头添加到直线末端。(也可以在起始端添加箭头,但本组件不使用),双箭头效果:

我们为组件设置属性:起点坐标、长度,然后来计算终点坐标:

js 复制代码
const angle = computed(()=>{
		if(!props.lineAngle) return 0;
		return props.lineAngle;
	});
	const rad = computed(()=>{
		return (angle.value * Math.PI) / 180
	});
	const distance = computed(()=>{
		if(!props.lineDistance) return 100;
		return props.lineDistance
	});
const xx2 = computed(()=>{
		return (xx1.value + distance.value * Math.cos(rad.value))
	});
	const yy2 = computed(()=>{
		return (yy1.value + distance.value * Math.sin(rad.value))
	});

使用计算属性,可以自动响应变化。

看一下演示效果:

相关推荐
还是大剑师兰特4 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷4 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
华洛5 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq5 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A6 小时前
vue css中 :global的使用
前端·javascript·vue.js
灵感__idea7 小时前
Hello 算法:复杂问题的应对策略
前端·javascript·算法
chushiyunen7 小时前
python中的内置属性 todo
开发语言·javascript·python
soso19688 小时前
JavaScript性能调优实战案例
javascript
Moment9 小时前
前端工程化 + AI 赋能,从需求到运维一条龙怎么搭 ❓❓❓
前端·javascript·面试
Joker Zxc9 小时前
【前端基础(Javascript部分)】6、用JavaScript的递归函数和for循环,计算斐波那契数列的第 n 项值
开发语言·前端·javascript