div#app
app
script#App(type='x/template')
div#App.App
.canv
.small(ref="small")
.big(ref="big")
.shadow(ref="shadow")
View Compiled
#App
.big,
.small
position absolute
bottom 10%
left 50%
width 100px
height 100px
margin-left -50px
margin-top -50px
background #9c27b0
cursor pointer
color white
text-align center
line-height 100px
font-weight bold
border-radius 6px
transform-origin center bottom
will-change transform
backface-visibility hidden
perspective 1000px
transform translateZ(0.0001px)
zoom 1
.small
background #5af158
width 50px
height 50px
margin-left -25px
margin-top -25px
.shadow
position absolute
background-color #dedede
width 140px
height 10px
border-radius 80%
left 50%
bottom calc(10% - 5px)
margin-left -70px
z-index -1
opacity 1
View Compiled
const {
styler,
easing,
keyframes,
parallel,
multicast
} = window.popmotion
const {
createExpoIn,
mirrored,
reversed
} = easing
const customEaseIn = createExpoIn(1)
const customEaseInOut = mirrored(customEaseIn)
Vue.component('app', {
data: () => ({
duration: 1500,
bigStyler: void 0,
smallStyler: void 0,
shadowStyler: void 0,
boxesRotation: multicast(),
}),
template: '#App',
mounted() {
this.bigStyler = styler(this.$refs.big)
this.smallStyler = styler(this.$refs.small)
this.shadowStyler = styler(this.$refs.shadow)
this.boxesRotation.subscribe(v => this.bigStyler.set({ rotate: v[0][1].rot }))
this.boxesRotation.subscribe(v => this.smallStyler.set({ rotate: -v[0][1].rot }))
this.handleJump()
},
methods: {
jump() {
const
move = keyframes({
values: [{
scaleX: 1.5,
scaleY: 0.4,
y: 0
},
{
scaleX: 1,
scaleY: 1,
y: 0
},
{
scaleX: 1,
scaleY: 1,
y: -200
},
{
scaleX: 1,
scaleY: 1,
y: 0
},
{
scaleX: 1.5,
scaleY: 0.4,
y: 0
},
],
duration: this.duration,
times: [0, 0.15, 0.5, 0.85, 1],
easings: [d3.easeCircleIn, d3.easeCircleOut, d3.easeCircleIn, d3.easeCircleOut],
loop: Infinity,
}),
rotate = keyframes({
values: [{
rot: 0
},
{
rot: 0
},
{
rot: -360
},
{
rot: -360
},
],
duration: this.duration,
times: [0, 0.15, 0.85, 1],
easings: [easing.linear, customEaseInOut, easing.linear],
loop: Infinity,
})
return parallel(move, rotate)
},
jumpsmall() {
const
move = keyframes({
values: [{
scaleX: 1.6,
scaleY: 0.4,
y: -40
},
{
scaleX: 1,
scaleY: 1,
y: -100
},
{
scaleX: 1,
scaleY: 1,
y: -400
},
{
scaleX: 1,
scaleY: 1,
y: -100
},
{
scaleX: 1.6,
scaleY: 0.4,
y: -40
},
],
duration: this.duration,
times: [0, 0.15, 0.5, 0.85, 1],
easings: [d3.easeCircleIn, d3.easeCircleOut, d3.easeCircleIn, d3.easeCircleOut],
loop: Infinity,
})
// rotate = keyframes({
// values: [{
// rot: 0
// },
// {
// rot: 0
// },
// {
// rot: 360
// },
// {
// rot: 360
// },
// ],
// duration: this.duration,
// times: [0, 0.15, 0.85, 1],
// easings: [easing.linear, customEaseInOut, easing.linear],
// loop: Infinity,
// })
return parallel(move)
},
animshadow() {
const
scale = keyframes({
values: [{
scale: 1
},
{
scale: 1
},
{
scale: 0.5
},
{
scale: 1
},
{
scale: 1
},
],
duration: this.duration,
times: [0, 0.15, 0.5, 0.85, 1],
easings: [easing.circIn, easing.circOut, easing.circIn, easing.circOut],
loop: Infinity,
})
return scale
},
multijump() {
return parallel(this.jump(), this.jumpsmall(), this.animshadow())
},
addOrigin(v) {
// console.log(v)
v[3] = {
origin: v[0][0].scaleX === 1 ? 'center center' : 'center bottom'
}
return v
},
handleJump() {
this.multijump().pipe(this.addOrigin).start({
update: v => {
this.boxesRotation.update(v)
this.bigStyler.set({
y: v[0][0].y,
scaleX: v[0][0].scaleX,
scaleY: v[0][0].scaleY,
// rotate: v[0][1].rot,
transformOrigin: v[3].origin,
})
this.smallStyler.set({
y: v[1][0].y,
scaleX: v[1][0].scaleX,
scaleY: v[1][0].scaleY,
// rotate: v[1][1].rot,
transformOrigin: v[3].origin,
})
// this.shadowStyler.set({
// scaleX: v[2].scaleX,
// })
this.shadowStyler.set(v[2])
},
// complete: () => console.log('complete triggered'),
})
},
},
})
new Vue({
el: '#app',
data: {},
components: [
app,
],
})
View Compiled
This Pen doesn't use any external CSS resources.