mdui实现一个拖动时钟指针选择事件效果代码

代码语言:html

所属分类:选择器

代码描述:mdui实现一个拖动时钟指针选择事件效果代码

代码标签: 拖动 时钟 指针 选择 事件 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">
    <link type="text/css" rel="stylesheet" href="//repo.bfw.wiki/bfwrepo/css/mdui.min.css">

    <style>
        html, body {
          height: 100%;
        }
        body {
          margin: 0;
          display: flex;
          align-items: center;
          justify-content: center;
          flex-direction: column;
          overflow-y: auto;
        }
        /*好看的更新动画*/
        mdui-replaceable {
          position: relative;
          display: block;
        }
        mdui-replaceable > div {
          box-sizing: border-box;
          width: 100%;
        }
        mdui-replaceable > .replacement-wrapper {
          position: absolute;
          left: 0;
          top: 0;
          right: 0;
          text-align: inherit;
        }
        /*选择器公用样式*/
        .picker {
          width: 330px;
          box-shadow: 0 39px 56px 4px rgba(0, 0, 0, .24);
          border-radius: 2px;
          overflow: hidden;
          background: white;
          /*控件颜色*/
          --preferred-color: #009688;
        }
        .picker > header {
          width: 100%;
          background: var(--preferred-color, #009688);
          color: white;
        }
        .picker > header button {
          text-align: left;
          box-sizing: border-box;
          border: none;
          padding: 0;
          background: none;
          color: rgba(255, 255, 255, .7);
          font-family: Roboto, -apple-system, PingFang SC, Noto Sans CJK SC, sans-serif;
          font-size: 16px;
          font-weight: 500;
          height: 16px;
          transition: all .3s cubic-bezier(0.2, 0.9, 0.4, 1);
        }
        .picker > header button.picker-toggle-active {
          color: white;
        }
        .picker > footer > button {
          color: var(--preferred-color, #009688)!important; /*MDUI对按钮的颜色设置会覆盖此属性*/
        }
        /*时间选择器*/
        .picker.time-picker {
          user-select: none;
        }
        .picker.time-picker > header {
          box-sizing: border-box;
          padding: 28px 48px 23px;
          display: flex;
          align-items: center;
          justify-content: flex-end;
          color: rgba(255, 255, 255, .7);
        }
        .picker.time-picker .time-picker--time-hour-switch, .picker.time-picker .time-picker--time-hour-switch > button {
          font-size: 60px;
          height: 45px;
          line-height: 20px;
          font-weight: 400;
        }
        .picker.time-picker .time-picker--am-pm-switch {
          margin-left : 24px;
          display: flex;
          flex-direction: column;
          justify-content: center;
        }
        .picker.time-picker .time-picker--am-pm-switch > button {
          height: 12px;
          line-height: 20px;
          overflow: visible;
        }
        .picker.time-picker .time-picker--am-pm-switch > button+button {
          margin-top: 11px;
        }
        .picker.time-picker .time-picker--selector {
          position: relative;
          box-sizing: border-box;
          height: 296px;
          width: 296px;
          border-radius: 50%;
          background: #EEEEEE;
          margin: 33px auto 8px;
          user-select: none;
          padding: 14px;
        }
        .picker.time-picker .time-picker--selection-wrapper {
          position: absolute;
          z-index: 2;
          width: 268px;
          height: 268px;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: flex-start;
          transform: rotate(var(--selection-rotation));
        }
        .picker.time-picker .time-picker--selection-wrapper > span {
          transform: rotate(calc( var(--selection-rotation) * -1 ));
          font-size: 16px;
          color: rgba(0, 0, 0, .87);
          letter-spacing: .1px;
        }
        .picker.time-picker :is(.time-picker--indicator, .time-picker--indicator-inverted) {
          position: absolute;
          left: 0;
          top: 0;
          right: 0;
          bottom: 0;
          padding: 3px;
          transform: rotate(var(--indicator-rotation));
          display: flex;
          flex-direction: column;
          align-items: center;
          transition: transform .3s cubic-bezier(0.2, 0.9, 0.4, 1);
        }
        .picker.time-picker .time-picker--selector:is(.time-picker--active, :active) :is(.time-picker--indicator, .time-picker--indicator-inverted) {
          transition: none; /*按着鼠标调整时,不应该有过渡,这会让钟表指针的运动看起来迟钝、不跟手*/
        }
        .picker.time-picker .time-picker--hand {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          background: var(--preferred-color);
          filter: invert(1);
          display: flex;
          align-items: center;
          justify-content: center;
        }
        .picker.time-picker .time-picker--hand.time-picker--display-black-dot::before {
          content: '';
          height: 4px;
          width: 4px;
          background: black;
          border-radius: 50%;
          filter: invert(1);
        }
        .picker.time-picker .time-picker--needle {
          width: 2px;
          height: 102px;
          background: var(--preferred-color);
        }
        .picker.time-picker .time-picker--axis { 
          height: 6px;
          width: 6px;
          background: var(--preferred-color);
          border-radius: 50%;
        }
        .picker.time-picker .time-picker--indicator-inverted {
          z-index: 3;
        }
        .picker.time-picker .time-picker--indicator-inverted::before {
          content: ' ';
          display: block;
          height: 40px;
          width: 40px;
          border-radius: 50%;
          backdrop-filter: invert(1);
        }
        /*24小时*/
        .picker.time-picker.time-picker--24-hours > header {
          justify-content: center;
        }
    </style>



</head>

<body>
    <div class="picker time-picker">
        <!--dialog 元素有自己的样式,而且默认会藏起来自己,使用不便-->
        <header>
            <div class="time-picker--time-hour-switch">
                <button id="hour" class="mdui-ripple">-</button>:<button id="minute" class="mdui-ripple">-</button>
            </div>
            <div class="time-picker--am-pm-switch">
                <button id="am" class="mdui-ripple">-</button>
                <button id="pm" class="mdui-ripple">-</button>
            </div>
        </header>
        <!--mdui-replaceable 的加入,使HTML结构很复杂,所以有必要用class来简化CSS选择器,不然选择器一堆“>”真是看不下去-->
        <main class="time-picker--selector">
            <div class="time-picker--indicator">
                <div class="time-picker--hand"></div>
                <div class="time-picker--needle"></div>
                <div class="time-picker--axis"></div>
            </div>
            <mdui-replaceable></mdui-replaceable>
            <div class="time-picker--indicator-inverted"></div>
        </main>
        <footer class="mdui-dialog-actions">
            <button class="mdui-btn mdui-ripple" id="cancel">-</button>
            <button class="mdui-btn mdui-ripple" id="confirm">-</button>
        </footer>
    </div>
    <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/mdui.min.js"></script>
    <script>
        const $ = mdui.$;
        
        //本地化信息,可自己修改
        const localization = {
          weekdays: "Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","),
          weekdayAbbreviations: "SMTWTFS".split(""), //为了减少后边检测这是数组还是字符串的工作量(因为字符串没有map这样的方法),这里直接做成数组
          months: "January,February,March,April,May,June,July,August,September,October,November,December".split(
            ","
          ),
          monthAbbreviations: "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(
            ","
          ), //自己手机的 Material Design 应用上九月的缩写都是Sep,尽管课本上的缩写是“Sept.”。
          am: "AM",
          pm: "PM",
          cancelText: "CANCEL",
          confirmText: "OK",
          //日期选择器上的日和月
          dayText(weekday, month, day) {
            return `${this.weekdays[weekday]}, ${this.monthAbbreviations[month]} ${day}`;
          },
          monthText(month, year) {
            return `${this.months[month]} ${year}`;
          }
        };
        
        //简体中文,去掉下划线(并给上边的加上下划线)以应用
        const _localization = {
          weekdayAbbreviations: "日一二三四五六".split(""),
          //星期、月份什么的只会被下面两个函数引用,所以没必要的话,不写也完全可以,星期缩写除外
          am: "上午",
          pm: "下午",
          cancelText: "取消",
          confirmText: "确定",
          //日期选择器上的日和月
          dayText(weekday, month, day) {
            return `${month}月${day}日星期${this.weekdayAbbreviations[weekday]}`;
          },
          monthText(month, year) {
            return `${year}年${month + 1}月`;
          }
        };
        
        //在更新内容时,可以有各种好看的动画
        //更新内容在Shadow DOM里的话,就不能继承外部的CSS,会导致样式错误,所以不能用Shadow DOM。
        customElements.define(
          "mdui-replaceable",
          class extends HTMLElement {
            #stack = [];
            #wrapper = document.createElement("div");
            animations = {
              fade: {
                enter: { opacity: [0, 0, 1] },
                exit: { opacity: [1, 0, 0] }
              },
              "slide-left": {
                enter: {
                  transform: ["translateX(100%)", "translateX(0)"],
                  opacity: [0, 1]
                },
                exit: [
                  { transform: "translateX(0)", opacity: 1 },
                  { transform: "translateX(-100%)", opacity: 0 }
                ]
              },
              "slide-right": {
                enter: {
                  transform: ["translateX(-100%)", "translateX(0)"],
                  opacity: [0, 1]
                },
                exit: [
                  { transform: "translateX(0)", opacity: 1 },
                  { transform: "translateX(100%)", opacity: 0 }
                ]
              },
              "slide-up": {
                enter: {
                  transform: ["translateY(100%)", "translateY(0)"],
                  opacity: [0, 1]
                },
                exit: [
                  { transform: "translateY(0)", opacity: 1 },
                  { transform: "translateY(-100%)", opacity: 0 }
                ]
              },
              "slide-down": {
                enter: {
                  transform: ["translateY(-100%)", "translateY(0)"],
                  opacity: [0, 1]
                },
                exit: [
                  { transform: "translateY(0)", opacity: 1 },
                  { transform: "translateY(100%)", opacity: 0 }
                ]
              }
            };
            constructor() {
              super();
              this.#wrapper.classList.add("wrapper");
              this.#wrapper.append(...this.childNodes);
              this.append(this.#wrapper);
            }
            replace(
              replacement,
              type = "fade",
              duration = 300,
              easing = "cubic-bezier(0.2, 0.9, 0.4, 1)"
            ) {
              this.#stack.push({ replacement, type, duration, easing });
              this.#stack.length === 1 && this.#update();
            }
            #update() {
              const { replacement, type, duration, easing } = this.#stack[0];
              const replacementWrapper = docum.........完整代码请登录后点击上方下载按钮下载查看

网友评论0