Как заставить двигаться только 1 слово с типом writer javascript? - PullRequest
0 голосов
/ 07 февраля 2020

Я попытался центрировать «исходный текст», в то время как только вторичный текст должен быть динамическим c и перемещаться с эффектом записи типа. Я не хочу выравнивать текст по левому краю с помощью text-left , но лучше держите все это в центре и динамически перемещайте только слова типа.

Я пытался добавить ml-5, но это не имеет никакого эффекта.

Я использую bootstrap и я хочу, чтобы это также было удобно для мобильных устройств.

// 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;
}

.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,
      <span class="txt-type" data-wait="1000" data-words='["Secondary text"]'></span>
    </h3>
  </div>
  
  <script src="main.js"></script>
</body>
</html>

Ответы [ 3 ]

1 голос
/ 07 февраля 2020

Чистый 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 и анимировать.

1 голос
/ 07 февраля 2020

, поскольку <span> - это встроенное отображение по умолчанию, оно будет располагаться рядом с исходным текстом, вы можете просто добавить <br> или установить display:block к элементу span или переместить его ниже h2

UPDATE : выравнивание текста по центру не будет работать, выровняйте его по левому краю с помощью поля Dynami c по левому краю (используя vw)

// 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;
}

.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 {
    margin-left:25vw;
}
<!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,
      <span class="txt-type" data-wait="1000" data-words='["Secondary text"]'></span>
    </h3>
  </div>
  
  <script src="main.js"></script>
</body>
</html>
0 голосов
/ 07 февраля 2020

Посмотрите. Существует две копии текста, одна видимая, другая прозрачная.

Символы, добавленные в видимый диапазон, удаляются из прозрачного диапазона, а символы, удаленные из видимого диапазона, добавляются в прозрачный диапазон, так что общая длина / ширина остается неизменной.

// ES6 Class
class TypeWriter {
  constructor(txtElement, words, wait = 3000, fakeElement) {
    this.txtElement = txtElement;
    this.fakeElement = fakeElement;
    this.words = words;
    this.txt = '';
    this.fakeTxt = 'Secondary text';
    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);
      this.fakeTxt = fullTxt.substring(this.txt.length);
    } else {
      // Add char
      this.txt = fullTxt.substring(0, this.txt.length + 1);
      this.fakeTxt = fullTxt.substring(this.txt.length);
    }

    // Insert txt into element
    this.txtElement.innerHTML = `<span class="txt">${this.txt}</span>`;
    this.fakeElement.innerHTML = `<span class="txt">${this.fakeTxt}</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');
  const fakeElement = document.querySelector('.txt-fake');
  // Init TypeWriter
  new TypeWriter(txtElement, words, wait, fakeElement);
}
@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;
}

.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
}
.txt-fake {
    color: #12345600;
}
<!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,
      <span class="txt-type" data-wait="1000" data-words='["Secondary text"]'
      ></span><span class="txt-fake">Secondary text</span></h3>
  </div>
  
  <script src="main.js"></script>
</body>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...