使用有限元素列出旋转

Src*_*Src 18 html javascript html5 css3 translate-animation

我有container里面的列表(卡)div .当我将它悬停时,卡片开始移动(translateX animation).containerwidth300px,元件计数container:3,每一个元素width:100px.

所以你可以在容器中看到3个元素overflow:hidden.我要做的是,当没有元素在第三个元素之后显示translateX动画-100px = 100px空格时,它从最后一个列表中的1个元素开始,没有空格.

就目前而言,我不知道如何在没有重复等的情况下完成任务.

这就是我现在所拥有的: 小提琴(悬停卡看翻译动画)

UPD 1: 代码和数据(卡数,容器大小)例如,我将尝试更好地解释我想要的东西:我的目标是建立卡片列表,按下按钮后,列表将开始移动(比如在一些时间里使用translateX动画)(例如translateX:12491px,animation-duration:15s ;)并停止.但问题是列表中的碎片数量将在3-40张卡的范围内(每张卡的宽度和高度均为100px).因此,当我将translateX:12491px设置为例如,它将超出范围,并且在列表中的最后一张卡出现空白后.我希望第一张和最后一张卡以某种方式被捆绑,并且在最后一张卡片后立即出现在列表中的第一张卡片等等.也许我正在以错误的方式寻找解决方案,但我想你明白了主要想法.

UPD 2: 我发现cs:go使用我想在html\css\js上写的动画.这是视频:youtube.com

HTML:

<div class="container">
    <div class="cards">
        <div class="card">
        1
    </div>
    <div class="card">
        2
    </div>
    <div class="card">
        3
    </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

CSS:

.container
{
    width:300px;
        height: 100px;
    border: 2px solid black;
    overflow: hidden;
}
.card
{
    float:left;
    height: 100px;
    width: 100px;
    background-color:blue;
    box-sizing: border-box;
    border: 2px solid red;
    color: white;
    font-size: 23px;
}
.cards:hover
{
    transform: translateX(-100px);
    transition-duration: 3s;
    animation-duration: 3s;
    animation-fill-mode: forwards;
}
Run Code Online (Sandbox Code Playgroud)

Abh*_*lks 6

从紧接着列表中的1个元素开始,没有空格

这超出了CSS,你需要Javascript.因为,你用Javascript而不是jQuery标记了这个问题,我的答案仅限于纯Javascript.看看ma,没有JQuery;)

我不知道如何在没有重复的情况下完成

这是一个DIY(自己动手)的想法..

  1. 主要技巧是显示至少一个项目少于你拥有的总数.如果您有3张牌,则仅显示2.如果您有4张牌,则仅显示3.为什么,因为您需要在卡片离开视图时重新定位卡片并将其包裹在最后.如果您显示的卡数与您所拥有的卡数完全相同,那么您无法打破半卡并将其包裹起来,您将看到一些空白区域,直到第一张卡片退出视图.你明白了吗?
  2. 不要使用translate或者在编写脚本时最终会让自己变得复杂.保持简单.
  3. 不要使用包装纸.为什么?因为,我们将重新定位已经消失的卡片.当我们这样做时,下一张牌将占据它的位置并立即离开视线,使你的事情变得更加困难.
  4. 为了简单起见,请安排卡片absolute相对于容器的位置.首先,让所有卡堆叠起来top:0; and left: 0;.
  5. 接下来连接Javascript以left根据width每张卡的位置定位属性并线性排列.
  6. 使用requestAnimationFrame控制动画.
  7. 跟踪最左边的卡及其left位置.当这超出视野(这是0减去宽度)时,appendChild此卡到其容器.这会将卡片移动到卡片的末尾.此外,left根据列表中的最后一张卡将属性更改为该属性.
  8. 那就是它的全部.

以下是演示.为了方便您进行实验,我使用了一个设置对象来保存您可以轻松调整和查看的可配置属性.仔细查看代码,您会发现它很容易理解.您可以将iterations设置设置0为使动画无限.

