如何制作两个字母交换的动画?
How do I animate two letters swapping?
我正在尝试制作一个网站,将鼠标悬停在由两个字母换位组成的拼写错误上可以更正它,如下所示:
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');
}
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;
}
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?
但是,如您所见,字母不能很好地交换,此外,我不想为每个不同的字母宽度计算精确的边距。
执行此操作的更好方法是什么?
可以通过使用 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`);
.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);
}
<span class="word">
App<span class="letter">e</span>r<span class="letter">a</span>nt
</span>
我正在尝试制作一个网站,将鼠标悬停在由两个字母换位组成的拼写错误上可以更正它,如下所示:
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');
}
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;
}
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?
但是,如您所见,字母不能很好地交换,此外,我不想为每个不同的字母宽度计算精确的边距。
执行此操作的更好方法是什么?
可以通过使用 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`);
.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);
}
<span class="word">
App<span class="letter">e</span>r<span class="letter">a</span>nt
</span>