Magnetism
by ktsn
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<div id="app"></div>
CSS
.wrapper {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.bar-wrapper {
display: flex;
justify-content: center;
align-items: center;
flex: 0 0 40px;
height: 40px;
}
.bar {
height: 10px;
width: 1px;
background-color: #333;
transition: transform 1s linear;
}
.bar.current {
background-color: #f00;
}
JavaScript
function radian(v) {
return Math.atan2(v.y, v.x)
}
const Circle = {
template: `
<div class="wrapper">
<div v-for="(bar, i) in bars" class="bar-wrapper" @mouseenter="onEnter(i)">
<div class="bar" ref="bar" :class="{ current: target === i }" :style="barStyle(bar)"></div>
</div>
</div>
`,
data() {
return {
target: null,
bars: Array.apply(null, Array(200)).map(_ => 0)
}
},
methods: {
barStyle(radian) {
return {
transform: `rotateZ(${radian}rad)`
}
},
onEnter(index) {
this.target = index
this.calcRadian(index)
},
calcRadian(index) {
const res = []
const target = this.$refs.bar[index]
const center = {
x: target.offsetLeft,
y: target.offsetTop
}
for (let i = 0; i < this.bars.length; ++i) {
const el = this.$refs.bar[i]
const pos = {
x: el.offsetLeft,
y: el.offsetTop
}
const v = {
x: center.x - pos.x,
y: center.y - pos.y
}
res.push(radian(v))
}
this.bars = res
}
}
}
new Vue({
el: '#app',
render: h => h(Circle)
})