另请注意,您无需复制或伪造卡片.尝试演示并添加您想要的卡.

代码段中的内联代码注释将进一步帮助您理解每行代码并与上述步骤相关.

片段:

var list = document.querySelector('.cardList'), // cache the container
    cards = document.querySelectorAll('.card'), // cache the list of cards
    start = document.getElementById('start'),   // buttons
    stop = document.getElementById('stop'), 
    reset = document.getElementById('reset'), 
    raf, init = 0, counter = 0, lastCard, currentIteration = 0, // general purpose variables
    settings = { // settings object to help make things configurable
        'width': 100, 'height': 100, 'speed': 2, 
        'iterations': 2, 'count': cards.length 
    }
;
start.addEventListener('click', startClick); // wire up click event on buttons
stop.addEventListener('click', stopClick);
reset.addEventListener('click', resetClick);
initialize(); // initialize to arrange the cards at start

function initialize() {
    // loop thru all cards and set the left property as per width and index position
    [].forEach.call(cards, function(elem, idx) { 
        elem.style.left = (settings.width * idx) + 'px';
    }); 
    init = -(settings.width); // initialize the view cutoff
    lastCard = cards[settings.count - 1]; // identify the last card
    counter = 0; currentIteration = 0; // reset some counters
    settings.speed = +(document.getElementById('speed').value);
    settings.iterations = +(document.getElementById('iter').value);
}
function startClick() { 
    initialize(); raf = window.requestAnimationFrame(keyframes); // start animating
}
function stopClick() { window.cancelAnimationFrame(raf); } // stop animating
function resetClick() { // stop animating and re-initialize cards to start again
    window.cancelAnimationFrame(raf); 
    document.getElementById('speed').value = '2';
    document.getElementById('iter').value = '2';
    initialize(); 
}

// actual animation function
function keyframes() {
    var currentCard, currentLeft = 0, newLeft = 0;
    // iterate all cards and decrease the left property based on speed
    [].forEach.call(cards, function(elem, idx) {
        elem.style.left = (parseInt(elem.style.left) - settings.speed) + 'px';
    }); 
    currentCard = cards[counter]; // identify left-most card
    currentLeft = parseInt(currentCard.style.left); // get its left position
    if (currentLeft <= init) { // check if it has gone out of view
        // calculate position of last card
        newLeft = parseInt(lastCard.style.left) + settings.width;
        list.appendChild(currentCard); // move the card to end of list
        currentCard.style.left = newLeft + 'px'; // change left position based on last card
        lastCard = currentCard; // set this as the last card for next iteration
        counter = (counter + 1) % settings.count; // set the next card index
        if ((settings.iterations > 0) && (counter >= (settings.count - 1))) { 
            currentIteration++; // check settings for repeat iterations
        }
    }
    if (currentIteration >= settings.iterations) { return; } // when to stop
    raf = window.requestAnimationFrame(keyframes); // request another animation frame
};
Run Code Online (Sandbox Code Playgroud)
* { box-sizing: border-box; padding: 0; margin: 0; }
.cardList { 
    position: relative; height: 100px; width: 300px; 
    margin: 10px; border: 2px solid #33e; 
    overflow: hidden; white-space: nowrap; 
}
.card { 
    position: absolute; left: 0; top: 0; text-align: center;
    height: 100px; width: 100px; line-height: 100px;
    background-color: #99e; 
    font-family: monospace; font-size: 2em; color: #444;
    border-left: 1px solid #33e; border-right: 1px solid #33e;
}

div.controls, button { margin: 10px; padding: 8px; font-family: monospace; }
div.controls input { width: 48px; padding: 2px; text-align: center; font-family: monospace; }
Run Code Online (Sandbox Code Playgroud)
<div class="controls">
    <label>Speed <input id="speed" type="number" min="1" max="8" value="2" />x</label>
    &nbsp;|&nbsp;
    <label>Iterations <input id="iter" type="number" min="0" max="8" value="2" /></label>
