news 2026/4/16 17:03:28

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/4/16 9:25:30

[特殊字符]_内存管理深度解析:如何避免GC导致的性能陷阱[20260107172234]

作为一名经历过无数性能调优案例的工程师&#xff0c;我深知内存管理对Web应用性能的影响有多大。在最近的一个项目中&#xff0c;我们遇到了一个棘手的性能问题&#xff1a;系统在高并发下会出现周期性的延迟飙升&#xff0c;经过深入分析&#xff0c;发现问题根源竟然是垃圾回…

作者头像 李华
网站建设 2026/4/16 9:24:58

在NEAR Protocol中获取用户账户的完整指南

近年来,随着区块链技术的发展,NEAR Protocol作为一个高效的智能合约平台,吸引了越来越多的开发者和用户。今天,我们将探讨如何在NEAR Protocol中获取用户账户列表,这对开发者来说是一个常见的需求,尤其是在进行用户数据分析或开发用户相关的应用时。 问题背景 在NEAR P…

作者头像 李华
网站建设 2026/4/16 10:18:03

格雷希尔:G15F-KFYK-FD39 定制款快速密封连接器,适配自动化产线,赋能电驱动通讯接口的自动化密封测试

某新能源设备商联系到我们&#xff0c;为其电驱动上的通讯接口采购一批快速密封连接器用于气密性测试&#xff0c;该生产线为自动化产线&#xff0c;对连接器的适配性、稳走性、耐用性均提出了极高要求。格雷希尔定制款 G15F-KFYK-FD39 自动化连接器格雷希尔定制款 G15F-KFYK-F…

作者头像 李华
网站建设 2026/4/16 10:16:42

2025年终总结 - 微分几何助力突破具身智能发展的瓶颈

今天是 2025 年 12 月 31 日&#xff0c;又到了一年一度回顾与思考的时刻。回望 2025 年&#xff0c;人工智能正在以前所未有的速度重塑人类社会结构&#xff0c;而具身智能&#xff08;Embodied Intelligence&#xff09;正逐渐成为这一轮技术浪潮中的核心焦点。所谓具身智能&…

作者头像 李华
网站建设 2026/4/16 10:18:35

Nordic方案——无线射频模组AS01-ML01SC

Nordic Semiconductor在无线性能和精密度方面拥有领先业界的表现&#xff0c;即使是对成本极为敏感的消费类产品&#xff0c;也能运用该公司的超低功耗 (ULP) 无线芯片。Nordic Semiconductor的芯片广泛用于无线PC外设、游戏控制器、体育和健身传感器、玩具、先进的多媒体控制器…

作者头像 李华