div背景 css网格背景_如何为背景图像网格创建运动悬停效果


div背景 css网格背景

div背景 css网格背景

MotionGrid_featured

View demo
查看演示
Download Source
下载源

If you follow our UI Interactions & Animations Roundups, you might have spotted this beautiful grid designed by the folks of tubik:

如果您遵循我们的UI交互和动画摘要,则可能已经发现了tubik员工设计的这个漂亮的网格:

演示地址

Previously, Zhenya Rynzhuk also designed this wonderful layout with a similar interaction:

之前, Zhenya Rynzhuk还设计了这种具有相似交互作用的出色布局:

演示地址

It’s not too complicated to implement this. I wanted to try it and in the following I’ll walk you through the relevant markup and code.

实现它并不太复杂。 我想尝试一下,下面我将引导您完成相关的标记和代码。

网格的标记和样式 (The markup and style for the grid)

The markup is simply a grid of items that have background images. I like to use this structure because it allows me to control the sizes of the images by setting their position in the grid.

标记只是具有背景图像的项目的网格。 我喜欢使用这种结构,因为它允许我通过设置图像在网格中的位置来控制图像的大小。

1
2
3
4
5
6
7
8
9
10
11
12
<div class="grid">
    <div class="grid__item pos-1">
        <div class="grid__item-img" style="background-image:url(img/1.jpg);"></div>
    </div>
    <div class="grid__item pos-2">
        <div class="grid__item-img" style="background-image:url(img/2.jpg);"></div>
    </div>
    <div class="grid__item pos-3">
        <div class="grid__item-img" style="background-image:url(img/3.jpg);"></div>
    </div>
    ...
</div>

The grid is stretched to be a bit bigger than its parent because we want to move the items and create the illusion of an infinite plane of images.

网格被拉伸到比其父网格大一点,因为我们要移动项目并创建无限的图像平面的错觉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.grid {
    pointer-events: none;
    position: absolute;
    width: 110%;
    height: 110%;
    top: -5%;
    left: -5%;
    display: grid;
    grid-template-columns: repeat(50,2%);
    grid-template-rows: repeat(50,2%);
}

.grid__item {
    position: relative;
}

.grid__item-img {
    position: relative;
    width: 100%;
    height: 100%;
    background-size: cover;
    background-position: 50% 50%;
}

The grid is divided into 50 cells for the rows and columns. With this layout density, the position of each image element can be set precisely.

网格分为行和列的50个单元格。 利用这种布局密度,可以精确设置每个图像元素的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* Shorthand grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end */

.pos-1 {
    grid-area: 10 / 1 / 26 / 7;
}

.pos-2 {
    grid-area: 1 / 18 / 9 / 27;
}

.pos-3 {
    grid-area: 1 / 36 / 14 / 42;
}

...

Note that I use the double division structure for the possibility of moving the inner element with the background image to create the motion effect seen in demo 3. For that case, I define some extra styles:

请注意,我使用双分割结构来将内部元素与背景图像一起移动,以创建演示3中看到的运动效果。在这种情况下,我定义了一些额外的样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* If we want to move the inner image */

.grid--img .grid__item {
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    will-change: transform;
}

.grid--img .grid__item-img {
    flex: none;
    width: calc(100% + 100px);
    height: calc(100% + 100px);
    will-change: transform;
}

JavaScript (The JavaScript)

Now, leta€?s have a look at the JavaScript part. I’m using GSAP by GreenSock. We start by creating a Grid class to represent the grid of pictures:

现在,让我们看一下JavaScript部分。 我正在使用GreenSock的GSAP 。 我们首先创建一个Grid类来表示图片的网格:

1
2
3
4
5
6
7
8
9
10
11
12
13
export default class Grid {
    constructor(el) {
        this.DOM = {el: el};
        this.gridItems = [];
        this.items = [...this.DOM.el.querySelectorAll('.grid__item')];
        this.items.forEach(item => this.gridItems.push(new GridItem(item)));
       
        this.showItems();
    }
    ...
}

const grid = new Grid(document.querySelector('.grid'));

There should be an initial animation where the grid items scale up and fade in. We can add a method to the class for that. We also want the items to start at different times and for that we use the GSAP stagger option. The items will start animating from the center of the grid:

应该有一个初始动画,其中网格项会按比例放大和淡入。我们可以为此添加一个方法。 我们还希望项目在不同的时间开始,为此,我们使用GSAP stagger选项。 这些项目将从网格中心开始动画:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
showItems() {
    gsap.timeline()
    .set(this.items, {scale: 0.7, opacity: 0}, 0)
    .to(this.items, {
        duration: 2,
        ease: 'Expo.easeOut',
        scale: 1,
        stagger: {amount: 0.6, grid: 'auto', from: 'center'}
    }, 0)
    .to(this.items, {
        duration: 3,
        ease: 'Power1.easeOut',
        opacity: 0.4,
        stagger: {amount: 0.6, grid: 'auto', from: 'center'}
    }, 0);
}

Now, let’s make the items move as we move the mouse around. Each grid item will be represented by a GridItem class:

现在,让我们随着鼠标的移动来移动项目。 每个网格项将由一个GridItem类表示:

1
2
3
4
5
6
7
class GridItem {
    constructor(el) {
        this.DOM = {el: el};
        this.move();
    }
    ...
}

The position of each item in both axes should be mapped with the mouse position. So, the mouse can move from position 0 to the width or height of the window. As for the item, it’ll move in a range of [start, end] that we need to specify. We’ll be assigning random values for the start/end value so that each item moves differently from each other.

每个项目在两个轴上的位置都应与鼠标位置对应。 因此,鼠标可以从位置0移动到窗口的宽度或高度。 至于项目,它将在我们需要指定的[开始,结束]范围内移动。 我们将为开始/结束值分配随机值,以使每个项目的移动方式彼此不同。

Let’s add the move method to the GridItem class:

让我们将move方法添加到GridItem类中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
move() {
    // amount to move in each axis
    let translationVals = {tx: 0, ty: 0};
    // get random start and end movement boundaries
    const xstart = getRandomNumber(15,60);
    const ystart = getRandomNumber(15,60);
   
    // infinite loop
    const render = () => {
        // Calculate the amount to move.
        // Using linear interpolation to smooth things out.
        // Translation values will be in the range of [-start, start] for a cursor movement from 0 to the window's width/height
        translationVals.tx = lerp(translationVals.tx, map(mousepos.x, 0, winsize.width, -xstart, xstart), 0.07);
        translationVals.ty = lerp(translationVals.ty, map(mousepos.y, 0, winsize.height, -ystart, ystart), 0.07);
       
        gsap.set(this.DOM.el, {x: translationVals.tx, y: translationVals.ty});  
        requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
}

And that’s it!

就是这样!

I hope you find this helpful and please let me know your feedback via @codrops. Thank you for reading!

希望对您有所帮助,并通过@codrops告诉我您的反馈意见。 感谢您的阅读!

翻译自: https://tympanus.net/codrops/2020/06/10/how-to-create-a-motion-hover-effect-for-a-background-image-grid/

div背景 css网格背景