• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    vue实现自定义颜色选择器

    发布者: 土豆服务器 | 发布时间: 2025-6-16 07:36| 查看数: 131| 评论数: 0|帖子模式

    vue自定义颜色选择器
    效果图:

    step0: 默认写法 调用系统自带的颜色选择器
    1.        <input type="color">
    复制代码
    step1:C:\Users\wangrusheng\PycharmProjects\untitled18\src\views\Home.vue
    1. <template>  <div class="container">    <!-- 颜色选择器组件 -->    <ColorPicker v-model="selectedColor" />    <!-- 新增的动态背景按钮 -->    <div>    <button      class="dynamic-button"      :style="{ backgroundColor: selectedColor }"    >      我的背景色会变化!    </button>       <input type="color">    <p>当前选中颜色: {{ selectedColor }}</p>    </div>     </div></template><script>import ColorPicker from './ColorPicker.vue'export default {  components: { ColorPicker },  data() {    return {      selectedColor: '#ff0000' // 默认颜色    }  }}</script>
    复制代码
    step2:C:\Users\wangrusheng\PycharmProjects\untitled18\src\views\ColorPicker.vue
    1. <template>
    2.   <div class="color-picker">
    3.     <!-- 饱和度/明度选择区域 -->
    4.     <div
    5.       class="saturation"
    6.       :style="{ backgroundColor: `hsl(${hsv.h}, 100%, 50%)` }"
    7.       @mousedown="startDrag"
    8.     >
    9.       <div
    10.         class="selector"
    11.         :style="{
    12.           left: `${hsv.s * 100}%`,
    13.           top: `${(1 - hsv.v) * 100}%`,
    14.           backgroundColor: currentColor
    15.         }"
    16.       ></div>
    17.     </div>

    18.     <!-- 色相滑块 -->
    19.     <div class="hue-slider" @mousedown="startHueDrag">
    20.       <div
    21.         class="hue-pointer"
    22.         :style="{ left: `${(hsv.h / 360) * 100}%` }"
    23.       ></div>
    24.     </div>

    25.     <!-- 颜色显示和输入 -->
    26.     <div class="color-preview" :style="{ backgroundColor: currentColor }"></div>
    27.     <input
    28.       v-model="hexColor"
    29.       class="hex-input"
    30.       placeholder="#FFFFFF"
    31.       @input="handleHexInput"
    32.     >
    33.   </div>
    34. </template>

    35. <script>
    36. export default {
    37.   props: {
    38.     modelValue: String
    39.   },
    40.   emits: ['update:modelValue'],
    41.   data() {
    42.     return {
    43.       hsv: { h: 0, s: 1, v: 1 },
    44.       hexColor: '#ff0000',
    45.       isDragging: false,
    46.       isHueDragging: false
    47.     }
    48.   },
    49.   computed: {
    50.     currentColor() {
    51.       return this.hsvToHex(this.hsv)
    52.     }
    53.   },
    54.   methods: {
    55.     startDrag(e) {
    56.       this.isDragging = true
    57.       this.handleDrag(e)
    58.       window.addEventListener('mousemove', this.handleDrag)
    59.       window.addEventListener('mouseup', this.stopDrag)
    60.     },
    61.     startHueDrag(e) {
    62.       this.isHueDragging = true
    63.       this.handleHueDrag(e)
    64.       window.addEventListener('mousemove', this.handleHueDrag)
    65.       window.addEventListener('mouseup', this.stopHueDrag)
    66.     },
    67.     handleDrag(e) {
    68.       if (!this.isDragging) return
    69.       const rect = e.target.getBoundingClientRect()
    70.       const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width))
    71.       const y = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height))

    72.       this.hsv.s = x
    73.       this.hsv.v = 1 - y
    74.       this.updateHex()
    75.     },
    76.     handleHueDrag(e) {
    77.       if (!this.isHueDragging) return
    78.       const rect = e.target.getBoundingClientRect()
    79.       const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width))
    80.       this.hsv.h = x * 360
    81.       this.updateHex()
    82.     },
    83.     stopDrag() {
    84.       this.isDragging = false
    85.       window.removeEventListener('mousemove', this.handleDrag)
    86.       window.removeEventListener('mouseup', this.stopDrag)
    87.     },
    88.     stopHueDrag() {
    89.       this.isHueDragging = false
    90.       window.removeEventListener('mousemove', this.handleHueDrag)
    91.       window.removeEventListener('mouseup', this.stopHueDrag)
    92.     },
    93.     updateHex() {
    94.       this.hexColor = this.hsvToHex(this.hsv)
    95.       this.$emit('update:modelValue', this.hexColor)
    96.     },
    97.     handleHexInput() {
    98.       if (/^#([0-9A-F]{3}){1,2}$/i.test(this.hexColor)) {
    99.         this.hsv = this.hexToHsv(this.hexColor)
    100.       }
    101.     },
    102.     // 颜色转换函数
    103.     hsvToHex(hsv) {
    104.       const h = hsv.h / 360
    105.       let r, g, b

    106.       const i = Math.floor(h * 6)
    107.       const f = h * 6 - i
    108.       const p = hsv.v * (1 - hsv.s)
    109.       const q = hsv.v * (1 - f * hsv.s)
    110.       const t = hsv.v * (1 - (1 - f) * hsv.s)

    111.       switch (i % 6) {
    112.         case 0: r = hsv.v, g = t, b = p; break
    113.         case 1: r = q, g = hsv.v, b = p; break
    114.         case 2: r = p, g = hsv.v, b = t; break
    115.         case 3: r = p, g = q, b = hsv.v; break
    116.         case 4: r = t, g = p, b = hsv.v; break
    117.         case 5: r = hsv.v, g = p, b = q; break
    118.       }

    119.       return `#${[r, g, b]
    120.         .map(x => Math.round(x * 255)
    121.         .toString(16)
    122.         .padStart(2, '0'))
    123.         .join('')}`
    124.     },
    125.     hexToHsv(hex) {
    126.       // 转换逻辑(此处省略具体实现)
    127.       // 返回类似 {h: 0, s: 1, v: 1} 的HSV对象
    128.     }
    129.   }
    130. }
    131. </script>

    132. <style>
    133. .color-picker {
    134.   width: 300px;
    135.   padding: 20px;
    136.   background: #fff;
    137.   border-radius: 8px;
    138.   box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    139. }

    140. .saturation {
    141.   position: relative;
    142.   width: 100%;
    143.   height: 200px;
    144.   border-radius: 4px;
    145.   background: linear-gradient(to top, #000, transparent),
    146.               linear-gradient(to right, #fff, transparent);
    147. }

    148. .selector {
    149.   position: absolute;
    150.   width: 16px;
    151.   height: 16px;
    152.   border: 2px solid white;
    153.   border-radius: 50%;
    154.   transform: translate(-8px, -8px);
    155.   box-shadow: 0 1px 3px rgba(0,0,0,0.3);
    156. }

    157. .hue-slider {
    158.   position: relative;
    159.   height: 12px;
    160.   margin: 15px 0;
    161.   background: linear-gradient(to right,
    162.     #ff0000 0%,
    163.     #ffff00 17%,
    164.     #00ff00 33%,
    165.     #00ffff 50%,
    166.     #0000ff 67%,
    167.     #ff00ff 83%,
    168.     #ff0000 100%);
    169.   border-radius: 6px;
    170. }

    171. .hue-pointer {
    172.   position: absolute;
    173.   width: 16px;
    174.   height: 16px;
    175.   background: white;
    176.   border-radius: 50%;
    177.   transform: translate(-8px, -2px);
    178.   box-shadow: 0 1px 3px rgba(0,0,0,0.3);
    179. }

    180. .color-preview {
    181.   width: 40px;
    182.   height: 40px;
    183.   border-radius: 4px;
    184.   border: 1px solid #ddd;
    185. }

    186. .hex-input {
    187.   margin-left: 10px;
    188.   padding: 8px;
    189.   width: 100px;
    190.   border: 1px solid #ddd;
    191.   border-radius: 4px;
    192. }
    193. </style>
    复制代码
    到此这篇关于vue实现自定义颜色选择器的文章就介绍到这了,更多相关vue颜色选择器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:https://www.jb51.net/javascript/339700qru.htm
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表