news 2026/9/3 1:25:19

128 自定义滑块

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
128 自定义滑块

1.自定义滑块

做法: 1.先定义好动画,暂停 2.使用动画的delay时间,来确定各个时间点位置 3.通过input:range来改变delay的css变量值,使用dom.style.setProperty('--delayTime',25s)来设置
<template> <!--智能环绕参数面板--> <pop-dialog width="368px" left="50%" top="35%" title="智能环绕设置" @close="onClose" > <div class="content"> <div class="explanation-box"> 说明:可通过键盘微调飞行位置,调整环绕高度或半径,请检查周边环境后再执行环绕操作。 </div> <div class="params-box"> <div class="params-box-item"> <div class="params-box-item-title">环绕高度</div> <div class="params-box-item-content"> <div class="params-btn" @click="handleSurround(-100)">-100</div> <div class="params-btn" @click="handleSurround(-10)">-10</div> <div class="params-btn" @click="handleSurround(-1)">-1</div> <a-input placeholder="请输入" addon-after="m" v-model:value="formData.surroundHeight" /> <div class="params-btn add" @click="handleSurround(1)">1</div> <div class="params-btn add" @click="handleSurround(10)">10</div> <div class="params-btn add" @click="handleSurround(100)">100</div> </div> </div> <div class="params-box-item"> <div class="params-box-item-title">环绕距离</div> <div class="params-box-item-content"> <div class="params-btn" @click="handleSurRadius(-100)">-100</div> <div class="params-btn" @click="handleSurRadius(-10)">-10</div> <div class="params-btn" @click="handleSurRadius(-1)">-1</div> <a-input placeholder="请输入" addon-after="m" v-model:value="formData.surroundRadius" /> <div class="params-btn add" @click="handleSurRadius(1)">1</div> <div class="params-btn add" @click="handleSurRadius(10)">10</div> <div class="params-btn add" @click="handleSurRadius(100)">100</div> </div> </div> <div class="params-box-item"> <div class="params-box-item-title">环绕速度</div> <div class="params-box-item-content column"> <div class="slider-box" ref="sliderBoxRef"> <input type="range" name="" id="" class="slider-input" :min="0" :max="50" ref="sliderInputRef" v-model="sliderValue" > <div class="slider-inner"> <img ref="sliderArrowRef" class="slider-arrow" :src="sliderArrow" alt="" /> </div> </div> <div class="slider-display"> <div class="slider-display-name"> {{ isClockwise ? '顺时钟' : '逆时针' }} </div> <div class="slider-display-name"> <span class="blue">{{ formData.surroundSpeed }}</span >m/s </div> <div class="slider-display-name">25m/s</div> </div> </div> </div> </div> </div> <template #footer> <a-button class="border-radius4" @click="onCancel">取消</a-button> <a-button class="border-radius4" type="primary" @click="onConfirm" >确定</a-button > </template> </pop-dialog> </template> <script setup lang="ts"> import { computed, onMounted, reactive, ref, nextTick } from 'vue' import popDialog from '@/components/pop-dialog.vue' import { message } from 'ant-design-vue' import sliderArrow from '@/components/cockpit/img/slider-arrow.png' const $emit = defineEmits(['close', 'confirm']) //顺时针 const isClockwise = ref(true) const formData = ref({ surroundHeight: 3, surroundRadius: 3, surroundSpeed: 3, }) //输入框速度 const sliderValue = ref(25) const handleSurround = (value: any) => { formData.value.surroundHeight = Number(formData.value.surroundHeight) + value } const handleSurRadius = (value: any) => { formData.value.surroundRadius = Number(formData.value.surroundRadius) + value } const sliderInputRef = ref() const sliderBoxRef = ref() onMounted(() => { if (isClockwise.value) {//顺时针 sliderValue.value = 25 - formData.value.surroundSpeed } else { sliderValue.value = formData.value.surroundSpeed + 25 } sliderInputRef.value.addEventListener('input', (e: any) => { if (e.target.value >= 25) { isClockwise.value = false formData.value.surroundSpeed= e.target.value - 25 } else { isClockwise.value = true formData.value.surroundSpeed=25 - e.target.value } const time = -50 + e.target.value; console.log(`${time}s` ); sliderBoxRef.value.style.setProperty('--delayTime',`${time}s` ) }) }) const onCancel = () => { $emit('close') } const onConfirm = () => { $emit('confirm') } //指点模式选择 const handleModelClick = (item: any) => {} const onClose = () => { $emit('close') } </script> <style lang="scss" scoped> @keyframes sliderInner { 0% { width: 45%; right: 50%; left: auto; //靠右居中 transform: translate(0%, -50%); } 50% { width: 0%; right: 50%; left: auto; transform: translate(0%, -50%); } 50.01% { width: 0%; right: auto; left: 50%; transform: translate(0%, -50%); } 100% { width: 45%; right: auto; left: 50%; transform: translate(0%, -50%); } } @keyframes sliderArrow { 0% { right: auto; left: 0; transform: translate(-50%, -50%); } 50% { right: auto; left: 0; transform: translate(-50%, -50%); } 50.01% { right: 0; left: auto; transform: translate(50%, -50%); } 100% { right: 0; left: auto; transform: translate(50%, -50%); } } $totalTime:50s; .popup { .popup-content { padding: 12px; } } .content { width: 100%; display: flex; flex-direction: column; gap: 8px; .explanation-box { width: 100%; /* 自动布局 */ display: flex; flex-direction: row; justify-content: center; align-items: center; padding: 8px; gap: 16px; background: rgba(255, 170, 0, 0.2); color: #ffaa00; } .params-box { display: flex; flex-direction: column; gap: 8px; .params-box-item { height: 90px; padding: 0px 12px; background: rgba(13, 21, 29, 0.6); display: flex; flex-direction: column; justify-content: center; gap: 8px; .params-box-item-title { } .params-box-item-content { display: flex; gap: 4px; .params-btn { cursor: pointer; user-select: none; width: auto; min-width: 30px; height: 30px; padding: 4px; border-radius: 4px; background: rgba(255, 255, 255, 0.16); // 添加以下属性确保flex行为正确 flex: 0 0 auto; // 不伸缩,根据内容自适应 box-sizing: border-box; // 确保padding不影响实际宽度计算 color: #a2a7b4; &.add { color: #fff; } &:hover { background: rgba(255, 255, 255, 0.24); } } &.column { flex-direction: column; } .slider-box { --delayTime: -50s; position: relative; width: 324px; height: 24px; background: url('@/components/cockpit/img/slider-bar.png') no-repeat center; background-size: 100% 100%; &::after { content: ''; z-index: 2; display: block; width: 10px; height: 20px; border-radius: 2px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #fff; } .slider-input{ opacity: 0; width: 90%; position: absolute; top: 50%; transform: translate(5%,-50%); z-index: 9; } .slider-inner { z-index: 1; position: absolute; width: 0%; height: 12px; top: 50%; left: 50%; // transform: translate(-100%, -50%); background-color: #1a71ff; animation: sliderInner $totalTime linear var(--delayTime,-25s) infinite; animation-play-state: paused; .slider-arrow { z-index: 9; // cursor: pointer; // pointer-events: all; position: absolute; top: 50%; left: 0; transform: translate(-50%, -50%); animation: sliderArrow $totalTime linear var(--delayTime,-25s) infinite; animation-play-state: paused; } } } .slider-display { display: flex; justify-content: space-between; font-size: 14px; color: #fff; .slider-display-name { .blue { color: #1a71ff; font-size: 14px; font-weight: 600; } } } } } } } </style>
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 22:11:52

