如何解决如何使用JS为计时器卡设置边框动画
我为正在制作的计时器应用程序配备了以下计时器卡,我希望边框逐渐缠绕,因为它的倒计时类似于此代码笔。 https://codepen.io/Mamboleoo/pen/zYOJOGb 进度必须由JS控制。
我正在将VueJS与Vuetify一起使用,这是我拥有的代码。
<v-col
cols="12"
sm="4"
xs="4" v-for="timer in formattedTimers" :key="timer.id">
<v-card :class="{jiggle : editmode}" max-width="200" class="mx-auto" outlined>
<v-list-item three-line>
<v-list-item-content>
<div class="headline mb-8 text-center">{{ timer.name }}</div>
<v-list-item-title class="headline mb-4 text-center">{{ parseTime(timer.timeLeft) }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-card-actions>
<div v-if="!editmode">
<v-btn @click="zeroTimer(timer.id)" left>Zero</v-btn>
<v-btn color="primary" @click="resetTimer(timer.id)" right absolute>Reset</v-btn>
</div>
<div v-else>
<v-btn color="primary" @click="deleteTimer(timer.id)" left>Delete</v-btn>
</div>
</v-card-actions>
</v-card>
</v-col>
解决方法
您可以直接在所附的the demo in Codepen中使用SVG。
为了使单击border-image
时重新渲染Reset
,一种技巧是在SVG
字符串中添加空白,然后将其转换为base64。
下面是一个简单的代码段:
Vue.component('v-timer',{
render (h) {
return h('div',{
style: {
border: '10px solid black',borderImage: `url("data:image/svg+xml;base64,${this.computedSVGUrl}") 1`
}
},[h('span',{},`${this.inner} Secs`),h('button',{
on: {
click: () => {
this.inner = this.seconds
this.spaces += ' '
this.startTimer(this.seconds)
}
}
},'Reset')])
},props: {
'seconds': {
type: Number,default: 0
}
},data () {
return {
spaces: '',inner: 0,intervalCtrl: null
}
},computed: {
computedSVGUrl: function () {
return window.btoa(`<svg width='100' height='100' viewBox='0 0 100 100' fill='none' xmlns='http://www.w3.org/2000/svg'> <style>path{animation:stroke ${this.seconds}s linear;}@keyframes stroke{to{stroke-dashoffset:388;}}</style><linearGradient id='g' x1='0%' y1='0%' x2='0%' y2='100%'><stop offset='0%' stop-color='#2d3561' /><stop offset='25%' stop-color='#c05c7e' /><stop offset='50%' stop-color='#f3826f' /><stop offset='100%' stop-color='#ffb961' /></linearGradient> <path d='M1.5 1.5 l97 0l0 97l-97 0 l0 -97' stroke-linecap='square' stroke='url(#g)' stroke-width='3' stroke-dasharray='388'/> ${this.spaces} </svg>`)
}
},watch: {
seconds: {
handler: function (newVal) {
this.inner = newVal
this.startTimer(newVal)
},immediate: true
}
},mounted: function () {
this.startTimer(this.seconds)
},methods: {
startTimer: function (seconds) {
this.resetInterval()
this.intervalCtrl = setInterval(() => {
this.inner -= 1
this.inner <= 0 && this.resetInterval()
},1000)
},resetInterval: function () {
this.intervalCtrl && clearInterval(this.intervalCtrl)
this.intervalCtrl = null
}
}
})
new Vue ({
el:'#app'
})
.timer {
width: 200px;
height: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div>
<div>
<v-timer :seconds="5" class="timer"></v-timer>
<v-timer :seconds="10" class="timer"></v-timer>
<v-timer :seconds="15" class="timer"></v-timer>
</div>
</div>
</div>
,
有几种技巧可以制作动画边框。其中之一: 您可以在框内创建四个空的span标签:
<v-card>
<span></span>
<span></span>
<span></span>
<span></span>
</v-card>
它们代表边界。它们应绝对位于卡上。然后,您应该提供一个关键帧无限动画,一个接一个地调整跨度的宽度。所有这些CSS逻辑都应绑定到一个类。然后在您的Vue组件中,根据您的计数器逻辑动态应用此类。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。