用CSS实现一个简单的盒子变化效果

1,076 阅读1分钟

最近看了一些作者在掘金上写CSS效果,自己抽空也写了一个,提供一个对象,方便之后拿来直接使用。

代码如下:

简单说下实现原理

我们使用一个大的盒子 parentEl,里边比如分成了3*3的盒子(box),我们动态的创建里边的小盒子。


for (var i = 0; i < this.row; i++) {
    for (var j = 0; j < this.col; j++) {
      var box = document.createElement('div');
      box.classList.add('box');
      box.style.width = this.boxWid + 'px';
      box.style.height = this.boxHei + 'px';
      this.addTransition(box, transtion); // 添加动画效果
      this.parentEl.appendChild(box);
    }
  }

企业微信20230214-125723@2x.png

我们设置小盒子的宽度和高度就是用大盒子除以行(row)和列(col)要分的块数。

  this.parentEl = document.getElementById(id);
  
  this.parentElWidth = this.parentEl.clientWidth;
  this.parentElHeight = this.parentEl.clientHeight;
  this.boxWid = this.parentElWidth / this.col;
  this.boxHei = this.parentElHeight / this.row;

接下来就是设置背景了,这里我们主要就是关注的是背景的偏移量,也就是说 backgroundPosition 属性

box.style.backgroundPosition = `${-j * this.boxHei}px ${-i * this.boxWid}px`;

我实现每个小盒子的动画效果主要是通过CSS去实现的。

.boxes.big .rotate {
  transform: rotateZ(360deg);
}

.boxes.big .rotateScale {
  transform: rotateZ(360deg) scale(1.4);
}

接下来就是添加动态变化的方法

TransformBox.prototype.scrollBig = function () {
  console.log('scrollBig');
  this.parentEl.classList.add('big');
  this.setBigBox();
}

TransformBox.prototype.toggleScroll = function () {
  console.log('toggleScroll');
  this.parentEl.classList.toggle("big");
  if (this.parentEl.classList.contains("big")) {
    this.setBigBox();
  } else {
    this.parentEl.style.width = this.parentElWidth + 'px';
    this.parentEl.style.height = this.parentElHeight + 'px';
  }
}
TransformBox.prototype.setBigBox = function () {
  const outContainer = document.querySelector('.big');
  outContainer.style.width = this.parentElWidth + this.boxWid - 1 + 'px';
  outContainer.style.height = this.parentElHeight + this.boxHei - 1 + 'px';
}

这里其实是添加了两个方法,scrollBig只是展开的方法,toggleScroll这个方法是展开和收回来回切换的效果。 原理就是动态的给父级盒子增加一个class名称big,并且设置盒子大小。这里需要注意的地方就是防止换行,所以我么设置外层盒子的大小不能大于原始大小加上小盒子。

之后如果想增加别的效果可以在addTransition这个方法里边加入名称。在css文件里边加入对应的效果。

TransformBox.prototype.addTransition = function (el, transtion) {
  // console.log('rrrr', transtion);
  const transtionName = transtion || 'rotate'
  const transtionMap = {
    rotate: 'rotate',
    rotateScale: 'rotateScale'
  }
  el.classList.add(transtionMap[transtionName]);
}

下面附上html代码

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>3Dbox</title>
        <link rel="stylesheet" href="./3dbox.css" />
    </head>
    <body>
        <div class="boxes" id="boxes"></div>
        <button onclick="toggleTransform()">切换</button>
    </body>
    <script src="./3dbox.js"></script>
    <script>
        var instance = new TransformBox("boxes", {
            url: "https://media.giphy.com/media/EZqwsBSPlvSda/giphy.gif",
            // url: "/Users/guosheng/Desktop/vidio.png",
            col: 4,
            row: 4,
            // transtion: "rotateScale",
        });

        function toggleTransform() {
            instance.toggleScroll();
        }
    </script>
</html>

可以通过直接创建TransformBox实例来简单的实现了.