国抽对接规则

1、国抽可以同步下来 待填报之前的样品信息&#xff08;包括正在接样状态&#xff09;。 2、国抽可以同步下来 待填报且已维护基础表的项目信息&#xff08;基础表维护按照报送分类B及细类维护&#xff0c;或特殊样品的项目维护&#xff09;。

作者头像 李华
网站建设 2026/9/2 22:11:49

[特殊字符]️_开发效率与运行性能的平衡艺术[20260107171443]

作为一名经历过无数项目开发的工程师&#xff0c;我深知开发效率与运行性能之间的平衡是多么重要。在快节奏的互联网行业&#xff0c;我们既需要快速交付功能&#xff0c;又需要保证系统性能。今天我要分享的是如何在开发效率和运行性能之间找到最佳平衡点的实战经验。 &#…

作者头像 李华
网站建设 2026/9/2 22:12:19

c++ 17的std::variant对标c#的哪个类型

C# 的 System.Object、dynamic 和 C# 7.0 引入的 System.ValueTuple 以及 System.OneOf 等都可以实现类似功能&#xff0c;但最接近 C std::variant 语义的是&#xff1a;1. 官方方案&#xff1a;System.Object 和模式匹配&#xff08;最接近&#xff09;基础用法csharp// 类似…

作者头像 李华
网站建设 2026/8/30 6:28:11

狂揽77k Star!我用3分钟,给本地服务安上了公网域名

我经常需要在外面访问家里的 NAS&#xff0c;或者给客户演示我电脑上一个还没上线的项目。每次都被内网穿透搞得头疼不已&#xff0c;不是要研究复杂的路由器设置&#xff0c;就是要忍受那些又慢又不稳定的免费服务。传统内网穿透&#xff0c;太折腾了想靠自己搞定内网穿透&…

作者头像 李华
网站建设 2026/9/3 1:00:17

ZGI 双向溯源:让 AI 的每一个回答都有据可查

为什么 RAG 依然会“自信地”胡说八道&#xff1f; 我们寄予厚望的 RAG&#xff08;检索增强生成&#xff09;技术&#xff0c;旨在通过引入外部知识来纠正大模型的“幻觉”。但在实践中&#xff0c;一个尴尬的局面屡见不鲜&#xff1a;RAG 系统精准地检索到了相关文档&#x…

作者头像 李华