lsc 2 years ago
parent
commit
c094585f7f
1 changed files with 274 additions and 13 deletions
  1. 274 13
      src/components/tools/time.vue

+ 274 - 13
src/components/tools/time.vue

@@ -1,26 +1,287 @@
 <template>
-  <div class="box">
-    <div>
-      <input type="number" id="min" value />
-      <span id="timetext">分</span>
-      <input id="sec" type="number" value />
-      <span id="timetext">秒</span>
+  <div class="container">
+    <div class="setters">
+      <div class="minutes-set">
+        <button
+          data-setter="minutes-plus"
+          @click="changeTime('minutes-plus')"
+          :disabled="isStarted"
+          :style="{ opacity: isStarted ? 1 : 0.5 }"
+        >
+          +
+        </button>
+        <button
+          data-setter="minutes-minus"
+          @click="changeTime('minutes-minus')"
+          :disabled="isStarted"
+          :style="{ opacity: isStarted ? 1 : 0.5 }"
+        >
+          -
+        </button>
+      </div>
+      <div class="seconds-set">
+        <button
+          data-setter="seconds-plus"
+          @click="changeTime('seconds-plus')"
+          :disabled="isStarted"
+          :style="{ opacity: isStarted ? 1 : 0.5 }"
+        >
+          +
+        </button>
+        <button
+          data-setter="seconds-minus"
+          @click="changeTime('seconds-minus')"
+          :disabled="isStarted"
+          :style="{ opacity: isStarted ? 1 : 0.5 }"
+        >
+          -
+        </button>
+      </div>
     </div>
-    <el-button type="primary" onclick="start()">开始</el-button>
-    <el-button type="primary" onclick="stop()">暂停</el-button>
-    <el-button type="primary" onclick="Reset()">重置</el-button>
-    <div>
-      <span id="timetext">00时00分00秒</span>
+    <div class="circle">
+      <svg width="300" viewBox="0 0 220 220" xmlns="http://www.w3.org/2000/svg">
+        <g transform="translate(110,110)">
+          <circle r="100" class="e-c-base" />
+          <g transform="rotate(-90)">
+            <circle r="100" class="e-c-progress" :style="{ strokeDasharray: offset }" />
+            <g id="e-pointer" :style="{ transform: pointerTransform }">
+              <circle cx="100" cy="0" r="8" class="e-c-pointer" />
+            </g>
+          </g>
+        </g>
+      </svg>
     </div>
