使用 jquery 或 javascript 的列表/网格/平铺视图转换

List / Grid / Tile view transitions using jquery or javascript

我想使用 Jquery/JS 实现 list/grid/tile 视图。

关于 grid/list 带动画的视图,我浏览了很多,但只有 grid/list 视图解决方案。 但我需要 grid/list 观看动画(即过渡效果)。我附上了过渡效果的示例 video

我知道这看起来并不完全像您想要的结果,但也许它适合您,或者您可以在此基础上进行改进。我只是在宽度和间隔上使用了一个过渡,以便在变换中有一个小的延迟。

function toggle(){
  var k= 0;
  var i = setInterval(function(){
t = $('.test').length;
if(k>t){
 clearInterval(t)
}
$('.test').eq(k).toggleClass("test2");
k++;

  },120)
}

setTimeout(function(){
  toggle()
},1000)
.wrap {
  width:500px;
  min-height:100vh;
  position:relative;
  margin: 0 auto;
}
.test {
  color:white;
  margin:10px;
  background:black;
  width:100px;
  height:100px;
  float:left;
  -webkit-transition: width 1s ease-in-out;
  -moz-transition: width 1s ease-in-out;
  -o-transition: width 1s ease-in-out;
  transition: width 1s ease-in-out;
}
.test2 {
  width:100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrap">
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>

  </div>

如果您希望它与视频中的完全一样,您可能需要使用 translate-x translate-y

代码

https://codepen.io/shahriarkh/pen/NWvOyry?editors=0110

单击网格上方的“更改样式”按钮可切换动画。


在这里!
我使用 grid 因为它是可动画的,因为它是一个二维网格,而 blockflex 都是一维的。

但是右边出现的滚动条有问题。这太烦人了,我找不到修复它的方法。在JS代码的第9行,每张卡片应该向左移动120px * N,但是当滚动条出现时,它不再是120而是变得比120大一点(比如126)。我不知道它是从哪里来的...虽然在将 overflow-y: hidden 添加到 body 时 120 工作正常,但它不是一个适用的解决方法(你需要滚动条!)。

更新

我找到了解决办法!使用 overflow-y: scroll + scrollbar-width: none 就可以了。但是,您需要以某种方式让用户知道该页面是可滚动的。


顺便说一句,原视频是什么?我想知道它是否是一个网页并且有人已经这样做了:) 此外,Framer Motion 可能是替代硬编码的不错选择。

这是我的基本实现。我试过创建像视频一样的输出。
这个想法是将列表项包装在包装器中。包装器是静态放置的,列表项是绝对放置的。当视图更改时,包装器会根据样式表或容器规则自动排列。但是在动画之后移动列表项。

var pos = [];
var offs = null;

function init() {
  offs = $(".container").first().offset();
  $(".wrapper").each(function (i) {
    updatePositions();
    $(this).children(0).css({
      top: pos[i].top,
      left: pos[i].left
    });
  });
}

$(document).ready(function () {
  init();
});

$(window).resize(function () {
  init();
})

function updatePositions() {
  $(".wrapper").each(function(index) {
    var tp = $(this).offset().top - offs.top;
    var lf = $(this).offset().left - offs.left;
    pos[index] = {
      top: tp,
      left: lf
    };
  });
}

function grid() {
  if ($(".wrapper").first().hasClass("gv-wrapper")) return;
  updatePositions();
  $(".wrapper").each(function(index) {
    $(this).removeClass("dv-wrapper cv-wrapper");
    $(this).addClass("gv-wrapper");

    $(this).children(0).css({
      opacity: 0.8,
      top: pos[index].top,
      left: pos[index].left
    });
  });

  updatePositions();
  $(".wrapper").each(function(index) {
    $(this).children(0).children(0).removeClass("dv-video cv-video");
    $(this).children(0).children(1).removeClass("dv-details cv-details");
    $(this).children(0).children(0).first().addClass("gv-video");
    $(this).children(0).children(1).last().addClass("gv-details");
    $(this).children(0).animate({
      height: "100px",
      width: "200px",
      opacity: 1,
      top: pos[index].top,
      left: pos[index].left
    }, 1000, "swing");
  });
}


function detailed() {
  if ($(".wrapper").first().hasClass("dv-wrapper")) return;

  updatePositions();

  $(".wrapper").each(function(index) {
    $(this).removeClass("gv-wrapper cv-wrapper");
    $(this).addClass("dv-wrapper");

    $(this).children(0).css({
      opacity: 0.8,
      top: pos[index].top,
      left: pos[index].left
    });
  });

  updatePositions();
  $(".wrapper").each(function(index) {
    $(this).children(0).children(0).removeClass("gv-video cv-video");
    $(this).children(0).children(1).removeClass("gv-details cv-details");
    $(this).children(0).children(0).first().addClass("dv-video");
    $(this).children(0).children(1).last().addClass("dv-details");

    $(this).children(0).animate({
      height: "100px",
      width: "95%",
      opacity: 1,
      top: pos[index].top,
      left: pos[index].left
    }, 1000, "swing");
  });
}


