Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// Build a MultiTween with tweens for each keyframe+property
let keyframePropTweens = []
for (let j = 1, len = keyframes.length; j < len; j++) {
let keyframe = keyframes[j]
let props = keyframe.props
for (let prop in props) {
if (props.hasOwnProperty(prop)) {
let prevKeyframe = null
for (let k = j; k--;) {
if (prop in keyframes[k].props) {
prevKeyframe = keyframes[k]
break
}
}
if (prevKeyframe) {
let propTween = new Tween(
this[prop + '➤anim:actuallySet'].bind(this), //callback
prevKeyframe.props[prop], //fromValue
props[prop], //toValue
(keyframe.time - prevKeyframe.time) * duration, //duration
prevKeyframe.time * duration, //delay
'linear', //easing
1, //iterations
'forward', //direction
animDesc.interpolate && animDesc.interpolate[prop] || 'number'
)
propTween.$$property = prop
keyframePropTweens.push(propTween)
}
}
}
}
// If there's no active transition tween, or the new value is different than the active tween's
// target value, initiate a new transition tween. Otherwise ignore it.
let tween = this[activeTweenKey]
let needsNewTween = false
if (tween) {
// Active tween - start new one if new value is different than the old tween's target value
if (value !== tween.toValue) {
runner.stop(tween)
needsNewTween = true
}
} else if (value !== this[propName]) {
// No active tween - only start one if the value is changing
needsNewTween = true
}
if (needsNewTween) {
tween = this[activeTweenKey] = new Tween(
actuallySet.bind(this), //callback
this[propName], //fromValue
value, //toValue
transition.duration || DEFAULT_DURATION, //duration
transition.delay || 0, //delay
transition.easing || DEFAULT_EASING, //easing
1, //iterations
'forward', //direction
transition.interpolate || 'number' //interpolate
)
runner.start(tween)
}
return
}
// No animation or transition will be started; set the value.
afterUpdate() {
// Disable pointer events on the onscreen canvas when in an immersive XR session
this._togglePointerListeners(!this._isImmersive())
super.afterUpdate()
const {xrSession, _threeRenderer:renderer} = this
const prevXrSession = _xrSessions.get(this)
if (xrSession !== prevXrSession) {
_xrSessions.set(this, xrSession)
this.renderingScheduler = xrSession || window
setAnimationScheduler(xrSession || window)
if (xrSession) {
let baseLayer = xrSession.renderState.baseLayer
const gl = renderer.getContext()
// If the session has an existing valid XRWebGLLayer, just grab its framebuffer.
// Otherwise, create a new XRWebGLLayer
if (baseLayer && baseLayer._glContext === gl) {
renderer.setFramebuffer(baseLayer.framebuffer)
} else {
const promise = gl.makeXRCompatible ? gl.makeXRCompatible() : Promise.resolve() //not always implemented?
promise.then(() => {
if (this.xrSession === xrSession) {
baseLayer = new XRWebGLLayer(xrSession, gl, {
antialias: !!renderer.getContextAttributes().antialias
})
baseLayer._glContext = gl
afterUpdate() {
// Disable pointer events on the onscreen canvas when in VR
const vrDisplay = this._isInVR() ? this.vrDisplay : null
this._togglePointerListeners(!vrDisplay)
// Update the animation scheduler
if (vrDisplay !== this._lastVrDisplay) {
this._lastVrDisplay = vrDisplay
this.renderingScheduler = vrDisplay || window
setAnimationScheduler(vrDisplay || window)
}
super.afterUpdate()
}
prevKeyframe.props[prop], //fromValue
props[prop], //toValue
(keyframe.time - prevKeyframe.time) * duration, //duration
prevKeyframe.time * duration, //delay
'linear', //easing
1, //iterations
'forward', //direction
animDesc.interpolate && animDesc.interpolate[prop] || 'number'
)
propTween.$$property = prop
keyframePropTweens.push(propTween)
}
}
}
}
let tween = newAnimTweens[animId] = new MultiTween(keyframePropTweens, duration, delay, easing, iterations, direction)
if (!animDesc.paused) {
runner.start(tween)
}
// The tween runner won't do anything until next tick, so immediately sync to the first frame's
// properties if the animation has no delay to avoid a flash of bad initial state
if (delay === 0) {
let firstKeyframeProps = keyframes[0].props
for (let prop in firstKeyframeProps) {
if (firstKeyframeProps.hasOwnProperty(prop)) {
this[prop + '➤anim:actuallySet'](firstKeyframeProps[prop])
}
}
}
}
constructor(...args) {
super(...args)
// Create root runner for all this object's animation and transition tweens
this.animation$runner = new Runner()
this.animation$runner.onTick = () => {
this.afterUpdate()
this.notifyWorld('needsRender')
}
}