我正在创建一个可重用的模块,该模块创建一个canvas元素并在其中绘制一个圆圈。我目前的结构是这样的。
var circle = (function () {
return {
init: function (el) {
this.el = el
},
start: function () {
}
}
})()
并启动它:
for (var i = links.length - 1; i >= 0; i--) {
circle.init(links[i])
}
我面临的问题是,我传递给模块的每个元素都将覆盖绑定到“ this”的变量。
例如。我为mouseenter添加了事件侦听器,以便在圆角中设置动画效果。 this.canvas将是最后创建的画布的值,而不是我要设置动画的画布的值。
完整代码:https://jsfiddle.net/vnLytr4q/
这个例子说明了一切。只有第一个(或循环中的最后一个)元素可以动画。
答案 0 :(得分:0)
您仅创建一个circle
,并在同一对象上多次调用init
。您需要多次调用该函数。也称为constructor function。
请参阅以下更新的代码:
var circle = function (el) {
return {
init: function () {
this.el = el
this.bounds = 0
this.size = {
x: 0,
y: 0,
radius: 0
}
this.angle = {
start: -0.5,
end: -0.5
}
this.start()
},
start: function () {
this.addListeners()
this.createCanvas()
this.setBounds()
this.draw()
},
addListeners: function () {
this.el.addEventListener('mouseenter', this.onEnter.bind(this))
this.el.addEventListener('mouseleave', this.onLeave.bind(this))
window.addEventListener('resize', this.onResize.bind(this))
},
createCanvas: function () {
this.canvas = document.createElement('canvas')
this.el.appendChild(this.canvas)
this.ctx = this.canvas.getContext('2d')
},
setBounds: function () {
this.bounds = this.el.getBoundingClientRect()
this.canvas.style.height = this.bounds.height + 'px'
this.canvas.style.width = this.bounds.width + 'px'
this.canvas.height = this.bounds.height * 2
this.canvas.width = this.bounds.width * 2
this.size = {
x: this.canvas.width / 2,
y: this.canvas.height / 2,
radius: this.canvas.height / 2
}
},
onEnter: function (e) {
TweenMax.to(this.angle, 1, {
end: 3.5,
start: 1.5,
onUpdate: this.draw.bind(this),
ease: Power2.easeOut
})
},
onLeave: function () {
TweenMax.to(this.angle, 1, {
end: -0.5,
start: -0.5,
onUpdate: this.draw.bind(this),
ease: Power2.easeOut
})
},
onResize: function () {
this.setBounds()
this.draw()
},
draw: function () {
const { x, y, radius } = this.size
const { start, end } = this.angle
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
this.ctx.beginPath()
this.ctx.arc(x, y, radius - 2, 0, 2 * Math.PI)
this.ctx.strokeStyle = 'rgba(255, 255, 255, 0.25)'
this.ctx.lineWidth = 3
this.ctx.stroke()
this.ctx.beginPath()
this.ctx.arc(x, y, radius - 2, start * Math.PI, end * Math.PI)
this.ctx.strokeStyle = '#ffffff'
this.ctx.lineWidth = 3
this.ctx.stroke()
}
}
} // Don't execute the function here
var page = {
init: function () {
// get all links
var links = document.querySelectorAll('.js-button')
for (var i = links.length - 1; i >= 0; i--) {
circle(links[i]).init() // Execute the function whenever you're creating a new circle
}
}
}
page.init()