如何制作两个字母交换的动画?

416*_*577 1 html javascript css dom css-animations

我正在尝试创建一个网站,将鼠标悬停在由两个字母换位组成的拼写错误上可以更正它,如下所示:

var swap = document.querySelector('.swap');

swap.addEventListener('mouseover', swapIn);
swap.addEventListener('mouseout', swapOut);

function swapIn(e) {
  e.target.parentNode.firstChild.classList.toggle('shifted-right');
  e.target.parentNode.lastChild.classList.toggle('shifted-left');
}

function swapOut(e) {
  e.target.parentNode.firstChild.classList.toggle('shifted-right');
  e.target.parentNode.lastChild.classList.toggle('shifted-left');
}
Run Code Online (Sandbox Code Playgroud)
body {
  font-size: 24px;
}

.swap {
  display: inline;
}

span {
    -webkit-transition: all 0.3s linear;
    -moz-transition: all 0.3s linear;
    -o-transition: all 0.3s linear;
    transition: all 0.3s linear;
}

.shifted-right {
  margin-left: 20px;
  color: blue;
}

.shifted-left {
  margin-left: -25px;
  color: red;
}
Run Code Online (Sandbox Code Playgroud)
E<div class="swap" id="swap"><span class="left-swap" id="ls">q</span><span class="right-swap" id="rs">c</span></div>uis me vivit fortunatior?
Run Code Online (Sandbox Code Playgroud)

但是,正如您所看到的,字母交换得不好,而且我不想计算每个不同字母宽度的精确边距。

执行此操作的更好方法是什么?

Emi*_*ier 5

可以通过使用该属性计算它们与其父字母的相对位置来完成在同一个单词中切换两个字母的操作offsetLeft

将这些值彼此相减并用于Math.abs保持整数为正数。这个数字是distance两个字母之间的数字。一个字母必须向左移动整个距离,而另一个则必须向右移动相同的距离才能交换位置。设置 CSS 变量的距离,以便我们可以将计算传递给 CSS。

在 CSS 中,我们可以使用:hover伪选择器来设置悬停时的样式,并使用 CSS 变量来进行正确的转换。并且不要将鼠标悬停在字母上,而是将鼠标悬停在整个单词上。

而不是margin使用transform; 此属性不会扰乱布局,并且只会操作目标元素。

const word = document.querySelector('.word');
const [e, a] = word.querySelectorAll('.letter');
const distance = Math.abs(e.offsetLeft - a.offsetLeft);
word.style.setProperty('--distance', `${distance}px`);
Run Code Online (Sandbox Code Playgroud)
.word {
  display: inline-block;
  padding: 15px;
  position: relative;
  font-size: 32px;
  background-color: #f7f7f7;
  border: 1px dashed #d0d0d0;
  border-radius: 3px;
  cursor: help;
}

.word .letter {
  display: inline-block;
  color: red;
  transition: color 500ms ease-in-out, transform 500ms ease-in-out;
}

.word:hover .letter {
  color: green;
}

.word:hover .letter:first-of-type {
  transform: translate(var(--distance), 0);
}

.word:hover .letter:last-of-type {
  transform: translate(calc(var(--distance) * -1), 0);
}
Run Code Online (Sandbox Code Playgroud)
<span class="word">
  App<span class="letter">e</span>r<span class="letter">a</span>nt
</span>
Run Code Online (Sandbox Code Playgroud)