Виктор Б Asked:2020-03-20 22:47:37 +0000 UTC2020-03-20 22:47:37 +0000 UTC 2020-03-20 22:47:37 +0000 UTC 打开纸牌扇的动画 772 请告诉我悬停在块上时如何在 js 上制作动画。图 1 中块的初始位置,图 2 中大约的最终位置。 谢谢你。 javascript 2 个回答 Voted Best Answer user355286 2020-03-21T15:24:49Z2020-03-21T15:24:49Z 一次 const deck = document.querySelector('.deck') const cards = document.querySelectorAll('.deck__card') const middle = Math.floor(cards.length / 2) const animationDuration = 0.7 let isRunning = false deck.addEventListener('mouseenter', function(e) { if (isRunning) return isRunning = true cards.forEach((c, i) => { c.style.transition = animationDuration + 's' c.style.transform = `translateX(240px) translateY(15px) rotateZ(30deg)` }) setTimeout(() => { cards.forEach((c, i) => { const tx = i * 50 + Math.random() * 20 const e = i == 0 || i == cards.length - 1 ? 15 : 0 const ty = i < middle ? -i * 14 + e : (i - cards.length + 1) * 14 + e const rz = i * 7 setData(c, 240 - tx, ty, 30 - rz) transform(c, c.dataset.tx, c.dataset.ty, c.dataset.rz, 0) }) }, animationDuration * 1000) setTimeout(() => { cards.forEach((c, i) => { setTimeout(() => { const tx = +c.dataset.tx - (10 + Math.random() * 40) const ty = +c.dataset.ty + (Math.random() * 10) transform(c, tx, ty, c.dataset.rz, -180) if (i == cards.length - 1) isRunning = false }, 80 * i) }) }, (animationDuration + 0.05) * 1000 * 2) }) deck.addEventListener('mouseleave', mouseLeaveHandler) function mouseLeaveHandler(e) { if (isRunning) return cards.forEach(c => transform(c, +c.dataset.tx, c.dataset.ty, c.dataset.rz, 0)) setTimeout( () => cards.forEach((c, i) => transform(c, 0, 0, 0, 0)), animationDuration * 1000 ) } function transform(el, tx, ty, rz, ry = 0) { el.style.transform = ` translateX(${tx}px) translateY(${ty}px) rotateZ(${rz}deg) rotateY(${ry}deg)` } function setData(el, tx, ty, rz) { el.dataset.tx = tx el.dataset.ty = ty el.dataset.rz = rz } * { margin: 0; padding: 0; } body { height: 100vh; display: grid; align-items: center; justify-content: center; perspective: 1000px; overflow: hidden; } .deck { height: 300px; width: 200px; display: grid; list-style: none; } .deck__card { grid-row: 1 / 1; grid-column: 1 / 1; display: grid; transform-style: preserve-3d; box-shadow: 0 1px 3px rgba(150, 150, 150, 0.4), 0 1px 2px rgba(150, 150, 150, 0.4); } .deck__card>* { grid-row: 1 / 1; grid-column: 1 / 1; backface-visibility: hidden; border-radius: 4px; background-size: 80%; background-repeat: no-repeat; background-position: center; } .deck__card__front { background-color: #E0E0E0; background-image: url(https://cdn.pixabay.com/photo/2017/07/12/18/38/treasure-2497813_960_720.png); transform: rotateY(-180deg); } .deck__card__back { background-color: #212121; background-image: url(https://static.warthunder.ru/upload/image/!2015/August/roger_01.png); } <ul class="deck"> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> <li class="deck__card"> <div class="deck__card__front"></div> <div class="deck__card__back"></div> </li> </ul> 二 :root { --card-height: 250px; --card-width: 150px; } * { margin: 0; padding: 0; box-sizing: border-box; } body { height: 100vh; display: flex; align-items: center; justify-content: center; perspective: 1000px; } ul { display: flex; list-style: none; } li { height: var(--card-height); width: var(--card-width); margin: 5px; border-radius: 4px; background-color: #EEEEEE; background-image: url(https://cdn131.picsart.com/276403626017211.png?type=webp&to=min&r=1024); background-position: center; background-size: 140%; background-repeat: no-repeat; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); transition: 0.5s; transform-origin: bottom; } li:nth-child(1) { transform: translateX(calc(var(--card-width) * 3 - 160%)) translateY(5%) rotateZ(-30deg); transition-delay: 0s; } li:nth-child(2) { transition-delay: 0.02s; transform: translateX(calc(var(--card-width) * 2 - 110%)) translateY(-12%) rotateZ(-20deg); } li:nth-child(3) { transition-delay: 0.04s; transform: translateX(calc(var(--card-width) * 1 - 60%)) translateY(-22%) rotateZ(-10deg); } li:nth-child(4) { transition-delay: 0.06s; transform: translateX(calc(var(--card-width) * -1 + 60%)) translateY(-22%) rotateZ(10deg); } li:nth-child(5) { transition-delay: 0.08s; transform: translateX(calc(var(--card-width) * -2 + 110%)) translateY(-12%) rotateZ(20deg); } li:nth-child(6) { transition-delay: 0.1s; transform: translateX(calc(var(--card-width) * -3 + 160%)) translateY(5%) rotateZ(30deg); } ul:hover>li { transform: translateX(0) translateY(0) rotateZ(0); } <ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> Stranger in the Q 2020-03-22T02:16:43Z2020-03-22T02:16:43Z 这是带有变量的版本: .hand { transform: translate(calc(50vw - 200px), calc(50vh - 50px)); width: 400px; height: 100px; } .hand div { transition: 0.2s; } .hand div:hover { transform:translate(0,-9px); } .hand div:after, .hand div:before { content: ''; position: absolute; background: radial-gradient(circle at center, wheat, steelblue); border: 1px solid; height: 76px; width: 50px; --rot: 0deg; transform: translate(175px) rotatez(calc(var(--i) * 15deg)) rotatey(var(--rot)); transform-origin: 50% 200%; transition: 0.5s; backface-visibility:hidden; } .hand div:after { content: attr(data-card); line-height: 76px; font-size: 30px; text-align: center; background: wheat; --rot: 180deg; } .hand:hover div:after, .hand:hover div:before { transform: translate(175px) translate(calc(var(--i) * 55px), 0) rotatez(0) rotatey(calc(180deg + var(--rot))); } <div class="hand"> <div data-card="♠️A" style="--i:-2.5"></div> <div data-card="♠️K" style="--i:-1.5"></div> <div data-card="♠️Q" style="--i:-0.5"></div> <div data-card="♠️J" style="--i: 0.5"></div> <div data-card="♠️10" style="--i: 1.5"></div> <div data-card="♠️9" style="--i: 2.5"></div> </div>
一次
二
这是带有变量的版本: