多行的动画文字下划线(从左到右绘制动画)

问题描述 投票:4回答:2

我正在为如何模拟我在下面的代码中显示的相同效果而疯狂,因为单行文本(悬停时)在多行文本上。

.underline-on-hover
{
  position:relative;
  display:inline-block;
}

.underline-on-hover::after
{
  content: " ";
  background-color: red;
  width:0;
  position: absolute;
  left:0;
  bottom:0;
  height:5px;
  
  -webkit-transition: width 1s ease-in-out;
  -moz-transition: width 1s ease-in-out;
  -o-transition: width 1s ease-in-out;
  transition: width 1s ease-in-out;

}

.underline-on-hover:hover::after
{
  width:100%;
}
<p class="underline-on-hover">
I'm a single line text!
</p>
<br><br>
<p class="underline-on-hover" style="max-width:200px">
I'm a multiple line text... let me prove it: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>

正如你所看到的,我可以从左到右模拟这个“下划线”动画,对于单行文本有一个后,但我不知道如何为多行文本做,我的问题是,我不能将它轻松分成几行,因为它将是一个插入动态容器的动态文本...

任何想法如何实现它?

非常感谢你!

html css animation pseudo-element underline
2个回答
2
投票

也许你应该尝试使用jQuery的How to select nth line of text (CSS/JS)解决方案来指定每一行,然后使用你的CSS。


1
投票

我想我遇到了同样的问题。我发现了一个使用js的决定。它起作用于ie11(我没有在下面测试)。 主要是获得每一行的宽度。

Codepen

帕格:

.container
  .text Lorem ipsum dolor sit amet consectetur adipisicing elit. Eligendi exercitationem quos, facere ipsum perspiciatis labore dolores, quibusdam, culpa numquam deleniti nihil ad. Tempore beatae nobis facere deserunt nam dicta earum.
br
br
div.test

SCSS:

.text {
  display: inline-block;
  line-height: 1.2;
}

.container {
  position: relative;
}

.line {
  position: absolute;
  width: 0;
  height: 2px;
  background: red;
  transition: width .5s;
}

.container:hover line {  
  left: 0;
  right: auto;
}

JS:

function multilineTextUnderline() {
  var text = document.querySelector('.text');
  var words = text.innerText.split(' ');
  var div = document.querySelector('.test');

  var initialText = text.innerText;
  var widths = [];
  var lineHeight = parseInt($(text).css('line-height'), 10);
  var firstWord = 0;
  text.innerText = words[0];
  var currentHeight = text.offsetHeight;

  $('.test span').remove();
  $('.test br').remove();

  function getWidths() {
    words.forEach(function(word, i) {
      text.innerText = words.slice(firstWord, i + 1).join(' ');
      if(currentHeight < text.offsetHeight) {
          text.innerText = words.slice(firstWord, i).join(' ');
          widths.push(text.offsetWidth);
          firstWord = i;

          var newSpan = document.createElement('span');
          newSpan.innerText = text.innerText;
          div.appendChild(newSpan);
          div.appendChild(document.createElement('br'));

          if(i === words.length - 1) {
            text.innerText = words[i];
            widths.push(text.offsetWidth);

            var newSpan = document.createElement('span');
            newSpan.innerText = text.innerText;
            div.appendChild(newSpan);
            div.appendChild(document.createElement('br'));
          }
      } else if(i === words.length - 1) {
          widths.push(text.offsetWidth);

          var newSpan = document.createElement('span');
          newSpan.innerText = words.slice(firstWord).join(' ');
          div.appendChild(newSpan);
          div.appendChild(document.createElement('br'));
      }
    });
  }

  getWidths();
  text.innerText = initialText;
  console.log('        widhts: ', widths);
  var controlWidths = [];

  [].forEach.call(document.querySelectorAll('.test span'), function(span) {
      controlWidths.push(span.offsetWidth);
  });
  console.log('control widths: ', controlWidths);

  //rendering underlines
  var container = document.querySelector('.container');
  var containerWidth = container.offsetWidth;
  var lines = [];
  $('.line').remove();

  widths.forEach(function(lineWidth, i) {
    var line = document.createElement('div');
    line.classList.add('line');
    line.style.top = lineHeight * (i + 1) - 2 + 'px';

    lines.push(line);
  });

  lines.forEach(function(line) {  
    container.appendChild(line);
  });

  container.addEventListener('mouseenter', function() {
    lines.forEach(function(line, i) {  
      line.style.width = widths[i] + 'px';
      line.style.left = 0;
      line.style.right = 'auto';
    });
  });
  container.addEventListener('mouseleave', function() {
    lines.forEach(function(line, i) {  
      line.style.width = 0;
      line.style.left = 'auto';
      line.style.right = containerWidth - widths[i] + 'px';
    });
  });
}

multilineTextUnderline();

window.addEventListener('resize', function() {

  multilineTextUnderline();
});
© www.soinside.com 2019 - 2024. All rights reserved.