Skip to content

Instantly share code, notes, and snippets.

@scott1028
Last active December 30, 2019 04:29
Show Gist options
  • Save scott1028/f4c66223ade3f4418e2a to your computer and use it in GitHub Desktop.
Save scott1028/f4c66223ade3f4418e2a to your computer and use it in GitHub Desktop.
Howl's Moving Castle

Howl's Moving Castle

This is a tribute to Studio Ghibli's Exhibition in Paris.

While walking through the exhibit, I learned that the castle in howl's moving castle was actually animated with a computer. I was surprised, and inspired to recreate this famous scene using web technologies that I'm familiar with, allowing the user to control the castle's movement.

I ended up biting off more than I could chew, and spending much longer than I had initially intended.

To achieve it, I cut all of the elements out of the film itself using photoshop to crop certain frames. I then inserted all of the elements directly to the DOM (no canvas) and animated them using GSAP and an epic amount of timelines. The legs' walk cycle were by far the most difficult part. I did not use any other software for the animation, just good old sublime text!

All rights go to Studio Ghibli and Joe Hisaishi for the audio.

Forked from Nathan Gordon's Pen Howl's Moving Castle.

A Pen by Captain Anonymous on CodePen.

License.

<audio src="http://cinemont.com/tutorials/howls/in_the_rain.mp3" autoplay loop></audio>
<div class="container">
<img class="background" src="http://cinemont.com/tutorials/howls/background.jpg">
<img class="cloud-bg" src="http://cinemont.com/tutorials/howls/cloud-bg.png">
<img class="cloud-bg2" src="http://cinemont.com/tutorials/howls/cloud-bg.png">
<div class="castle-container">
<div class="castle">
<div class="brleg">
<img class="brfoot" src="http://cinemont.com/tutorials/howls/brfoot.png" />
<img class="brbottom" src="http://cinemont.com/tutorials/howls/brbottom.png" />
</div>
<div class="frleg">
<img class="frfoot" src="http://cinemont.com/tutorials/howls/frfoot.png" />
<img class="frbottom" src="http://cinemont.com/tutorials/howls/frbottom.png" />
</div>
<img class="chimney3" src="http://cinemont.com/tutorials/howls/chimney3.png" />
<img class="treehouse" src="http://cinemont.com/tutorials/howls/treehouse.png" />
<div class="houses-group">
<img class="point6" src="http://cinemont.com/tutorials/howls/point6.png" />
<img class="point5" src="http://cinemont.com/tutorials/howls/point5.png" />
<img class="point4" src="http://cinemont.com/tutorials/howls/point4.png" />
<img class="houses" src="http://cinemont.com/tutorials/howls/houses.png" />
</div>
<img class="chimney2" src="http://cinemont.com/tutorials/howls/chimney2.png" />
<img class="chimney1" src="http://cinemont.com/tutorials/howls/chimney1.png" />
<img class="wing" src="http://cinemont.com/tutorials/howls/wing.png" />
<div class="mound-group">
<img class="antenna" src="http://cinemont.com/tutorials/howls/antenna.png" />
<img class="point3" src="http://cinemont.com/tutorials/howls/point3.png" />
<img class="point2" src="http://cinemont.com/tutorials/howls/point2.png" />
<img class="point1" src="http://cinemont.com/tutorials/howls/point1.png" />
<img class="mound" src="http://cinemont.com/tutorials/howls/mound.png" />
</div>
<img class="wind" src="http://cinemont.com/tutorials/howls/wind.png" />
<img class="cannon" src="http://cinemont.com/tutorials/howls/cannon.png" />
<img class="main" src="http://cinemont.com/tutorials/howls/main.png" />
<div class="blleg">
<div class="blbottom-group">
<img class="blfoot" src="http://cinemont.com/tutorials/howls/flfoot.png" />
<img class="blbottom" src="http://cinemont.com/tutorials/howls/flbottom.png" />
</div>
<img class="bltop" src="http://cinemont.com/tutorials/howls/fltop.png" />
</div>
<img class="blcover" src="http://cinemont.com/tutorials/howls/blcover.png" />
<img class="knob" src="http://cinemont.com/tutorials/howls/knob.png" />
<img class="tele" src="http://cinemont.com/tutorials/howls/tele.png" />
<img class="telecover" src="http://cinemont.com/tutorials/howls/telecover.png" />
<div class="flleg">
<div class="flbottom-group">
<img class="flfoot" src="http://cinemont.com/tutorials/howls/flfoot.png" />
<img class="flbottom" src="http://cinemont.com/tutorials/howls/flbottom.png" />
</div>
<img class="fltop" src="http://cinemont.com/tutorials/howls/fltop.png" />
</div>
<img class="flcover" src="http://cinemont.com/tutorials/howls/flcover.png" />
</div>
</div>
<img class="foreground" src="http://cinemont.com/tutorials/howls/foreground.png">
<div class="clouds">
<img class="cloud-shadow1" src="http://cinemont.com/tutorials/howls/cloud_shadow-1.png">
<img class="cloud-shadow2" src="http://cinemont.com/tutorials/howls/cloud_shadow-1.png">
<img class="cloud-shadow3" src="http://cinemont.com/tutorials/howls/cloud_shadow-1.png">
<img class="cloud1" src="http://cinemont.com/tutorials/howls/cloud-1.png">
<img class="cloud2" src="http://cinemont.com/tutorials/howls/cloud-1.png">
<img class="cloud3" src="http://cinemont.com/tutorials/howls/cloud-2.png">
<img class="cloud4" src="http://cinemont.com/tutorials/howls/cloud-1.png">
<img class="cloud5" src="http://cinemont.com/tutorials/howls/cloud-2.png">
</div>
</div>
<div class="control-toggle">Toggle mouse controls</div>
<div class="load-gate">Loading...</div>
var speed = 0.9;
var WIDTH;
var HEIGHT;
var castleWidth;
var scale;
var control = false;
var progress = 0.0;
var _castleCont = $('.castle-container');
var _castle = $('.castle');
var resize = function() {
WIDTH = window.innerWidth;
HEIGHT = window.innerHeight;
scale = WIDTH / 1440;
castleWidth = _castle.width() * scale;
TweenLite.set(_castle, {scale: scale * 0.85});
};
resize();
$(window).on('resize', resize);
var draw = function() {
requestAnimationFrame(draw);
progress += 0.0012 * speed;
if (progress > 1) progress = 0;
if (progress < 0) progress = 1;
TweenLite.set(_castleCont, {x: (1440 * scale + castleWidth) * -progress + castleWidth / 2, y: 900 * scale * -(0.36 + progress * 0.35)});
};
$(document).on('mousemove', function(e) {
if (!control) return;
speed = (1 - (e.clientX / WIDTH) * 2) * 2;
tl.timeScale(speed);
tl2.timeScale(speed);
tl3.timeScale(speed);
tl4.timeScale(speed);
tl5.timeScale(speed);
});
$('.control-toggle').on('click', function() {
control = !control;
$('.container').toggleClass('active');
});
TweenLite.defaultEase = Power1.easeInOut;
var cloudIntro = function() {
TweenLite.to($('.cloud1'), 20, {x: WIDTH * 2, y: 300 * scale, opacity: 0.3, ease: Linear.easeNone, force3D: true});
TweenLite.to($('.cloud-shadow1'), 20, {x: WIDTH * 2 + 50 * scale, y: 450 * scale, opacity: 0.2, ease: Linear.easeNone, force3D: true});
TweenLite.to($('.cloud-shadow2'), 20, {x: WIDTH * 2 + 50 * scale, y: 450 * scale, ease: Linear.easeNone, force3D: true});
TweenLite.to($('.cloud-shadow3'), 20, {x: WIDTH * 2 + 50 * scale, y: 450 * scale, ease: Linear.easeNone, force3D: true});
TweenLite.to($('.cloud2'), 20, {x: WIDTH * 2, y: 300 * scale, opacity: 0.5, ease: Linear.easeNone, force3D: true});
TweenLite.to($('.cloud3'), 20, {x: WIDTH * 2, y: 300 * scale, ease: Linear.easeNone, force3D: true});
TweenLite.to($('.cloud4'), 20, {x: WIDTH * 2, y: 300 * scale, ease: Linear.easeNone, force3D: true});
TweenLite.to($('.cloud5'), 20, {x: WIDTH * 2, y: 300 * scale, ease: Linear.easeNone, force3D: true, onComplete: function() {
$('.clouds').remove();
}});
};
var init = function() {
TweenLite.to($('.load-gate'), 0.5, {opacity: 0, onComplete: function() {
$('.load-gate').remove();
}});
requestAnimationFrame(draw);
cloudIntro();
};
if (document.readyState == 'complete') {
init();
} else {
$(window).load(init);
};
TweenMax.to($('.cloud-bg'), 40, {x: WIDTH * 2, y: 200 * scale, ease: Linear.easeNone, repeat: -1, force3D: true, onRepeat: function() {
TweenLite.set(this.target[0], {y: Math.random() * 200 - 100, rotationZ: Math.round(Math.random() * 60) - 30, scaleX: Math.random() > 0.5 ? 1 : -1});
}});
TweenMax.to($('.cloud-bg2'), 40, {x: WIDTH * 2, y: 200 * scale, ease: Linear.easeNone, delay: 10, repeat: -1, force3D: true, onRepeat: function() {
TweenLite.set(this.target[0], {y: Math.random() * 200 - 100, rotationZ: Math.round(Math.random() * 60) - 30, scaleX: Math.random() > 0.5 ? 1 : -1});
}});
var tl = new TimelineMax({repeat: -1, onReverseComplete: function() {this.seek(tl.duration())}});
var _flleg = $('.flleg');
var _flbottomGroup = $('.flbottom-group');
var _flfoot = $('.flfoot');
TweenLite.set(_flleg, {rotationZ: 45, x: -5});
TweenLite.set(_flbottomGroup, {rotationZ: 5});
TweenLite.set(_flfoot, {rotationZ: -50});
tl.add([
TweenLite.to(_flleg, 1.0, {rotationZ: -45, delay: 0.0, force3D: true}),
TweenLite.to(_flleg, 0.2, {x: 0, delay: 0.0, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_flleg, 0.55, {scaleY: 0.8, delay: 0.0, force3D: true}),
TweenLite.to(_flbottomGroup, 0.55, {scaleY: 0.8, delay: 0.0, force3D: true}),
TweenLite.to(_flbottomGroup, 0.6, {rotationZ: 20, delay: 0.0, ease: Power3.easeIn, force3D: true}),
TweenLite.to(_flfoot, 0.55, {scaleY: 1.5, delay: 0.0, force3D: true}),
TweenLite.to(_flfoot, 0.6, {rotationZ: 10, delay: 0.0, ease: Power2.easeIn, force3D: true}),
TweenLite.to(_flleg, 0.4, {scaleY: 1.0, delay: 0.6, force3D: true}),
TweenLite.to(_flbottomGroup, 0.4, {scaleY: 0.7, delay: 0.6, force3D: true}),
TweenLite.to(_flbottomGroup, 0.4, {rotationZ: 50, delay: 0.6, force3D: true}),
TweenLite.to(_flfoot, 0.2, {rotationZ: 10, delay: 0.6, ease: Linear.easeNone, force3D: true}),
TweenLite.to(_flfoot, 0.2, {rotationZ: -10, delay: 0.8, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_flfoot, 0.4, {scaleY: 1.5, delay: 0.6, force3D: true}),
TweenLite.to(_flleg, 0.6, {x: 20, delay: 0.7, force3D: true}),
TweenLite.to(_flleg, 0.5, {rotationZ: 0, delay: 1.0, ease: Power1.easeIn, force3D: true}),
TweenLite.to(_flleg, 0.5, {scaleY: 0.8, delay: 1.0, force3D: true}),
TweenLite.to(_flbottomGroup, 0.5, {scaleY: 0.5, delay: 1.0, force3D: true}),
TweenLite.to(_flfoot, 0.5, {scaleX: 1.8, scaleY: 1.7, delay: 1.0, ease: Power1.easeIn, force3D: true}),
TweenLite.to(_flbottomGroup, 0.5, {rotationZ: 40, delay: 1.0, force3D: true}),
TweenLite.to(_flfoot, 0.5, {rotationZ: -70, delay: 1.0, force3D: true}),
TweenLite.to(_flleg, 0.5, {rotationZ: 45, delay: 1.5, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_flleg, 0.5, {scaleY: 1.0, delay: 1.5, force3D: true}),
TweenLite.to(_flbottomGroup, 0.5, {scaleY: 1.0, delay: 1.5, force3D: true}),
TweenLite.to(_flbottomGroup, 0.5, {rotationZ: 5, delay: 1.5, force3D: true}),
TweenLite.to(_flfoot, 0.5, {rotationZ: -50, delay: 1.5, force3D: true}),
TweenLite.to(_flfoot, 0.5, {scaleX: 1.0, scaleY: 1.0, delay: 1.5, force3D: true}),
TweenLite.to(_flleg, 0.5, {x: -10, delay: 1.3, force3D: true}),
TweenLite.to(_flleg, 0.2, {x: -5, delay: 1.8, ease: Power1.easeIn, force3D: true}),
]);
var tl2 = new TimelineMax({repeat: -1, delay: 0.7, onReverseComplete: function() {this.seek(tl2.duration())}});
var _blleg = $('.blleg');
var _blbottomGroup = $('.blbottom-group');
var _blfoot = $('.blfoot');
TweenLite.set(_blleg, {rotationZ: 45, x: -5});
TweenLite.set(_blbottomGroup, {rotationZ: 5});
TweenLite.set(_blfoot, {rotationZ: -50});
tl2.add([
TweenLite.to(_blleg, 1.0, {rotationZ: -45, delay: 0.0, force3D: true}),
TweenLite.to(_blleg, 0.2, {x: 0, delay: 0.0, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_blleg, 0.55, {scaleY: 0.8, delay: 0.0, force3D: true}),
TweenLite.to(_blbottomGroup, 0.55, {scaleY: 0.8, delay: 0.0, force3D: true}),
TweenLite.to(_blbottomGroup, 0.6, {rotationZ: 20, delay: 0.0, ease: Power3.easeIn, force3D: true}),
TweenLite.to(_blfoot, 0.55, {scaleY: 1.5, delay: 0.0, force3D: true}),
TweenLite.to(_blfoot, 0.6, {rotationZ: 10, delay: 0.0, ease: Power2.easeIn, force3D: true}),
TweenLite.to(_blleg, 0.4, {scaleY: 1.0, delay: 0.6, force3D: true}),
TweenLite.to(_blbottomGroup, 0.4, {scaleY: 0.7, delay: 0.6, force3D: true}),
TweenLite.to(_blbottomGroup, 0.4, {rotationZ: 50, delay: 0.6, force3D: true}),
TweenLite.to(_blfoot, 0.2, {rotationZ: 10, delay: 0.6, ease: Linear.easeNone, force3D: true}),
TweenLite.to(_blfoot, 0.2, {rotationZ: -10, delay: 0.8, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_blfoot, 0.4, {scaleY: 1.5, delay: 0.6, force3D: true}),
TweenLite.to(_blleg, 0.6, {x: 20, delay: 0.7, force3D: true}),
TweenLite.to(_blleg, 0.5, {rotationZ: 0, delay: 1.0, ease: Power1.easeIn, force3D: true}),
TweenLite.to(_blleg, 0.5, {scaleY: 0.8, delay: 1.0, force3D: true}),
TweenLite.to(_blbottomGroup, 0.5, {scaleY: 0.5, delay: 1.0, force3D: true}),
TweenLite.to(_blfoot, 0.5, {scaleX: 1.8, scaleY: 1.7, delay: 1.0, ease: Power1.easeIn, force3D: true}),
TweenLite.to(_blbottomGroup, 0.5, {rotationZ: 40, delay: 1.0, force3D: true}),
TweenLite.to(_blfoot, 0.5, {rotationZ: -70, delay: 1.0, force3D: true}),
TweenLite.to(_blleg, 0.5, {rotationZ: 45, delay: 1.5, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_blleg, 0.5, {scaleY: 1.0, delay: 1.5, force3D: true}),
TweenLite.to(_blbottomGroup, 0.5, {scaleY: 1.0, delay: 1.5, force3D: true}),
TweenLite.to(_blbottomGroup, 0.5, {rotationZ: 5, delay: 1.5, force3D: true}),
TweenLite.to(_blfoot, 0.5, {rotationZ: -50, delay: 1.5, force3D: true}),
TweenLite.to(_blfoot, 0.5, {scaleX: 1.0, scaleY: 1.0, delay: 1.5, force3D: true}),
TweenLite.to(_blleg, 0.5, {x: -10, delay: 1.3, force3D: true}),
TweenLite.to(_blleg, 0.2, {x: -5, delay: 1.8, ease: Power1.easeIn, force3D: true}),
]);
var tl3 = new TimelineMax({repeat: -1, delay: 1.0, onReverseComplete: function() {this.seek(tl3.duration())}});
var _frleg = $('.frleg');
var _frfoot = $('.frfoot');
TweenLite.set(_frleg, {rotationZ: 35, x: -40});
TweenLite.set(_frfoot, {rotationZ: -35});
tl3.add([
TweenLite.to(_frleg, 0.9, {rotationZ: -35, delay: 0.0, force3D: true}),
TweenLite.to(_frleg, 1.2, {x: 40, delay: 0.0, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_frfoot, 0.9, {rotationZ: 35, delay: 0.0, force3D: true}),
TweenLite.to(_frleg, 0.4, {y: -15, delay: 0.0, ease: Power1.easeIn, force3D: true}),
TweenLite.to(_frleg, 0.4, {y: 0, delay: 0.5, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_frleg, 1.1, {rotationZ: 35, delay: 0.9, force3D: true}),
TweenLite.to(_frleg, 0.6, {x: -50, delay: 1.2, force3D: true}),
TweenLite.to(_frfoot, 0.5, {rotationZ: -50, delay: 0.9, force3D: true}),
TweenLite.to(_frfoot, 0.3, {rotationZ: -35, delay: 1.7, force3D: true}),
TweenLite.to(_frleg, 0.6, {y: -40, delay: 0.9, force3D: true}),
TweenLite.to(_frleg, 0.5, {y: 0, delay: 1.5, force3D: true}),
TweenLite.to(_frleg, 0.2, {x: -40, delay: 1.8, ease: Power1.easeIn, force3D: true}),
]);
var tl4 = new TimelineMax({repeat: -1, delay: 1.7, onReverseComplete: function() {this.seek(tl4.duration())}});
var _brleg = $('.brleg');
var _brfoot = $('.brfoot');
TweenLite.set(_brleg, {rotationZ: 35, x: -40});
TweenLite.set(_brfoot, {rotationZ: -35});
tl4.add([
TweenLite.to(_brleg, 0.9, {rotationZ: -35, delay: 0.0, force3D: true}),
TweenLite.to(_brleg, 1.2, {x: 40, delay: 0.0, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_brfoot, 0.9, {rotationZ: 35, delay: 0.0, force3D: true}),
TweenLite.to(_brleg, 0.4, {y: -15, delay: 0.0, ease: Power1.easeIn, force3D: true}),
TweenLite.to(_brleg, 0.4, {y: 0, delay: 0.5, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_brleg, 1.1, {rotationZ: 35, delay: 0.9, force3D: true}),
TweenLite.to(_brleg, 0.6, {x: -50, delay: 1.2, force3D: true}),
TweenLite.to(_brfoot, 0.5, {rotationZ: -50, delay: 0.9, force3D: true}),
TweenLite.to(_brfoot, 0.3, {rotationZ: -35, delay: 1.7, force3D: true}),
TweenLite.to(_brleg, 0.6, {y: -40, delay: 0.9, force3D: true}),
TweenLite.to(_brleg, 0.5, {y: 0, delay: 1.5, force3D: true}),
TweenLite.to(_brleg, 0.2, {x: -40, delay: 1.8, ease: Power1.easeIn, force3D: true}),
]);
var tl5 = new TimelineMax({repeat: -1, delay: 0.0, onReverseComplete: function() {this.seek(tl5.duration())}});
var _castle = $('.castle');
TweenLite.set(_castle, {rotationZ: 9});
tl5.add([
TweenLite.to(_castle, 1.0, {rotationZ: 7, delay: 0.0, force3D: true}),
TweenLite.to(_castle, 1.0, {rotationZ: 9, delay: 1.0, force3D: true}),
TweenLite.to(_castle, 0.5, {x: '+=' + 2 * scale, y: '-=' + 4 * scale, delay: 0.0, force3D: true}),
TweenLite.to(_castle, 0.5, {x: '-=' + 4 * scale, y: '+=' + 4 * scale, delay: 0.5, force3D: true}),
TweenLite.to(_castle, 0.5, {x: '+=' + 4 * scale, y: '-=' + 5 * scale, delay: 1.0, force3D: true}),
TweenLite.to(_castle, 0.5, {x: '-=' + 2 * scale, y: '+=' + 5 * scale, delay: 1.5, force3D: true}),
]);
var tl6 = new TimelineMax({repeat: -1, delay: 0.2});
var _mound = $('.mound-group');
TweenLite.set(_mound, {rotationZ: 2});
tl6.add([
TweenLite.to(_mound, 1.0, {rotationZ: -1, delay: 0.0, force3D: true}),
TweenLite.to(_mound, 1.0, {rotationZ: 2, delay: 1.0, force3D: true}),
]);
var tl7 = new TimelineMax({repeat: -1, delay: 0.8});
var _wing = $('.wing');
TweenLite.set(_wing, {rotationZ: 2});
tl7.add([
TweenLite.to(_wing, 1.0, {rotationZ: -1, x: -5, delay: 0.0, force3D: true}),
TweenLite.to(_wing, 1.0, {rotationZ: 2, x: 0, delay: 1.0, force3D: true}),
]);
var tl8 = new TimelineMax({repeat: -1, delay: 0.0});
var _chimney1 = $('.chimney1');
TweenLite.set(_chimney1, {rotationZ: -10});
tl8.add([
TweenLite.to(_chimney1, 1.5, {rotationZ: 5, delay: 0.0, force3D: true}),
TweenLite.to(_chimney1, 1.5, {rotationZ: -10, delay: 1.5, force3D: true}),
TweenLite.to(_chimney1, 0.5, {y: 5, x: 0, delay: 0.1, force3D: true}),
TweenLite.to(_chimney1, 0.1, {y: -15, x: 4, delay: 0.6, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_chimney1, 0.9, {y: 0, x: 0, delay: 0.7, force3D: true}),
TweenLite.to(_chimney1, 0.5, {y: 5, x: 0, delay: 1.6, force3D: true}),
TweenLite.to(_chimney1, 0.1, {y: -15, x: 4, delay: 2.1, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_chimney1, 0.5, {y: 0, x: 0, delay: 2.2, force3D: true}),
]);
var tl9 = new TimelineMax({repeat: -1, delay: 0.5});
var _chimney2 = $('.chimney2');
TweenLite.set(_chimney2, {rotationZ: -10});
tl9.add([
TweenLite.to(_chimney2, 1.5, {rotationZ: 5, delay: 0.0, force3D: true}),
TweenLite.to(_chimney2, 1.5, {rotationZ: -10, delay: 1.5, force3D: true}),
TweenLite.to(_chimney2, 0.5, {y: 5, x: 0, delay: 0.1, force3D: true}),
TweenLite.to(_chimney2, 0.1, {y: -15, x: 4, delay: 0.6, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_chimney2, 0.9, {y: 0, x: 0, delay: 0.7, force3D: true}),
TweenLite.to(_chimney2, 0.5, {y: 5, x: 0, delay: 1.6, force3D: true}),
TweenLite.to(_chimney2, 0.1, {y: -15, x: 4, delay: 2.1, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_chimney2, 0.5, {y: 0, x: 0, delay: 2.2, force3D: true}),
]);
var tl10 = new TimelineMax({repeat: -1, delay: 1.1});
var _chimney3 = $('.chimney3');
TweenLite.set(_chimney3, {rotationZ: -10});
tl10.add([
TweenLite.to(_chimney3, 1.5, {rotationZ: 5, delay: 0.0, force3D: true}),
TweenLite.to(_chimney3, 1.5, {rotationZ: -10, delay: 1.5, force3D: true}),
TweenLite.to(_chimney3, 0.5, {y: 5, x: 0, delay: 0.1, force3D: true}),
TweenLite.to(_chimney3, 0.1, {y: -15, x: 4, delay: 0.6, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_chimney3, 0.9, {y: 0, x: 0, delay: 0.7, force3D: true}),
TweenLite.to(_chimney3, 0.5, {y: 5, x: 0, delay: 1.6, force3D: true}),
TweenLite.to(_chimney3, 0.1, {y: -15, x: 4, delay: 2.1, ease: Power1.easeOut, force3D: true}),
TweenLite.to(_chimney3, 0.5, {y: 0, x: 0, delay: 2.2, force3D: true}),
]);
var tl11 = new TimelineMax({repeat: -1, delay: 0.5});
var _houses = $('.houses-group');
var _point1 = $('.point1');
var _point2 = $('.point2');
TweenLite.set(_houses, {rotationZ: 2, x: -4});
TweenLite.set(_point1, {rotationZ: 2, x: -2});
tl11.add([
TweenLite.to(_houses, 1.0, {rotationZ: -1, y: 5, x: 0, delay: 0.0, force3D: true}),
TweenLite.to(_houses, 1.0, {rotationZ: 2, y: 0, x: -4, delay: 1.0, force3D: true}),
TweenLite.to(_point1, 1.0, {rotationZ: -10, y: 2, x: 0, delay: 0.0, force3D: true}),
TweenLite.to(_point1, 1.0, {rotationZ: 2, y: 0, x: -2, delay: 1.0, force3D: true}),
TweenLite.to(_point2, 1.0, {rotationZ: -5, y: 5, x: 2, delay: 0.0, force3D: true}),
TweenLite.to(_point2, 1.0, {rotationZ: 0, y: 0, x: 0, delay: 1.0, force3D: true}),
]);
var tl12 = new TimelineMax({repeat: -1, delay: 0.45});
var _point4 = $('.point4');
var _point5 = $('.point5');
var _point6 = $('.point6');
tl12.add([
TweenLite.to(_point6, 0.3, {y: 3, delay: 0.0, force3D: true}),
TweenLite.to(_point6, 0.1, {y: -10, x: 4, delay: 0.3, force3D: true}),
TweenLite.to(_point6, 0.9, {y: 0, x: 0, delay: 0.4, force3D: true}),
TweenLite.to(_point5, 0.3, {y: 3, delay: 0.2, force3D: true}),
TweenLite.to(_point5, 0.1, {y: -7, x: 3, delay: 0.5, force3D: true}),
TweenLite.to(_point5, 0.7, {y: 0, x: 0, delay: 0.6, force3D: true}),
TweenLite.to(_point4, 0.3, {y: 3, delay: 0.4, force3D: true}),
TweenLite.to(_point4, 0.1, {y: -10, x: 4, delay: 0.7, force3D: true}),
TweenLite.to(_point4, 0.7, {y: 0, x: 0, delay: 0.8, force3D: true}),
]);
var tl13 = new TimelineMax({repeat: -1, delay: 1.4});
var _treehouse = $('.treehouse');
TweenLite.set(_treehouse, {rotationZ: -5, y: 20, x: 4});
tl13.add([
TweenLite.to(_treehouse, 1.0, {rotationZ: 10, delay: 0.0, force3D: true}),
TweenLite.to(_treehouse, 1.0, {rotationZ: -5, delay: 1.0, force3D: true}),
TweenLite.to(_treehouse, 1.0, {rotationZ: 10, delay: 2.0, force3D: true}),
TweenLite.to(_treehouse, 1.0, {rotationZ: -5, delay: 3.0, force3D: true}),
TweenLite.to(_treehouse, 0.4, {y: -5, x: -2, delay: 0.2, force3D: true}),
TweenLite.to(_treehouse, 3.2, {y: 20, x: 4, delay: 0.8, force3D: true}),
]);
var tl14 = new TimelineMax({repeat: -1, delay: 0.65});
var _wind = $('.wind');
var _antenna = $('.antenna');
var _cannon = $('.cannon');
var _tele = $('.tele');
var _knob = $('.knob');
TweenLite.set(_antenna, {rotationZ: 10, x: 0});
TweenLite.set(_wind, {rotationZ: -10, x: 0});
TweenLite.set(_knob, {rotationZ: -20, x: 0});
tl14.add([
TweenLite.to(_antenna, 1.0, {rotationZ: -5, x: 0, delay: 0.0, force3D: true}),
TweenLite.to(_antenna, 1.0, {rotationZ: 10, x: 5, delay: 1.0, force3D: true}),
TweenLite.to(_antenna, 1.0, {rotationZ: -10, x: -5, delay: 2.0, force3D: true}),
TweenLite.to(_antenna, 1.0, {rotationZ: 10, x: 0, delay: 3.0, force3D: true}),
TweenLite.to(_wind, 1.1, {rotationZ: 5, delay: 0.0, force3D: true}),
TweenLite.to(_wind, 1.0, {rotationZ: -15, delay: 1.1, force3D: true}),
TweenLite.to(_wind, 1.0, {rotationZ: 10, delay: 2.1, force3D: true}),
TweenLite.to(_wind, 0.9, {rotationZ: -10, delay: 3.1, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: 50, delay: 0.0, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: -20, delay: 0.3, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: 45, delay: 0.7, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: -25, delay: 1.0, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: 30, delay: 1.5, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: 0, delay: 1.9, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: -20, delay: 2.2, force3D: true}),
TweenLite.to(_knob, 0.3, {rotationZ: 60, delay: 2.6, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: -10, delay: 3.0, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: 40, delay: 3.4, force3D: true}),
TweenLite.to(_knob, 0.2, {rotationZ: -20, delay: 3.7, force3D: true}),
TweenLite.to(_tele, 1.0, {rotationZ: -3, delay: 0.0, force3D: true}),
TweenLite.to(_tele, 1.0, {rotationZ: 2, delay: 1.0, force3D: true}),
TweenLite.to(_tele, 1.0, {rotationZ: -3, delay: 2.0, force3D: true}),
TweenLite.to(_tele, 1.0, {rotationZ: 0, delay: 3.0, force3D: true}),
TweenLite.to(_tele, 0.25, {x: 25, y: 4, delay: 0.6, force3D: true}),
TweenLite.to(_tele, 2.5, {x: 0, y: 0, delay: 0.9, force3D: true}),
TweenLite.to(_cannon, 0.9, {rotationZ: -7, delay: 0.0, force3D: true}),
TweenLite.to(_cannon, 0.9, {rotationZ: 2, delay: 0.9, force3D: true}),
TweenLite.to(_cannon, 1.1, {rotationZ: -5, delay: 1.8, force3D: true}),
TweenLite.to(_cannon, 1.1, {rotationZ: 0, delay: 2.9, force3D: true}),
TweenLite.to(_cannon, 0.25, {x: 30, y: 4, delay: 0.85, force3D: true}),
TweenLite.to(_cannon, 2.6, {x: 0, y: 0, delay: 1.4, force3D: true}),
]);
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.14.2/TweenMax.min.js"></script>
html, body { height: 100%; margin: 0; background: #2294b3; overflow: hidden; }
.container { padding-top: 62.5%; position: absolute; width: 100%; bottom: 0; left: 0; }
.container.active { cursor: ew-resize; }
img,
.mound-group,
.houses-group,
.flbottom-group,
.blbottom-group,
.brleg,
.frleg,
.blleg,
.flleg { position: absolute; transform-style: preserve-3d; }
.castle-container { position: absolute; left: 100%; bottom: 0%; }
.castle { position: absolute; top: 0; left: 0; width: 600px; height: 750px; perspective: 1000px; transform-origin: 50% 70%; transform: translate(-50%, -70%) rotateZ(9deg); }
.brleg { left: 400px; top: 625px; transform-origin: 10px -10px; transform: rotateZ(0deg); }
.brfoot { left: -18px; top: 82px; transform-origin: 56% 44%; transform: rotateZ(0deg); }
.brbottom { }
.frleg { left: 240px; top: 653px; transform-origin: 8px -10px; transform: rotateZ(0deg); }
.frfoot { left: -18px; top: 51px; transform-origin: 56% 44%; transform: rotateZ(0deg); }
.frbottom { }
.chimney3 { left: 400px; top: 30px; transform-origin: 45% 120%; transform: rotateZ(0deg); }
.houses-group { left: 305px; top: 130px; transform-origin: -50px 300px; transform: rotateZ(1deg); }
.point6 { left: 84px; top: 19px; transform-origin: 40% 120%; transform: rotateZ(0deg); }
.point5 { left: 70px; top: -23px; transform-origin: -40% 200%; transform: rotateZ(0deg); }
.point4 { left: 40px; top: -17px; transform-origin: 0% 100%; transform: rotateZ(0deg); }
.houses { }
.treehouse { left: 220px; top: 10px; transform-origin: 50% 150%; transform: rotateZ(0deg); }
.chimney2 { left: 430px; top: 120px; transform-origin: 0% 90%; transform: rotateZ(0deg); }
.chimney1 { left: 420px; top: 90px; transform-origin: -10% 90%; transform: rotateZ(0deg); }
.wing { left: 420px; top: 370px; transform-origin: 0% 50%; transform: rotateZ(0deg); }
.antenna { left: -100px; top: 90px; transform-origin: 100% 65%; transform: rotateZ(0deg); }
.mound-group { left: 115px; top: 110px; transform-origin: 110px 220px; transform: rotateZ(0deg); }
.point3 { left: 125px; top: -13px; transform-origin: 50% 400%; transform: rotateZ(0deg); }
.point2 { left: 50px; top: -22px; transform-origin: 120% 200%; transform: rotateZ(0deg); }
.point1 { left: 4px; top: 55px; transform-origin: 150% 150%; transform: rotateZ(0deg); }
.mound { }
.wind { left: 400px; top: 260px; transform-origin: 0% 90%; transform: rotateZ(0deg); }
.cannon { left: 30px; top: 460px; transform-origin: 100% 60%; transform: rotateZ(0deg); }
.main { left: 80px; top: 230px; transform-origin: 50% 50%; transform: rotateZ(0deg); }
.blleg { left: 410px; top: 615px; transform-origin: 10px 15px; transform: rotateZ(0deg); }
.blbottom-group { left: 0px; top: 60px; transform-origin: 10px 0px; transform: rotateZ(0deg); }
.blfoot { left: -19px; top: 68px; transform-origin: 56% 44%; transform: rotateZ(0deg); }
.blbottom { }
.bltop { }
.blcover { left: 360px; top: 573px; }
.knob { left: 214px; top: 524px; transform-origin: 30% 63%; transform: rotateZ(0deg); }
.tele { left: 90px; top: 430px; transform-origin: 90% 50%; transform: rotateZ(0deg); }
.telecover { left: 161px; top: 399px; }
.flleg { left: 250px; top: 615px; transform-origin: 10px 15px; transform: rotateZ(0deg); }
.flbottom-group { left: 0px; top: 60px; transform-origin: 10px 0px; transform: rotateZ(0deg); }
.flfoot { left: -19px; top: 68px; transform-origin: 56% 44%; transform: rotateZ(0deg); }
.flbottom { }
.fltop { }
.flcover { left: 244px; top: 567px; }
.foreground { position: absolute; bottom: 0; left: 0; width: 100%; }
.background { position: absolute; bottom: 25.5%; left: 0; width: 100%; }
.cloud-bg { bottom: 17%; width: 80%; right: 100%;}
.cloud-bg2 { bottom: 17%; width: 80%; right: 100%; }
.cloud-shadow1 { bottom: 43%; right: 100%; width: 80%; transform: rotate(5deg); }
.cloud1 { bottom: 30%; right: 100%; width: 80%; }
.cloud-shadow2 { bottom: 12%; left: 36%; width: 80%; transform: rotate(5deg); }
.cloud-shadow3 { bottom: 31%; left: -30%; width: 80%; transform: rotate(5deg); }
.cloud2 { bottom: 46%; left: -29%; width: 80%; }
.cloud3 { bottom: 38%; left: 17%; width: 80%; }
.cloud4 { bottom: 18%; left: -18%; width: 80%; }
.cloud5 { bottom: 8%; left: 40%; width: 80%; }
.control-toggle { position: absolute; top: 0; left: 0; padding: 10px 20px; background: rgba(255,255,255,1); font-family: sans-serif; text-transform: uppercase; font-size: 10px; letter-spacing: 0.05em; opacity: 0.1; cursor: pointer; }
.control-toggle:hover { opacity: 1.0;}
.load-gate { position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: #fff; font-family: sans-serif; text-transform: uppercase; font-size: 10px; letter-spacing: 0.2em; padding: 20px; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment