Чистый CSS Подход ниже *. Тем не менее, вы должны немного изменить свой HTML, чтобы освободить место для заполнителя Secondary text TextNode
. С помощью заполнителя мы можем получить text-align
, чтобы не изменять положение Initial text
. Затем мы просто изменяем реальный элемент, который анимируется, набирая JS (который был абсолютно позиционирован из контейнера, который содержит и заполнитель, и реальный элемент).
Я изменил ваш HTML немного структурировать и добавить несколько строк CSS:
// ES6 Class
class TypeWriter {
constructor(txtElement, words, wait = 3000) {
this.txtElement = txtElement;
this.words = words;
this.txt = '';
this.wordIndex = 0;
this.wait = parseInt(wait, 10);
this.type();
this.isDeleting = false;
}
type() {
// Current index of word
const current = this.wordIndex % this.words.length;
// Get full text of current word
const fullTxt = this.words[current];
// Check if deleting
if(this.isDeleting) {
// Remove char
this.txt = fullTxt.substring(0, this.txt.length - 1);
} else {
// Add char
this.txt = fullTxt.substring(0, this.txt.length + 1);
}
// Insert txt into element
this.txtElement.innerHTML = `<span class="txt">${this.txt}</span>`;
// Initial Type Speed
let typeSpeed = 300;
if(this.isDeleting) {
typeSpeed /= 2;
}
// If word is complete
if(!this.isDeleting && this.txt === fullTxt) {
// Make pause at end
typeSpeed = this.wait;
// Set delete to true
this.isDeleting = true;
} else if(this.isDeleting && this.txt === '') {
this.isDeleting = false;
// Move to next word
this.wordIndex++;
// Pause before start typing
typeSpeed = 500;
}
setTimeout(() => this.type(), typeSpeed);
}
}
// Init On DOM Load
document.addEventListener('DOMContentLoaded', init);
// Init App
function init() {
const txtElement = document.querySelector('.txt-type');
const words = JSON.parse(txtElement.getAttribute('data-words'));
const wait = txtElement.getAttribute('data-wait');
// Init TypeWriter
new TypeWriter(txtElement, words, wait);
}
@import url('https://fonts.googleapis.com/css?family=Raleway:200,100,400');
body {
font-family: 'Raleway', sans-serif;
height: 100vh;
background: #333 url('https://image.ibb.co/n5A2HU/showcase.jpg') no-repeat center center / cover;
color: #ccc;
overflow:hidden;
}
/* =============== */
/* Add starts here */
/* =============== */
.container-type {
position: relative;
}
.txt-type-placeholder {
opacity: 0;
}
.txt-type {
position: absolute;
left: 0;
top: 0;
}
/* =============== */
/* Add ends here */
/* =============== */
.container {
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
padding: 0 3rem;
}
h1, h2 {
font-weight: 200;
margin: 0.4rem;
}
h1 {
font-size: 3.5rem;
}
h2 {
font-size: 2rem;
color: #aaa;
}
/* Cursor */
.txt-type > .txt {
border-right: 0.2rem solid #777;
}
.align-self-baseline {
align-self: baseline!important
}
@media(min-width: 1200px) {
h1 {
font-size: 5rem;
}
}
@media(max-width: 800px) {
.container {
padding: 0 1rem;
}
h1 {
font-size: 3rem;
}
}
@media(max-width: 500px) {
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 1.5rem;
}
}
.text-center {
text-align: center !important
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Welcome To My Site</title>
</head>
<body>
<div class="container">
<h3 class="text-center">
Initial text,
<!-- Changed here -->
<span class="container-type">
<span class="txt-type-placeholder">Secondary text</span>
<span class="txt-type" data-wait="1000" data-words='["Secondary text"]'></span>
</span>
<!-- End of change -->
</h3>
</div>
<script src="main.js"></script>
</body>
</html>
* При условии, что текст всегда состоит только из одной строки, вышеприведенный подход прекрасно работает. Однако если есть вероятность, что текст занимает более одной строки, измените код так, чтобы вы создали заполнитель таким образом, чтобы он был точной копией всего многострочного текста. Затем установите непрозрачность части текста заполнителя, который не должен быть анимирован, равным 0 и анимировать.