【问题标题】:Shared element transition using ReactJS使用 ReactJS 的共享元素转换
【发布时间】:2017-11-02 23:35:36
【问题描述】:

在 Android 中,共享元素转换允许两个页面中存在的 2 个完全相同的元素在转换页面时链接在一起,就像下面显示的 gif 中的专辑封面一样:

我想知道是否可以在类之间使用 ReactJS 实现相同的转换。如果是这样,有什么例子吗?如果没有,那么 jQuery 呢?

【问题讨论】:

标签: javascript jquery css reactjs


【解决方案1】:

您几乎可以完全使用 CSS transform 属性来完成此转换。 React JS 是关于操作 DOM 的,但你不需要在这里做太多。

动画:

  1. 隐藏小面板的文本内容。
  2. 缩放图片和文本背景以填满全屏。
  3. 放入新的文本内容。

其中 1 和 3 用 React 很容易,所以你只需要过渡动画。

这是一个非常基本的示例,完全不使用 JS:

body {
  background-color: #ccc;
}

.card {
  width: 150px;
  padding: 0;
  margin: 0;
  background-color: #fff;
  position: absolute;
  top: 0: left: 0;
  z-index: 1;
  
  /* Transition properties mean changes to them are animated */
  transition-property: transform;
  transition-timing-function: ease-in-out;
  transition-duration: 500ms;
  transform-origin: top left;
}

.card>img {
  width: 150px;
  height: 150px;
  margin: 0;
  padding: 0;
}

.card>.content {
  width: 150px;
  height: 50px;
  background-color: #fff;
  margin: 0;
}


/* This is only for the purposes of this demo.
 * In production you'd have an underlying grid layout and JS to figure out the position */
.card:nth-of-type(2) {
  left: 175px;
}

.card:nth-of-type(3) {
  top: 230px;
}

.card:nth-of-type(4) {
  top: 230px;
  left: 175px;
}


/* On hover transform the card to full size and translate it to the top left
 * Note that translate comes before scale. */
.card:nth-of-type(1):hover {
  transform: scale(2.1667);
  z-index: 2;
}

.card:nth-of-type(2):hover {
  transform: translate(-175px, 0) scale(2.1667);
  z-index: 2;
}

.card:nth-of-type(3):hover {
  transform: translate(0, -230px) scale(2.1667);
  z-index: 2;
}

.card:nth-of-type(4):hover {
  transform: translate(-175px, -230px) scale(2.1667);
  z-index: 2;
}
<div class="card">
  <img src="http://via.placeholder.com/325/F50057/ffffff">
  <div class="content"></div>
</div>

<div class="card">
  <img src="http://via.placeholder.com/325/F44336/ffffff">
  <div class="content"></div>
</div>

<div class="card">
  <img src="http://via.placeholder.com/325/1DE9B6/000000">
  <div class="content"></div>
</div>

<div class="card">
  <img src="http://via.placeholder.com/325/FFEB3B/000000">
  <div class="content"></div>
</div>

基本技巧是使用 CSS transformtranslatescale - 这些属性可以由显卡处理,因此即使在移动设备上也能保持动画流畅。

请注意,CSS 相当笨拙——我这样做只是为了表明它可以使用纯 CSS 来完成。在实践中,您将需要一些 JS 来设置偏移属性、连接点击事件等。

另一个技巧(我在这里没有做过)是向后缩放动画 - 从全尺寸控件开始,然后将 translate/scale 向下缩小到它似乎开始的位置。当用户点击在它上面删除transform - 这使浏览器不必在开始动画之前重新计算完整大小的对象的DOM。

【讨论】:

  • 这很酷!然而它不符合我的需要。在将列表与项目反应时,重点关注的项目是两个独立的组件,所以我不能轻易地做到这一点,就像你的例子中所示。
  • @Lucio 可以,您只需要在动画播放完毕后额外执行一个步骤即可换入 item 组件。或者你让 item 组件同时处理展开的细节和列表视图,然后它进行转换。无论哪种情况,这都是您在网络中进行这种转换的方式。
【解决方案2】:

我不确定我是否正确理解了这个问题,因为我不知道 Android 框架。这是我基于 ReactJS 知识的解决方案:

步骤:

  1. 维护 2 个状态变量:CurrentMode & NextMode。可能的值为1 & 2
  2. 点击相册将NextMode更改为2。在代码中比较CurrentModeNextMode 的值。如果CurrentMode NextMode 则相应地设置大小。
  3. 类似地,当CurrentMode > NextMode 时,相应地设置大小。

【讨论】:

    【解决方案3】:

    您可以使用 mauerwerk 做到这一点:https://github.com/drcmda/mauerwerk

    它基本上是一个网格,其中每个单元格都会获得一个状态,无论它是处于缩略图还是打开模式。您可以使用此状态在内容之间切换或转换,是否要淡化它们或让部分站立由您决定。还有一个额外的切换功能,您可以使用它来切换单元格的打开/关闭。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多