Typer JS
String.prototype.rightChars = function(n){
if (n <= 0) {
return "";
}
else if (n > this.length) {
return this;
}
else {
return this.substring(this.length, this.length - n);
}
};
(function($) {
var
options = {
highlightSpeed : 20,
typeSpeed : 100,
clearDelay : 500,
typeDelay : 200,
clearOnHighlight : true,
typerDataAttr : 'data-typer-targets',
typerInterval : 2000,
highlightColor : '#ffffff',
textColor : '#ff3399',
initialDelay : 1000
},
highlight,
clearText,
backspace,
type,
spanWithColor,
clearDelay,
typeDelay,
clearData,
isNumber,
typeWithAttribute,
getHighlightInterval,
getTypeInterval,
typerInterval;
spanWithColor = function(color, backgroundColor) {
if (color === 'rgba(0, 0, 0, 0)') {
color = 'rgb(255, 255, 255)';
}
return $('<span></span>')
.css('color', color)
.css('background-color', backgroundColor);
};
isNumber = function (n) {
return !isNaN(parseFloat(n)) && isFinite(n);
};
clearData = function ($e) {
$e.removeData([
'typePosition',
'highlightPosition',
'leftStop',
'rightStop',
'primaryColor',
'backgroundColor',
'text',
'typing'
]);
};
type = function ($e) {
var
// position = $e.data('typePosition'),
text = $e.data('text'),
oldLeft = $e.data('oldLeft'),
oldRight = $e.data('oldRight');
// if (!isNumber(position)) {
// position = $e.data('leftStop');
// }
if (!text || text.length === 0) {
clearData($e);
return;
}
$e.text(
oldLeft +
text.charAt(0) +
oldRight
).data({
oldLeft: oldLeft + text.charAt(0),
text: text.substring(1)
});
// $e.text($e.text() + text.substring(position, position + 1));
// $e.data('typePosition', position + 1);
setTimeout(function () {
type($e);
}, getTypeInterval());
};
clearText = function ($e) {
$e.find('span').remove();
setTimeout(function () {
type($e);
}, typeDelay());
};
highlight = function ($e) {
var
position = $e.data('highlightPosition'),
leftText,
highlightedText,
rightText;
if (!isNumber(position)) {
position = $e.data('rightStop') + 1;
}
if (position <= $e.data('leftStop')) {
setTimeout(function () {
clearText($e);
}, clearDelay());
return;
}
leftText = $e.text().substring(0, position - 1);
highlightedText = $e.text().substring(position - 1, $e.data('rightStop') + 1);
rightText = $e.text().substring($e.data('rightStop') + 1);
$e.html(leftText)
.append(
spanWithColor(
$e.data('backgroundColor'),
$e.data('primaryColor')
)
.append(highlightedText)
)
.append(rightText);
$e.data('highlightPosition', position - 1);
setTimeout(function () {
return highlight($e);
}, getHighlightInterval());
};
typeWithAttribute = function ($e) {
var targets;
if ($e.data('typing')) {
return;
}
try {
targets = JSON.parse($e.attr($.typer.options.typerDataAttr)).targets;
} catch (e) {}
if (typeof targets === "undefined") {
targets = $.map($e.attr($.typer.options.typerDataAttr).split(','), function (e) {
return $.trim(e);
});
}
$e.typeTo(targets[Math.floor(Math.random()*targets.length)]);
};
// Expose our options to the world.
$.typer = (function () {
return { options: options };
})();
$.extend($.typer, {
options: options
});
//-- Methods to attach to jQuery sets
$.fn.typer = function() {
var $elements = $(this);
return $elements.each(function () {
var $e = $(this);
if (typeof $e.attr($.typer.options.typerDataAttr) === "undefined") {
return;
}
typeWithAttribute($e);
setInterval(function () {
typeWithAttribute($e);
}, typerInterval());
});
};
$.fn.typeTo = function (newString) {
var
$e = $(this),
currentText = $e.text(),
i = 0,
j = 0;
if (currentText === newString) {
console.log("Our strings our equal, nothing to type");
return $e;
}
if (currentText !== $e.html()) {
console.error("Typer does not work on elements with child elements.");
return $e;
}
$e.data('typing', true);
while (currentText.charAt(i) === newString.charAt(i)) {
i++;
}
while (currentText.rightChars(j) === newString.rightChars(j)) {
j++;
}
newString = newString.substring(i, newString.length - j + 1);
$e.data({
oldLeft: currentText.substring(0, i),
oldRight: currentText.rightChars(j - 1),
leftStop: i,
rightStop: currentText.length - j,
primaryColor: $.typer.options.highlightColor || $e.css('color'),
backgroundColor: $.typer.options.textColor || $e.css('background-color'),
text: newString
});
var initDelay = function() {
highlight($e);
return $e;
}
window.setTimeout(initDelay, $.typer.options.initialDelay)
};
//-- Helper methods. These can one day be customized further to include things like ranges of delays.
getHighlightInterval = function () {
return $.typer.options.highlightSpeed;
};
getTypeInterval = function () {
return $.typer.options.typeSpeed;
},
clearDelay = function () {
return $.typer.options.clearDelay;
},
typeDelay = function () {
return $.typer.options.typeDelay;
};
typerInterval = function () {
return $.typer.options.typerInterval;
};
})(jQuery);
(function($) {
$(document).ready(function($) {
$('[data-typer-targets]').typer();
});
})(jQuery);