• 封装一个滑块控制灯光组件


    效果如下gif

    只进行了基础的事件和布局,可优化的地方:luminance-box这个div加上后,由于和slider-run-way都是absolute定位,导致slider-run-way的点击事件无法设置值,只能通过滑块设置。暂时想不到咋处理,有想法可以讨论一下

    html布局

    1. <div class="light-slider">
    2. <div
    3. class="slider-run-way"
    4. @click.stop="handleClickRunway($event)"
    5. ref="runwayRef"
    6. >
    7. <div class="active-bar" :style="{ width: activeWidth + '%' }">div>
    8. <div
    9. class="control-wrapper"
    10. :style="{ left: activeWidth + '%' }"
    11. @mousedown="handleMousedown($event)"
    12. >
    13. <div class="control-btn"><span>span><span>span>div>
    14. div>
    15. div>
    16. <div class="luminance-box" @click="handleRight">
    17. <img src="../../../../assets/home/homepage_control_bright.png" />
    18. <div class="right-box">
    19. <span class="num">{{ activeWidth }}%span>
    20. <span class="l-title">luminancespan>
    21. div>
    22. div>
    23. div>

    js部分

    1. export default {
    2. name: "lightingControl",
    3. props: {
    4. isDisabled: {
    5. type: Boolean,
    6. default: true,
    7. },
    8. },
    9. data() {
    10. return {
    11. activeWidth: 13,
    12. runWayWidth: 0, // 滑道总宽度
    13. startX: 0,
    14. dragging: false,
    15. isClick: true,
    16. startPosition: 0,
    17. };
    18. },
    19. mounted() {
    20. this.$nextTick(() => {
    21. this.runWayWidth = this.$refs.runwayRef.clientWidth;
    22. });
    23. },
    24. methods: {
    25. handleClickRunway(e) {
    26. if (!this.isClick || this.isDisabled) return;
    27. console.log(e);
    28. const { runWayWidth } = this;
    29. const { offsetX } = e;
    30. const percent = parseInt((offsetX / runWayWidth) * 100);
    31. this.activeWidth = percent;
    32. },
    33. handleRight(e) {
    34. return false;
    35. },
    36. handleMousedown(e) {
    37. if (this.isDisabled) return;
    38. e.preventDefault();
    39. this.startX = e.clientX;
    40. this.onDragStart(e);
    41. window.addEventListener("mousemove", this.onDragging);
    42. window.addEventListener("mouseup", this.onDragEnd);
    43. },
    44. onDragStart(e) {
    45. this.dragging = true;
    46. this.isClick = true;
    47. this.startPosition = parseFloat(this.activeWidth);
    48. },
    49. onDragging(e) {
    50. e.stopPropagation();
    51. if (this.dragging) {
    52. this.isClick = false;
    53. let currentX = e.clientX;
    54. let diff = ((currentX - this.startX) / this.runWayWidth) * 100;
    55. this.newPosition = this.startPosition + diff;
    56. this.setPosition(this.newPosition);
    57. }
    58. },
    59. onDragEnd() {
    60. if (this.dragging) {
    61. setTimeout(() => {
    62. this.dragging = false;
    63. if (!this.isClick) {
    64. this.setPosition(this.newPosition);
    65. this.isClick = true;
    66. }
    67. }, 0);
    68. window.removeEventListener("mousemove", this.onDragging);
    69. window.removeEventListener("mouseup", this.onDragEnd);
    70. }
    71. },
    72. setPosition(newPosition) {
    73. if (newPosition < 0) {
    74. newPosition = 0;
    75. } else if (newPosition > 100) {
    76. newPosition = 100;
    77. }
    78. this.activeWidth = Math.round(newPosition);
    79. },
    80. },
    81. };

    css

    1. .light-slider {
    2. margin-top: 16px;
    3. position: relative;
    4. .slider-run-way {
    5. width: 100%;
    6. position: relative;
    7. cursor: pointer;
    8. height: 70px;
    9. background: #d7eeff;
    10. border-radius: 4px 4px 4px 4px;
    11. .active-bar {
    12. height: 100%;
    13. position: absolute;
    14. left: 0;
    15. border-top-left-radius: 4px;
    16. border-bottom-left-radius: 4px;
    17. background: #36c1fd;
    18. }
    19. .control-wrapper {
    20. display: flex;
    21. align-items: center;
    22. justify-content: center;
    23. height: 30px;
    24. width: 22px;
    25. position: absolute;
    26. user-select: none;
    27. z-index: 1001;
    28. top: 20px;
    29. transform: translateX(-50%);
    30. background-color: transparent;
    31. .control-btn {
    32. width: 16px;
    33. height: 24px;
    34. background: #fff;
    35. box-shadow: 0px 0px 5px 0px rgba(76, 115, 184, 0.5);
    36. border-radius: 2px 2px 2px 2px;
    37. color: #36c1fd;
    38. display: flex;
    39. align-items: center;
    40. justify-content: space-evenly;
    41. span {
    42. width: 2px;
    43. height: 6px;
    44. background: #36c1fd;
    45. border-radius: 30px 30px 30px 30px;
    46. }
    47. }
    48. }
    49. }
    50. .luminance-box {
    51. display: flex;
    52. width: 100%;
    53. height: 70px;
    54. justify-content: space-between;
    55. align-items: center;
    56. position: absolute;
    57. left: 0;
    58. top: 0;
    59. img {
    60. width: 20px;
    61. height: 20px;
    62. margin-left: 14px;
    63. }
    64. .l-title {
    65. font-size: 14px;
    66. }
    67. .right-box {
    68. color: #2e2e48;
    69. display: flex;
    70. flex-direction: column;
    71. align-items: center;
    72. font-weight: bolder;
    73. margin-right: 10px;
    74. .num {
    75. font-size: 24px;
    76. }
    77. }
    78. }
    79. }

  • 相关阅读:
    ZMQ之脱机可靠性--巨人模式
    docker-compose部署三主三从redis集群
    单芯片3路CC管理的VR转接器解决方案
    民办二本计算机毕业以后
    LiveGBS流媒体平台GB/T28181功能-视频直播流快照的安全控制配置播放回调鉴权接口控制播放权限
    云服务器下搭建 NFS 网络文件系统
    JSP SSH 产品质量追溯管理统myeclipse开发mysql数据库MVC模式java编程网页设计
    【无标题】只出现一次的数字
    Python-装饰器
    使用动态住宅代理还能带来哪些好处?
  • 原文地址:https://blog.csdn.net/weixin_42704663/article/details/133911390