【问题标题】:Animating HTML objects that move when text is modified / changed修改/更改文本时移动的动画 HTML 对象
【发布时间】:2018-03-29 08:39:54
【问题描述】:

我有这个代码:

<span><img id="user" src="http://placehold.it/100x100" alt="img"></span>
<span><h2 id="textToChange">text here</h2></span>

当我更改#textToChange 时,#user 会自动移动,因为文本会更改并且因为它是一个跨度,所以它会移动它。我想为#user 设置动画,以便它以线性动画的形式移动,而不是仅仅到达 x 值。 是有可能实现还是我疯了?谢谢。

【问题讨论】:

  • 嗨!请参阅How to Ask 以及如何创建minimal reproducible example,我们需要能够为您提供帮助。您如何使用您拥有的代码制作一个 sn-p,尝试对​​其进行动画处理,然后向我们询问具体
  • 编辑应该不错
  • 我对你到底想要什么感到有点困惑:你想要一个在另一个之上并且一个相应地改变它的宽度吗? 您希望它如何移动?
  • 想象一下:这是文本,字母 X 是图像 这是文本 X 当我将其更改为其他内容时,例如这是其他内容 X 你看到 X 位置已更改,我希望这个位置变化是动画的。
  • 所以你在#textToChange 中有一个文本,当该文本动态变化时,它会影响图像(因为它是内联的)。您希望碰撞是动画的而不是即时的。两件事:1)什么改变了文本?有没有一些JS可以做到这一点? 2)为什么您的代码将图像和文本放在不同的跨度中,而文本紧随其后?这是否意味着文本永远无法移动图像?

标签: javascript jquery html css css-animations


【解决方案1】:

这是一个有趣的小问题。让我把它分解成几个步骤:

  1. 查找图像的当前位置
  2. 找到需要移动的位置
  3. 移动它
  4. 更改文字

现在,困难的部分是第 2 步和第 3 步。

对于第 2 步,您必须计算新文本的长度。这很棘手,因为没有内置函数可以告诉您使用给定样式集的文本有多宽。您几乎必须创建一个重复的元素并对其进行测量。

对于第 3 步,您必须在文本更改之前或之后移动元素而不引起跳转。我这样做的方法是使用position: absolute 并将left 设置为当前位置(从而消除那里的任何抽搐)。然后我使用transform(做一些数学计算来说明当前位置)转换到正确的位置,以提高性能。在过渡结束时,去掉style 属性并更改文本。

要注意的另一件事是当图像变为position: absolute 时文本会跳来跳去。为简单起见,我将整行放在display: flex 容器中。如果不想使用 flex,可以在文本上使用 inline-blockblock 并调整 padding/height 以保持适当的空间。

这是我想出的(也在JSFiddle):

var $img = document.getElementById('user');
var $text = document.getElementById('textToChange');
var $estimator = document.getElementById('estimator');

var extraWidth = $img.offsetLeft - $text.offsetWidth;

function estimate(text) {
  $estimator.textContent = text;

  var width = $estimator.offsetWidth;

  $estimator.textContent = '';

  return width;
}

document.getElementById('change-text')
  .addEventListener('click', function() {
    var newText = randomText();

    var left = $img.offsetLeft;

    $img.style.position = 'absolute';
    $img.style.left = left + 'px';
    $img.style.transition = 'transform linear 1s';
    $img.style.transform = 'translateX(0)';

    window.requestAnimationFrame(function() {
      $img.style.transform = 'translateX(' + (extraWidth + estimate(newText) - left) + 'px)';

      window.setTimeout(function() {
        $text.textContent = newText;
        $img.removeAttribute('style');
      }, 1000);
    });
  });

// For testing
function randomText() {
  var length = Math.floor(Math.random() * 43) + 3;

  return 'Lorem ipsum dolor sit amet portris noc tefweep'.slice(0, length);
}
h2 {
  position: relative;
  height: 100px;
  display: flex;
  align-items: flex-end;
}

/* For measuring text width. I don't want it to be seen. */
.not-shown {
  visibility: hidden;
  color: transparent;
  position: absolute;
  z-index: -1;
}
<h2>
  <span id="textToChange">text here</span>
  <img id="user" src="http://placehold.it/100x100" alt="img">
</h2>

<h2 class="not-shown"><span id="estimator"></span></h2>

<button id="change-text">Change text</button>

请注意,如果文本多行,这将无法正常工作。我选择不担心这种情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    • 2019-01-13
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多