news 2026/10/13 5:52:02

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/10/12 5:22:34

前后端分离教师工作量管理系统系统|SpringBoot+Vue+MyBatis+MySQL完整源码+部署教程

摘要 随着教育信息化的快速发展&#xff0c;高校教师工作量管理逐渐从传统的手工记录向数字化、智能化转型。传统管理方式存在效率低下、数据易丢失、统计不准确等问题&#xff0c;难以满足现代高校对教师工作量精细化管理的需求。教师工作量管理系统通过信息化手段实现工作量计…

作者头像 李华
网站建设 2026/10/9 14:56:00

自定义封装tabs,超出显示上下翻页按钮

效果展示&#xff1a;未超出&#xff1a;超出&#xff1a;代码&#xff1a;<template><div class"custom-tabs"><!-- 左侧翻页按钮 --><div class"scroll-btn left-btn" :class"{ disabled: !canScrollLeft }" click"…

作者头像 李华
网站建设 2026/10/9 23:52:51

自定义tabs(支持横向/竖向排列)

效果展示&#xff1a;组件代码&#xff1a;CustomTabs.vue组件代码如下&#xff1a;<template><div class"custom-tabs" :class"[tabs-${type}, { tabs-vertical: type vertical }]"><!-- 横向布局 --><template v-if"type ho…

作者头像 李华
网站建设 2026/10/9 5:43:26

[特殊字符]_可扩展性架构设计:从单体到微服务的性能演进[20260107163924]

作为一名经历过多次系统架构演进的老兵&#xff0c;我深知可扩展性对Web应用的重要性。从单体架构到微服务&#xff0c;我见证了无数系统在扩展性上的成败。今天我要分享的是基于真实项目经验的Web框架可扩展性设计实战。 &#x1f4a1; 可扩展性的核心挑战 在系统架构演进过…

作者头像 李华
网站建设 2026/10/8 2:09:54

2025年广州市“人工智能+”典型案例集|附118页PDF文件下载

《广州市“人工智能”典型案例集》展示了AI在各领域的应用。关键点包括&#xff1a;AI制造&#xff1a;智能座舱、多模态大模型应用、PCB项目等&#xff0c;提升效率与精度。AI安全&#xff1a;智能机器狗、安全大模型、AI安管一体机等&#xff0c;保障公共安全。AI教育&#x…

作者头像 李华
网站建设 2026/10/9 18:00:42

NestJS 中动态 Swagger 参数文档的实现

在 NestJS 项目中,常常需要对 API 的参数进行验证和文档化。特别是在使用 UUID 作为参数时,确保参数格式的正确性以及在 Swagger 中正确展示这些参数是非常重要的。今天我们来探讨如何在 NestJS 中创建一个自定义装饰器来验证 UUID 格式,并动态生成 Swagger 文档。 背景介绍…

作者头像 李华