F
F
fessss2018-03-18 12:48:50
JavaScript
fessss, 2018-03-18 12:48:50

Circular countdown timer?

Hello, I'm making a countdown timer on vue
, I made the timer myself, but since I didn't work with svg, I have no idea how to make a circular timer.

<div id="timer">
  <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"
    :width="width" :height="width"
  >
    <circle cx="100" cy="100" :r="100 - border / 2" 
      fill="none"
      opacity="0.4"
      :stroke="color" 
      :stroke-width="border"
    />
    <circle cx="100" cy="100" :r="100 - border / 2" 
      fill="none"
      transform="rotate(270,100,100)" 
      :stroke="color" 
      :stroke-width="border"
      :stroke-dasharray="dashLen" 
      :stroke-dashoffset = "days | myFilter"
      style="transition: stroke-dashoffset 0.4s"
    />
    <text x="100" y="100" text-anchor="middle"
      :font-size="fontSize + 5" 
      :fill="color" 
    >
      {{ days | myFilter }}
    </text>
  </svg>
  <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"
    :width="width" :height="width"
  >
    <circle cx="100" cy="100" :r="100 - border / 2" 
      fill="none"
      opacity="0.4"
      :stroke="color" 
      :stroke-width="border"
    />
    <circle cx="100" cy="100" :r="100 - border / 2" 
      fill="none"
      transform="rotate(270,100,100)" 
      :stroke="color" 
      :stroke-width="border"
      :stroke-dasharray="dashLen" 
      :stroke-dashoffset = "hours | myFilter"
      style="transition: stroke-dashoffset 0.4s"
    />
    <text x="100" y="100" text-anchor="middle"
      :font-size="fontSize + 5" 
      :fill="color" 
    >
      {{ hours | myFilter }}
    </text>
  </svg>
  <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"
    :width="width" :height="width"
  >
    <circle cx="100" cy="100" :r="100 - border / 2" 
      fill="none"
      opacity="0.4"
      :stroke="color" 
      :stroke-width="border"
    />
    <circle cx="100" cy="100" :r="100 - border / 2" 
      fill="none"
      transform="rotate(270,100,100)" 
      :stroke="color" 
      :stroke-width="border"
      :stroke-dasharray="dashLen" 
      :stroke-dashoffset = "minutes | myFilter"
      style="transition: stroke-dashoffset 0.4s"
    />
    <text x="100" y="100" text-anchor="middle"
      :font-size="fontSize + 5" 
      :fill="color" 
    >
      {{ minutes | myFilter }}
    </text>
  </svg>
  <svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"
    :width="width" :height="width"
  >
    <circle cx="100" cy="100" :r="100 - border / 2" 
      fill="none"
      opacity="0.4"
      :stroke="color" 
      :stroke-width="border"
    />
    <circle cx="100" cy="100" :r="100 - border / 2" 
      fill="none"
      transform="rotate(270,100,100)" 
      :stroke="color" 
      :stroke-width="border"
      :stroke-dasharray="dashLen" 
      :stroke-dashoffset = "seconds | myFilter"
      style="transition: stroke-dashoffset 0.4s"
    />
    <text x="100" y="100" text-anchor="middle"
      :font-size="fontSize + 5" 
      :fill="color" 
    >
      {{ seconds | myFilter }}
    </text>
  </svg>
</div>

mounted () {
  window.setInterval(() => {
    this.now = Math.trunc((new Date()).getTime() / 1000)
  }, 1000)
},

props: {
  date: {
    type: String
  },
  width: {
    type: Number,
    default: 80
  },
  border: {
    type: Number,
    default: 8
  },
  color: {
    type: String,
    default: '#fcaa55'
  },
  fontSize: {
    type: Number,
    default: 30
  }
},

data() {
    return {
      now: Math.trunc((new Date()).getTime() / 1000),
      dashLen: (100 - this.border / 2) * Math.PI * 2
    }
},

computed: {
  modifiedDate () {
    return Math.trunc(Date.parse(this.date) / 1000)
  },
  seconds () {
    return (this.modifiedDate - this.now) % 60
  },
  minutes () {
    return Math.trunc((this.modifiedDate - this.now) / 60) % 60
  },
  hours() {
      return Math.trunc((this.modifiedDate - this.now) / 60 / 60) % 24;
  },
  days() {
      return Math.trunc((this.modifiedDate - this.now) / 60 / 60 / 24);
  }
},

filters: {
  myFilter: function (value) {
    if (value.toString().length <= 1) {
      return '0' + value.toString()
    }
    return value.toString()
  }
}

Modified. The timer is working. But the border does not count correctly. Tell

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2018-03-18
@fessss

Probably, instead of sculpting 4 svgs manually, you should have made a separate component that would represent one of the date elements, and created 4 instances of this component - for days, hours, minutes and seconds. Each of the component instances would have its own maximum counter values ​​(365 days a year, 24 hours a day, ...), based on which the stroke-dashoffset values ​​can be calculated independently of the other instances. Somehow so .

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question