+    <div class="controlls">
+      <div class="display-remain-time">{{ displayString }}</div>
+      <button
+        :class="{ play: !play, pause: play }"
+        id="pause"
+        @click="pauseTimer"
+      ></button>
+    </div>
+    <el-button type="primary" @click="reset">重置</el-button>
   </div>
 </template>
 
 <script>
 export default {
   data() {
-    return {};
+    return {
+      length: Math.PI * 2 * 100,
+      offset: 0,
+      pointerTransform: "",
+      play: false,
+      intervalTimer: null,
+      wholeTime: 0,
+      timeLeft: "",
+      isPaused: false,
+      isStarted: false,
+      displayString: "",
+    };
+  },
+  methods: {
+    changeWholeTime(seconds) {
+      if (this.wholeTime + seconds >= 0) {
+        this.wholeTime += seconds;
+        this.update(this.wholeTime, this.wholeTime);
+      }
+    },
+    changeTime(param) {
+      switch (param) {
+        case "minutes-plus":
+          this.changeWholeTime(1 * 60);
+          break;
+        case "minutes-minus":
+          this.changeWholeTime(-1 * 60);
+          break;
+        case "seconds-plus":
+          this.changeWholeTime(1);
+          break;
+        case "seconds-minus":
+          this.changeWholeTime(-1);
+          break;
+      }
+      this.displayTimeLeft(this.wholeTime);
+    },
+    update(value, timePercent) {
+      this.offset = -this.length - (this.length * value) / timePercent;
+      if (value === 0) {
+        this.pointerTransform = `rotate(${360}deg)`;
+      } else {
+        this.pointerTransform = `rotate(${(360 * value) / timePercent}deg)`;
+      }
+    },
+    displayTimeLeft(timeLeft) {
+      //displays time on the input
+      let minutes = Math.floor(timeLeft / 60);
+      let seconds = timeLeft % 60;
+      this.displayString = `${minutes < 10 ? "0" : ""}${minutes}:${
+        seconds < 10 ? "0" : ""
+      }${seconds}`;
+      // displayOutput.textContent = displayString;
+      this.update(timeLeft, this.wholeTime);
+    },
+    timer(seconds) {
+      //counts time, takes seconds
+      let remainTime = Date.now() + seconds * 1000;
+      this.displayTimeLeft(seconds);
+
+      let _this = this;
+      _this.intervalTimer = setInterval(function () {
+        _this.timeLeft = Math.round((remainTime - Date.now()) / 1000);
+        if (_this.timeLeft < 0) {
+          clearInterval(_this.intervalTimer);
+          _this.isStarted = false;
+          _this.play = false;
+          // setterBtns.forEach(function (btn) {
+          //   btn.disabled = false;
+          //   btn.style.opacity = 1;
+          // });
+          _this.displayTimeLeft(_this.wholeTime);
+          // pauseBtn.classList.remove("pause");
+          // pauseBtn.classList.add("play");
+          return;
+        }
+        _this.displayTimeLeft(_this.timeLeft);
+      }, 1000);
+    },
+    pauseTimer() {
+      if (!this.play && !this.isPaused) {
+        this.play = true;
+        this.isStarted = true;
+        this.timer(this.wholeTime);
+      } else if (this.isPaused) {
+        this.play = true;
+        this.timer(this.timeLeft);
+        this.isStarted = true;
+        this.isPaused = this.isPaused ? false : true;
+      } else {
+        this.play = false;
+        this.isStarted = true;
+        clearInterval(this.intervalTimer);
+        this.isPaused = this.isPaused ? false : true;
+      }
+    },
+    reset() {
+      clearInterval(this.intervalTimer);
+      this.play = false;
+      this.isStarted = false;
+      this.wholeTime = 0;
+      this.update(this.wholeTime, this.wholeTime);
+      this.displayTimeLeft(this.wholeTime);
+    },
+  },
+  created() {
+    this.offset = this.length;
+    this.update(this.wholeTime, this.wholeTime);
+    this.displayTimeLeft(this.wholeTime);
+  },
+  beforeDestroy() {
+    clearInterval(this.intervalTimer);
   },
 };
 </script>
 
-<style></style>
+<style scoped>
+button[data-setter] {
+  outline: none;
+  background: transparent;
+  border: none;
+  font-family: "Roboto";
+  font-weight: 300;
+  font-size: 18px;
+  width: 25px;
+  height: 30px;
+  color: #f7958e;
+  cursor: pointer;
+}
+button[data-setter]:hover {
+  opacity: 0.5;
+}
+.container {
+  position: relative;
+  /* top: 30px; */
+  width: 300px;
+  margin: 0 auto;
+  display: flex;
+  flex-direction: column;
+}
+.setters {
+  position: absolute;
+  left: 85px;
+  top: 75px;
+}
+.minutes-set {
+  float: left;
+  margin-right: 28px;
+}
+.seconds-set {
+  float: right;
+}
+.controlls {
+  position: absolute;
+  left: 75px;
+  top: 105px;
+  text-align: center;
+}
+.display-remain-time {
+  font-family: "Roboto";
+  font-weight: 100;
+  font-size: 65px;
+  color: #f7958e;
+}
+#pause {
+  outline: none;
+  background: transparent;
+  border: none;
+  margin-top: 10px;
+  width: 50px;
+  height: 50px;
+  position: relative;
+}
+.play::before {
+  display: block;
+  content: "";
+  position: absolute;
+  top: 8px;
+  left: 16px;
+  border-top: 15px solid transparent;
+  border-bottom: 15px solid transparent;
+  border-left: 22px solid #f7958e;
+}
+.pause::after {
+  content: "";
+  position: absolute;
+  top: 8px;
+  left: 12px;
+  width: 15px;
+  height: 30px;
+  background-color: transparent;
+  border-radius: 1px;
+  border: 5px solid #f7958e;
+  border-top: none;
+  border-bottom: none;
+}
+#pause:hover {
+  opacity: 0.8;
+}
+.e-c-base {
+  fill: none;
+  stroke: #b6b6b6;
+  stroke-width: 4px;
+}
+.e-c-progress {
+  fill: none;
+  stroke: #f7958e;
+  stroke-width: 4px;
+  transition: stroke-dashoffset 0.7s;
+}
+.e-c-pointer {
+  fill: #fff;
+  stroke: #f7958e;
+  stroke-width: 2px;
+}
+#e-pointer {
+  transition: transform 0.7s;
+}
+</style>