I'm making a landing page where a phrase is constantly changing with select words. For instance,
Design better websites
made for clients.
will switch the first or last word to become
Develop better websites
made for clients.
However, since "Develop" is a larger word than "Design", the rest of the text ends up getting pushed around without smoothly transitioning. Keep in mind, this is a multi-line sentence, and it is centered.
var first = ['Create','Design','Develop'];
var second = ['you','clients','artists','us'];
var i = 0;
var j = 0;
var maxfirst = first.length - 1;
var maxsecond = second.length - 1;
function delay() {
$('#intro').velocity("transi1ion.slideUpIn", 1250);
setInterval(firstwordchange, 400);
setInterval(secondwordchange, 500);
}
function firstwordchange() {
if (i < maxfirst) i++; else i = 0;
$('#firstword').velocity("transition.slideUpOut", 300);
setTimeout(function () {
$('#firstword').text(first[i]);
}, 200);
$('#firstword').velocity("transition.slideUpIn", 300);
}
function secondwordchange() {
if (j < maxsecond) j++; else j = 0;
$('#secondword').velocity("transition.slideUpOut", 300);
setTimeout(function () {
$('#secondword').text(second[j]);
}, 200);
$('#secondword').velocity("transition.slideUpIn", 300);
}
setTimeout(delay, 700);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/velocity/1.1.0/velocity.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/velocity/1.1.0/velocity.ui.min.js"></script>
<div id="intro">
<span id="firstword" class="introchange">Create</span>
better websites made for
<span id="secondword" class="introchange">you</span>.
</div>
How can I make the inner, non-changing text transition smoothly?
(actual website here)
I'm going to write an outline of how I would do did it:
visibility: hidden
so that you can determine their sizes.position: relative
on the parent).Demo:
var first = ['Create','Cut','Reticulate'];
var second = ['you','clients','artists','us'];
var firstM = [], secondM = [], el;
var $first = $('.the-first');
var $second = $('.the-second');
var $container = $('#container');
// init static //
$first.text(first[0]);
$second.text(second[0]);
// create measurables //
for(var i = 0; i < first.length; i++){
el = $('<div class="measurable">' + first[i] + '</div>');
$container.append(el);
firstM.push(el.width());
}
for(var i = 0; i < second.length; i++){
el = $('<div class="measurable">' + second[i] + '</div>');
$container.append(el);
secondM.push(el.width());
}
// absolutize //
var positions = [];
$('#container > span').each(function(){
positions.push($(this).position());
});
$('#container > span').each(function(){
var pos = positions.shift();
$(this).css({
position: 'absolute',
left: pos.left,
top: pos.top
});
});
// remember initial sizes //
var firstInitialWidth = $first.width();
var secondInitialWidth = $second.width();
// loop the loop //
var activeWordsIndex = 0;
setInterval(function(){
activeWordsIndex++;
var firstIndex = activeWordsIndex % first.length;
var secondIndex = activeWordsIndex % second.length;
$first.text( first[firstIndex] );
$second.text( second[secondIndex] );
var firstLineOffset = (firstM[firstIndex] - firstInitialWidth) / 2;
var secondLineOffset = (secondM[secondIndex] - secondInitialWidth) / 2;
$('.static.first').css({
transform: 'translateX(' + firstLineOffset + 'px)'
});
$('.static.second').css({
transform: 'translateX(' + (-secondLineOffset) + 'px)'
});
$first.css({
transition: 'none',
transform: 'translate(' + (-firstLineOffset) + 'px, -30px)',
opacity: '0'
});
setTimeout(function(){
$first.css({
transition: 'all 1s ease',
transform: 'translate(' + (-firstLineOffset) + 'px, 0px)',
opacity: '1'
});
}, 50);
$second.css({
transition: 'none',
transform: 'translate(' + (-secondLineOffset) + 'px, 30px)',
opacity: '0'
});
setTimeout(function(){
$second.css({
transition: 'all 1s ease',
transform: 'translate(' + (-secondLineOffset) + 'px, 0px)',
opacity: '1'
});
}, 50);
}, 2000);
#ubercontainer {
border: 1px solid #eaeaea;
border-radius: 2px;
background-color: #ffefc6;
width: 500px;
margin: 20px auto;
padding: 30px 0;
}
#container {
position: relative;
text-align: center;
font-family: sans-serif;
font-size: 32px;
font-weight: 800;
color: #4a6b82;
height: 78px;
}
.measurable {
position: absolute;
visibility: hidden;
}
.static.first, .static.second {
transition: transform 1s ease;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ubercontainer">
<div id="container">
<span class="the-first"></span>
<span class="static first">better websites </span><br />
<span class="static second">made for</span>
<span class="the-second"></span>
</div>
</div>
Writing a solution like this you will quickly come to realize you will have to abandon the idea of dynamic line breaks if your words differ in length by a reasonable amount.
That small detail aside, you can easily achieve the effect you're after using a standard pyramid of jQuery animate callback hell:
var target = $('#target');
var change = function(str) {
var tmp = $('<h1>' + str + '</h1>');
tmp.css({
display: "inline-block",
position: "absolute"
})
.appendTo('body')
.hide();
var targetWidth = tmp.outerWidth();
tmp.remove();
target.animate({
opacity: 0
}, 200, function() {
target.animate({
width: targetWidth
}, 300, function() {
target.empty()
.html(str)
.css({
display: "initial"
})
.animate({
opacity: 1
}, 200);
});
});
}
var samples = [
"some sample",
"another example",
"just"
];
var i = 0;
setInterval(function() {
change(samples[++i % samples.length]);
}, 1400);
.container {
margin: 0 auto;
text-align: center;
}
#target {
display: inline-block;
vertical-align: bottom;
white-space: no-wrap;
height: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h1>This is <span id="target"></span> text</h1>
<h1>in a longer sentence</h1>
</div>
Try using the Web Animation API
Element.animate();
Simplest reference: http://updates.html5rocks.com/2014/05/Web-Animations---element-animate-is-now-in-Chrome-36
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With