function collapsed() {
  if ($(".wrapper").first().hasClass("cv-wrapper")) return;

  updatePositions();
  $(".wrapper").each(function(index) {
    $(this).removeClass("dv-wrapper gv-wrapper");
    $(this).addClass("cv-wrapper");

    $(this).children(0).css({
      opacity: 0.8,
      top: pos[index].top,
      left: pos[index].left
    });
  });

  updatePositions();
  $(".wrapper").each(function(index) {
    $(this).children(0).children(0).removeClass("dv-video gv-video");
    $(this).children(0).children(1).removeClass("dv-details gv-details");
    $(this).children(0).children(0).first().addClass("cv-video");
    $(this).children(0).children(1).last().addClass("cv-details");

    $(this).children(0).animate({
      height: "50px",
      width: "94%",
      opacity: 1,
      top: pos[index].top,
      left: pos[index].left
    }, 1000, "swing");
  });

}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  counter-reset: number;
  background-color: #ffffff;
  padding: 24px;
}

i.fas {
  margin: 5px;
}

i.fas:hover {
  background-color: white;
}

.container {
  width: 500px;
  min-height: 90vh;
  margin: 0 auto;
  background-color: #ADC2A9;
  border: 1px dotted gray;
  font-size: 0.7em;
  position: relative;
}

.wrapper {
  margin: 10px 10px;
  /* to debug enable the color */
  /*background-color: darkcyan;*/
}

.record {
  position: absolute;
  width: 95%;
  top: 0px;
  left: 0px;
  background-color: #D3E4CD;
}

.record:first-child:before {
  counter-increment: number;
  content: counter(number);
  position: absolute;
  top: 10%;
  left: 10%;
  font-size: 23px;
  color: blue
}

.video {
  width: 200px;
  height: 100px;
  background: linear-gradient(white 40%, #5e819ef8);
}


/* list view */

.dv-wrapper {
  height: 100px;
  width: 95%;
  float: left;
}

.dv-video {}

.dv-details {
  position: absolute;
  width: calc(100% - 200px);
  top: 0px;
  right: 0px;
  float: right;
  padding-left: 10px;
  overflow: hidden;
}


/* grid view */

.gv-wrapper {
  height: 100px;
  width: 200px;
  float: left;
}

.gv-video {
  float: left;
}

.gv-details {
  position: absolute;
  left: 0px;
  bottom: 0px;
  padding-left: 10px;
  overflow: hidden;
}


/* collapsed view */

.cv-wrapper {
  height: 50px;
  width: 80%;
}

.cv-video {
  float: left;
  display: none;
}

.cv-details {
  padding-left: 10px;
  overflow: hidden;
}

.details p {
  width: 100%;
  text-overflow: ellipsis;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" rel="stylesheet" />

<div style="margin: 0 50%; width: 100px; transform: translate(-50%);">
  <i class="fas fa-list" onclick="detailed()"></i>
  <i class="fa fa-th" onclick="grid()"></i>
  <i class="fas fa-bars" onclick="collapsed()"></i>
</div>
<div class="container">
  <div class="dv-wrapper wrapper">
    <div class="record">
      <div class="video dv-video"></div>
      <div class="details dv-details">
        <p>1 Lorem ipsum dolor sit amet consectetur adipiorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt, dolor.</p>
      </div>
    </div>
  </div>
  <div class="dv-wrapper wrapper">
    <div class="record">
      <div class="video dv-video"></div>
      <div class="details dv-details">
        <p>2 Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt, dolor.</p>
      </div>
    </div>
  </div>
  <div class="dv-wrapper wrapper">
    <div class="record">
      <div class="video dv-video"></div>
      <div class="details dv-details">
        <p>3 Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt, dolor.</p>
      </div>
    </div>
  </div>
  <div class="dv-wrapper wrapper">
    <div class="record">
      <div class="video dv-video"></div>
      <div class="details dv-details">
        <p>4 Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt, dolor.</p>
      </div>
    </div>
  </div>
  <div class="dv-wrapper wrapper">
    <div class="record">
      <div class="video dv-video"></div>
      <div class="details dv-details">
        <p>5 Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt, dolor.</p>
      </div>
    </div>
  </div>

</div>

这只是一个演示代码。它可以通过多种方式进行改进。我们可以将包装器放入现有的网格或弹性容器中,并为内容项设置动画,如上所示。
让我知道是否有现成的第三方可以减少或改进上述代码。