Эффект написания письма
Урок в котором будем создавать эффект автоматического написания текста. Но писать будем пером и при высыхании чернил будем окунать его в чернильницу. Также будет эффект эмулирующий написание ошибок, которые будут стираться при написании.
HTML
Наша основная разметка:
<div id="letter"></div>
<img id="inkwell1" src="inkwell1.gif" alt="inkwell1" />
<img id="inkwell2" src="inkwell2.gif" alt="inkwell2" />
<div id="letter_src">
Быть знаменитым некрасиво.<br>
Не это поднимает||||||ымает ввысь.<br>
Не надо начинать||||||||заводить архива,<br>
Над рукописями трясись|||тись.<br>
<br>
Цель творчества - самоотдача,<br>
А не шумиха, не успех.<br>
Позорно, ничего не знача,<br>
Быть притчей на устах у всех.<br>
<br>
Но надо жить без самозванства,<br>
Так жить, чтобы в конце концов<br>
Привлечь к себе любовь просранства|||||||транства,<br>
Услышать будущего зов.<br>
<br>
И надо оставлять пробелы<br>
В судьбе, а не среди бумаг,<br>
Места и главы жизни целой<br>
Отчеркивая на полях.<br>
<br>
И окунаться в неизвестность,<br>
И прятать в ней свои шаги,<br>
Как прячется в тумане местность,<br>
Когда в ней не видать ни зги.<br>
<br>
Другие по живому следу<br>
Пройдут твой путь за пядью пядь,<br>
Но пораженья от победы<br>
Ты сам не должен отличать.<br>
<br>
И должен ни единой долькой<br>
Не отступаться от лица,<br>
Но быть живым, живым и только,<br>
Живым и только до конца.<br>
<br>
Ваш|||Борис Пастернак
</div>
Тут у нас два контейнера letter один выступает в роли источника письма (letter_src) и будет скрыт, а второй это пустой контейнер letter для будущего письма. Так же два блока с изображениями пера и погружением пера в чернильницу.
CSS
body {
background: url('bg.jpg') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
#inkwell1 {
bottom: 100px;
left: 140px;
position: fixed;
}
#inkwell2 {
bottom: 100px;
left: 140px;
position: fixed;
visibility: hidden;
}
#letter {
font-family: Comic Sans MS;
font-size: 18px;
font-weight: bold;
margin: 50px auto;
position: relative;
width: 75%;
}
#letter_src {
display: none;
}
JS
window.onload = function(){
// public variables
var vLetter = document.getElementById('letter');
var iSpeedInk = 5;
// other variables
var sText = document.getElementById('letter_src').innerHTML;
var iCurChar = 0;
var sChars = '<span>';
var iCurInk = 0;
var sCurCaret = '';
var sCaret = " <img src='pen.gif' style='position:absolute' />";
var doStep = function () {
// current char
var sChar = sText.charAt(iCurChar);
// default char delay
var iDelay = 32;
if (sChar == '') {
sCurCaret = '';
} else if (sChar == '|') { // мы используем символ | для эмуляции символа 'ошибки'
sChar = '';
sChars = sChars.substring(0, sChars.length-1);
iDelay = 64;
} else if (sChar == '<') { // pass tags
var iPos = sText.indexOf('>', iCurChar);
sChar = sText.substring(iCurChar, iPos + 1);
iCurChar = iPos;
} else if (sChar == '&') { // pass html entities
var iPos = sText.indexOf(';', iCurChar);
sChar = sText.substring(iCurChar, iPos + 1);
iCurChar = iPos;
} else if (sChar == '.') { // custom delay in case of . symbol
iDelay = 300;
} else if (sChar == ',') { // custom delay in case of , symbol
iDelay = 100;
} else if (sChar == ' ') { // custom delay in case of space symbol
iDelay = 32;
} else if (iCurChar > 5) {
sCurCaret = sCaret;
}
// expenditure of ink
if (sChar == ' ') {
iCurInk += iSpeedInk;
sChar = '</span><span style="color:RGB(' + (iCurInk) + ',' + (iCurInk) + ',' + (iCurInk) + ')">' + sChar;
}
if (document.getElementById('inkwell2').style.visibility == 'visible') {
sCurCaret = sCaret;
document.getElementById('inkwell2').style.visibility = 'hidden';
sChar = '</span><span style="color:RGB(0,0,0)">' + sChar;
}
// refresh Ink
if (iCurInk > 160) {
iCurInk = 0;
document.getElementById('inkwell2').style.visibility = 'visible';
iDelay = 1000;
sCurCaret = '';
}
// add current char to chars
sChars += sChar;
// hide the caret at the end of the letter
if (iCurChar == sText.length - 1)
sCurCaret = '';
// update letter with new chars
vLetter.innerHTML = sChars + sCurCaret;
// goto next char
iCurChar++;
// next step
if (iCurChar < sText.length) {
setTimeout(doStep, 20 + iDelay);
}
}
doStep();
};
Основная идея это отображать постепенно все символы один за другим. В зависимости от текущего символа мы можем установить различные задержки и моделировать ошибки. Для имитации расхода чернил, мы отслеживаем символ пробела, и каждое следующее слово становится светлее предыдущего (градации серого) и в конце концов вызываем эффект окунания пера в чернильницу.