</div>
<div class="cardList">
    <div class="card">1</div>
    <div class="card">2</div>
    <div class="card">3</div>
    <div class="card">4</div>
</div>
<button id="start">Start</button>
<button id="stop">Stop</button>
<button id="reset">Reset</button>
Run Code Online (Sandbox Code Playgroud)

小提琴:http://jsfiddle.net/abhitalks/1hkw1v0w/

注意:我在演示中遗漏了一些东西.特别是,虽然卡片的宽度和高度是设置对象的一部分,但目前它是固定的.您可以轻松使用设置对象来使卡的尺寸也可配置.


编辑:

(根据Op的评论)

如果你想要更好地控制距离滚动,持续时间和计时功能(缓和),那么你可以自己使用库来实现.一些很好的库是Robert Penner的Easing FunctionsGSGD的jQuery插件.虽然您可以使用纯Javascript实现所有这些,但如果您使用像jQuery这样的库会更容易.

这里要抓住的是,为了有效地这样做,你必须复制这些卡片.你可以通过几次克隆整个列表来轻松完成.

虽然你还没有用jQuery标记这个问题,但这是一个小型演示(使用jQuery快速完成),你可以在其中配置速度和距离.

摘录2:

var $cardList 	= $('.cardList').first(), 
    $cards 		= $('.card'), 
    $speed 		= $('input[name=speed]'), 
    width 		= 100, 
    randomize 	= true, 
    distance 	= 20 * width 
;

for (var i = 0; i < 50; i++) {
    $cards.clone().appendTo($cardList);
}

function spin() {
    var newMargin = 0, newDistance = distance, 
        speed = +($speed.filter(':checked').val());
    if (randomize) {
        newDistance = Math.floor(Math.random() * $cards.length * 5);
		newDistance += $cards.length * 5;
        newDistance *= width;
    } 
	newMargin = -(newDistance);
    $cards.first().animate({
        marginLeft: newMargin
    }, speed);
}

$('#spin').click(function() {
    $cards.first().css('margin-left', 0);
    spin();
    return false;
});
Run Code Online (Sandbox Code Playgroud)
* { box-sizing: border-box; padding: 0; margin: 0; }
.cardList { 
    height: 100px; width: 302px; position: relative;
    margin: 10px; border: 1px solid #33e; 
    overflow: hidden; white-space: nowrap; 
}
.card { 
    display: inline-block; text-align: center;
    height: 100px; width: 100px; line-height: 100px;
    background-color: #99e; 
    font-family: monospace; font-size: 2em; color: #444;
    border-left: 1px solid #33e; border-right: 1px solid #33e;
}
.cardList::before, .cardList::after {
    content: ''; display: block; z-index: 100;
    width: 0px; height: 0px; transform: translateX(-50%);
	border-left: 8px solid transparent;
	border-right: 8px solid transparent;    
}
.cardList::before {
    position: absolute; top: 0px; left: 50%;
	border-top: 12px solid #33e;
}
.cardList::after {
    position: absolute; bottom: 0px; left: 50%;
	border-bottom: 12px solid #33e;
}
div.controls, button { margin: 10px; padding: 8px; font-family: monospace; }
div.controls input { width: 48px; padding: 2px; text-align: center; font-family: monospace; }
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="controls">
    <label>Speed: </label>
    &nbsp;|&nbsp;
    <label><input name="speed" type="radio" value='6000' />Slow</label>
    <label><input name="speed" type="radio" value='5000' checked />Medium</label>
    <label><input name="speed" type="radio" value='3000' />Fast</label>
</div>
<div class="cardList"><!--
    --><div class="card">1</div><!--
    --><div class="card">2</div><!--
    --><div class="card">3</div><!--
    --><div class="card">4</div><!--
--></div>
<button id="spin">Spin</button>
Run Code Online (Sandbox Code Playgroud)

小提琴2:http://jsfiddle.net/abhitalks/c50upco5/