本文主要是介绍如何将一个幻灯片的照片平铺_如何创建平铺背景幻灯片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
如何将一个幻灯片的照片平铺
Today we’d like to show you how to recreate the background image slideshow seen on the stunning website of Serge Thoroval’s Atelier that was coded and designed by talented Jean-Christophe Suzanne and Jonathan Da Costa. If you haven’t seen the website, you should definitely go and check it out; it’s full of interesting and creative effects. The slideshow that we are recreating today, is made up of four tiles that move individually, making the image split while scaling up the new image. This combines into a really nice effect which we will re-implement today using 3D transforms, transitions and animations. In addition to that effect we’ll also add two more variations. The aim that we want to keep in mind, is to achieve a super-smooth effect experience.
今天,我们想向您展示如何重新制作由Serge Thoroval的Atelier网站制作的背景图像幻灯片,该网站由才华横溢的Jean-Christophe Suzanne和Jonathan Da Costa进行编码和设计。 如果您还没有看到该网站,则应该去看看它; 它充满了有趣和创造性的效果。 我们今天正在重新创建的幻灯片显示是由四个单独移动的图块组成的,在放大新图像的同时分割图像。 这组合在一起的效果非常好,我们今天将使用3D变换,过渡和动画重新实现。 除了这种效果外,我们还将添加另外两个变体。 我们要牢记的目标是获得超流畅的效果体验。
Note that we’ll be using very modern CSS properties, so the desired effect will only work in the newest browser versions.
请注意,我们将使用非常现代CSS属性,因此所需的效果仅在最新的浏览器版本中有效。
The images used in the demos are made with really great mobile phone PSD mockups from the team of Mockuuups.com. You can find the free iPhone 5S Mockups in this Dribbble post by Tomas Jasovsky.
演示中使用的图像是由Mockuuups.com团队使用非常出色的手机PSD样机制作的。 您可以在Tomas Jasovsky的Dribbble帖子中找到免费的iPhone 5S样机。
Let’s get started with the markup.
让我们开始标记。
标记 (The Markup)
For the slideshow we will need a special structure that will allow us to play with four different tiles, all containing the same image but with different positioning. We need to make sure that everything stretches over the full viewport since this is a “fullscreen” slideshow. We’ll define a simple initial structure that will allow us to specify which images will be visible in each panel (or slide) and then we’ll create our repeated structure for the tiles. So, initially we want something like this:
对于幻灯片放映,我们将需要一种特殊的结构,该结构将允许我们使用四个不同的图块进行播放,这些图块均包含相同的图像,但位置不同。 我们需要确保所有内容都在整个视口上延伸,因为这是“全屏”幻灯片显示。 我们将定义一个简单的初始结构,该结构将使我们可以指定在每个面板(或幻灯片)中可见的图像,然后为图块创建重复的结构。 因此,最初我们需要这样的东西:
<div id="boxgallery" class="boxgallery" data-effect="effect-1">
<div class="panel"><img src="img/1.jpg" alt="Image 1"/></div>
<div class="panel"><img src="img/2.jpg" alt="Image 2"/></div>
<div class="panel"><img src="img/3.jpg" alt="Image 3"/></div>
<div class="panel"><img src="img/4.jpg" alt="Image 4"/></div>
</div>
In order to be able to animate the image by breaking it into tiles we will need the following repeated structure for each panel:
为了能够通过将图像分成小块来对图像进行动画处理,我们需要为每个面板使用以下重复结构:
<div id="boxgallery" class="boxgallery" data-effect="effect-1">
<div class="panel current">
<div class="bg-tile">
<div class="bg-img"><img src="img/1.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/1.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/1.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/1.jpg" /></div>
</div>
</div>
<div class="panel">
<div class="bg-tile">
<div class="bg-img"><img src="img/2.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/2.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/2.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/2.jpg" /></div>
</div>
</div>
<div class="panel">
<!-- ... -->
</div>
<div class="panel">
<!-- ... -->
</div>
<nav>
<span class="prev"><i></i></span>
<span class="next"><i></i></span>
</nav>
</div>
We’ll also have to add a navigation so that we can browse through the panels. The data attribute data-effect will make it possible to define some individual variations of the effect.
我们还必须添加导航,以便我们可以浏览面板。 数据属性data-effect将使定义效果的某些单独变化成为可能。
Naturally, you might look at the structure and think, why not use background images instead of image elements? After some tries on what performs better cross-browser wise, we came to the conclusion that using a background image together with background-size can cause quite choppy transitions. Using for example, background-size: cover
can be a major source of jerkiness. Another critical thing that causes twitchy transitions (at least in Chrome) is using percentage values when translating. This might not be noticeable at first glance but when comparing with a pixel-based translation, you will be able to see an impactful difference. For that reason we will not be using classes to control the transforms, but we’ll instead do it in our script by getting the pixel values of the viewport and applying the respective translation values to the tiles’ “background images”.
自然,您可能会看一下结构并思考,为什么不使用背景图像代替图像元素? 在对跨浏览器的性能进行更好的尝试之后,我们得出的结论是,将背景图像与背景大小一起使用可能会导致断断续续的过渡。 例如,使用background-size: cover
可能是造成混乱的主要原因。 导致抽动过渡(至少在Chrome中如此)的另一个关键问题是在翻译时使用百分比值。 乍一看这可能并不明显,但是与基于像素的翻译进行比较时,您将能够看到有影响的差异。 因此,我们将不会使用类来控制转换,而是在脚本中通过获取视口的像素值并将相应的转换值应用于图块的“背景图像”来实现。
Let’s add some style to this thing.
让我们添加一些样式。
CSS (The CSS)
With the generated structure in mind, we’ll now add the style. Note that the CSS will not contain any vendor prefixes, but you will find them in the files.
考虑到生成的结构,我们现在将添加样式。 请注意,CSS将不包含任何供应商前缀,但是您可以在文件中找到它们。
First off, we are in the “fullscreen” realm, so we need to prepare our page elements for that. Setting the html
, the body
and the main container to a height of 100% will allow us to expand our slideshow to the full height of the viewport:
首先,我们处于“全屏”领域,因此我们需要为此准备页面元素。 将html
, body
和main容器设置为100%的高度将使我们能够将幻灯片扩展到视口的整个高度:
html, body, .container {
height: 100%;
}
The main wrapper and the child divisions will all be of absolute positioning and the panels will occupy all the width and height:
主包装纸和子分隔纸都将处于绝对位置,并且面板将占据所有宽度和高度:
.js .boxgallery,
.js .boxgallery div {
position: absolute;
}.js .boxgallery,
.js .panel {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Since our effects will potentially have elements moving out of their limits, we’ll make sure that nothing overflows:
由于我们的效果可能会使元素超出其范围,因此我们将确保没有溢出:
.js .boxgallery,
.bg-tile,
.bg-img {
overflow: hidden;
}
When looking at the effect of Serge Thoroval’s slideshow, you’ll notice that when navigating, the newly revealed slide scales up. We’ll be using 3D transforms wherever we can so we’ll need to add some perspective to the slide wrapper so that we can then translate the individual tiles on the z-Axis, i.e. make them scale down visually:
查看Serge Thoroval幻灯片的效果时,您会注意到在导航时,新显示的幻灯片会放大。 我们将在任何可能的地方使用3D变换,因此我们需要向幻灯片包装器添加一些透视图,以便随后我们可以平移z轴上的单个图块,即,使其在视觉上缩小:
.panel {
z-index: 0;
perspective: 1200px;
}
Next, we have to style the tiles. Since we have four tiles, each tile will be 50% high and wide:
接下来,我们必须对图块进行样式设置。 由于我们有四个图块,因此每个图块的高度和宽度将为50%:
.bg-tile {
width: 50%;
height: 50%;
}
Let’s position each tile:
让我们放置每个图块:
.bg-tile:nth-child(2),
.bg-tile:nth-child(4) {
left: 50%;
}.bg-tile:nth-child(3),
.bg-tile:nth-child(4) {
top: 50%;
}
The inner division with the class bg-img will occupy the whole tile:
类bg-img的内部划分将占据整个图块:
.bg-img {
width: 100%;
height: 100%;
background: #999;
}
In order to place the images in a way that only shows one complete image per tile, we need to set it’s width and height to the double. Using percentages on both, width and height will distort our image so we need to make sure that we maintain the aspect ration. We can do that by setting only one of the dimensions to 200% and let the other one be defined automatically. But which one can we set? Well, that all depends on whether our viewport is more wide than high and vice versa. Fortunately, we have media queries and one expression in particular will help us do exactly what we want: min-aspect-ratio
. This allows us to simply take the real size of our images as ratio value (width/height) and define, when we want the width and when the height to be calculated automatically:
为了以每张图块仅显示一个完整图像的方式放置图像,我们需要将其宽度和高度设置为两倍。 在宽度和高度上都使用百分比会使图像失真,因此我们需要确保保持宽高比。 我们可以通过仅将一个尺寸设置为200%并自动定义另一个尺寸来做到这一点。 但是我们可以设置哪一个呢? 好吧,这完全取决于我们的视口是否比高视口更宽,反之亦然。 幸运的是,我们有媒体查询,尤其是一个表达式可以帮助我们准确地完成我们想要的事情: min-aspect-ratio
。 这使我们可以简单地将图像的实际大小作为比率值(宽度/高度)并定义何时需要宽度和何时自动计算高度:
.bg-img img {
position: absolute;
display: block;
height: 200%;
}@media screen and (min-aspect-ratio: 1280/850) {
.bg-img img {
width: 200%;
height: auto;
}
}
You can fine-tune this method by also adding width/height expressions in order to offer the desired viewing experience of the image for any screensize. For out slideshow, this little simple method will do.
您还可以通过添加宽度/高度表达式来微调此方法,以便为任何屏幕尺寸提供所需的图像观看体验。 对于幻灯片放映,可以使用这种简单的方法。
Each image needs to be positioned as well:
每个图像也需要定位:
.bg-tile:nth-child(2) .bg-img img,
.bg-tile:nth-child(4) .bg-img img {
left: -100%;
}.bg-tile:nth-child(3) .bg-img img,
.bg-tile:nth-child(4) .bg-img img {
top: -100%;
}
The navigational arrows have the “Fill Path” style from the Arrow Navigation Styles.
导航箭头具有“箭头导航样式”中的“填充路径”样式。
So let’s define what happens when we navigate. First of all, we need to set a z-index value to the current panel so that it stays on top of all the others. Since we’ve previously set all out panels’ z-indices to 0, we can use a value like 1. But because we’ll have a current panel but also one that needs to be shown directly under it (the next or previous one), we’ll set the z-indices as follows:
因此,让我们定义导航时会发生什么。 首先,我们需要为当前面板设置一个z-index值,以使其位于所有其他面板的顶部。 由于我们先前已将所有面板的z索引设置为0,因此我们可以使用类似1的值。但是,因为我们将有一个当前面板,但还有一个面板需要直接显示在其下方(下一个或上一个面板) ),我们将按如下所示设置z索引:
.panel.current {
z-index: 2;
}.panel.active {
z-index: 1;
}
This will guarantee that the current one is on top of any other and the newly coming one is directly under it.
这将确保当前的一个位于其他任何一个之上,而新近出现的则位于它的正下方。
Considering that we will add the individual 3D transforms to each tile’s bg-img in our JavaScript (remember, we want to use pixel-based values for which we need the window width and height), we still want to set some things in our style sheet, like the transition itself and the animation for the new panel. So, let’s define a transition on the transform property with a time and easing function that fit nicely:
考虑到我们将在JavaScript中将单独的3D变换添加到每个图块的bg-img中(请记住,我们要使用需要窗口宽度和高度的基于像素的值),因此我们仍想在样式中设置一些内容工作表,例如过渡本身和新面板的动画。 因此,让我们使用非常合适的时间和缓动函数在transform属性上定义一个过渡:
.panel.current .bg-img {
transition: transform 1.1s ease-in-out;
}
For the first effect (the one that we are trying to recreate) and the second one (which moves the tiles to the outside), we want the following panel to appear with a scale down effect:
对于第一个效果(我们尝试重新创建的效果)和第二个效果(将图块移到外部),我们希望以下面板以缩小效果显示:
.boxgallery[data-effect="effect-1"] .panel.active .bg-tile,
.boxgallery[data-effect="effect-2"] .panel.active .bg-tile {
animation: scaleDown 1.1s ease-in-out;
}@keyframes scaleDown {
from { transform: translate3d(0,0,380px); }
to { transform: translate3d(0,0,0); }
}
The following variation of the effect looks really great when adding a little delay to each tile’s child and making everything a bit faster with a nice cubic-bezier timing function. This variation will make the tiles move to the sides when navigating next and up/down when navigating to the previous panel:
当给每个图块的孩子增加一点延迟,并通过良好的三次方贝塞尔曲线计时功能使一切变得更快时,以下效果变化看起来确实很棒。 这种变化将使磁贴在下一个导航时移动到侧面,并在上一个导航面板时向上/向下移动:
/* Variation 2 */.boxgallery[data-effect="effect-2"] .panel.current .bg-img {
transition: transform 0.9s cubic-bezier(0.7,0,0.3,1);
}.boxgallery[data-effect="effect-2"] .panel.current .bg-tile:nth-child(2) .bg-img {
transition-delay: 0.15s;
}.boxgallery[data-effect="effect-2"] .panel.current .bg-tile:nth-child(3) .bg-img {
transition-delay: 0.3s;
}.boxgallery[data-effect="effect-2"] .panel.current .bg-tile:nth-child(4) .bg-img {
transition-delay: 0.45s;
}
The third variation serves as an example on how to use an overlay that will fade out once a new panel is revealed:
第三个变体作为一个示例,说明如何使用叠加层,一旦显示新面板,该叠加层将逐渐消失:
/* Variation 3 */.boxgallery[data-effect="effect-3"] .panel::after {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.8);
content: '';
transition: opacity 1.1s ease-in-out;
}.boxgallery[data-effect="effect-3"] .panel.current::after,
.boxgallery[data-effect="effect-3"] .panel.active::after {
opacity: 0;
}.boxgallery[data-effect="effect-3"] .panel.current::after {
transition: none;
}
We’ll also use the same cubic-bezier timing function and define some delays (same as before).
我们还将使用相同的三次贝塞尔定时函数,并定义一些延迟(与之前相同)。
.boxgallery[data-effect="effect-3"] .panel.current .bg-img {
transition: transform 1.1s cubic-bezier(0.7,0,0.3,1);
}.boxgallery[data-effect="effect-3"] .panel.current .bg-tile:nth-child(2) .bg-img {
transition-delay: 0.15s;
}.boxgallery[data-effect="effect-3"] .panel.current .bg-tile:nth-child(3) .bg-img {
transition-delay: 0.3s;
}.boxgallery[data-effect="effect-3"] .panel.current .bg-tile:nth-child(4) .bg-img {
transition-delay: 0.45s;
}
After we go through the JavaScript, make sure to play with these values and add a new effect, there are so many possibilities!
在浏览完JavaScript之后,请确保使用这些值并添加新的效果,其中有很多可能性!
JavaScript (The JavaScript)
Like mentioned before, we’ve opted to manipulate the translation values directly in the JS, using pixel-based values obtained from the viewport width and height for a smoother transition. Alternatively, we could set classes and define everything in the stylesheet using percentage-based values, but this leaves us with jerky transitions. (In case we would use an effect that does not need any of those viewport dependent values (e.g. opacity, absolute values, scale, etc.) we could definitely go with the class-based solution.)
如前所述,我们选择直接在JS中操纵转换值,使用从视口的宽度和高度获得的基于像素的值来实现更平滑的过渡。 另外,我们可以设置类并使用基于百分比的值定义样式表中的所有内容,但这使我们处于生涩的过渡状态。 (如果我们使用不需要任何依赖于视口的值(例如,不透明度,绝对值,比例等)的效果,我们绝对可以使用基于类的解决方案。)
Let’s have a look at the init function. We will start by defining the transforms that we want to apply to the panels as we navigate the slideshow. We need to specify which transforms we want the panels to have for both directions (navigate to the right and left, next and previous, respectively). Let’s define a fitting structure which we set in the setTransforms function.
让我们看一下init函数。 我们将首先定义在浏览幻灯片时要应用于面板的变换。 我们需要指定我们希望面板在两个方向上都具有哪些变换(分别导航到左右,下一个和上一个)。 让我们定义一个在setTransforms函数中设置的拟合结构。
Next, we get the effect type from the data-effect attribute. This will indicate which transforms we pick from the previously created structure. We then initialize and cache some variables and finally we create the necessary DOM structure for our four boxes. For that, the image in each panel is replaced by four divisions, each one having an image element with the same src
like the image. We also add the nav
element at this point.
接下来,我们从data-effect属性获得效果类型。 这将表明我们从先前创建的结构中选择了哪些变换。 然后,我们初始化并缓存一些变量,最后为四个盒子创建必要的DOM结构。 为此,将每个面板中的图像替换为四个部分,每个部分都具有一个与该图像具有相同src
的图像元素。 此时,我们还添加了nav
元素。
BoxesFx.prototype._init = function() {
// set transforms configuration
this._setTransforms();
// which effect
this.effect = this.el.getAttribute( 'data-effect' ) || 'effect-1';
// check if animating
this.isAnimating = false;
// the panels
this.panels = [].slice.call( this.el.querySelectorAll( '.panel' ) );
// total number of panels (4 for this demo)
//this.panelsCount = this.panels.length;
this.panelsCount = 4;
// current panel´s index
this.current = 0;
classie.add( this.panels[0], 'current' );
// replace image with 4 divs, each including the image
var self = this;
this.panels.forEach( function( panel ) {
var img = panel.querySelector( 'img' ), imgReplacement = '';
for( var i = 0; i < self.panelsCount; ++i ) {
imgReplacement += '<div class="bg-tile"><div class="bg-img"><img src="' + img.src + '" /></div></div>'
}
panel.removeChild( img );
panel.innerHTML = imgReplacement + panel.innerHTML;
} );
// add navigation element
this.nav = document.createElement( 'nav' );
this.nav.innerHTML = '<span class="prev"><i></i></span><span class="next"><i></i></span>';
this.el.appendChild( this.nav );
// initialize events
this._initEvents();
}
The translate values are calculated using the window width and height. We also add 10 pixels so that the transitions don’t really end in the last visible point, but rather a bit further, adding some more smoothness to the effects:
使用窗口的宽度和高度计算转换值。 我们还添加了10个像素,这样过渡实际上不会在最后一个可见点结束,而是更远一点,为效果添加了更多的平滑度:
BoxesFx.prototype._setTransforms = function() {
this.transforms = {
'effect-1' : {
'next' : [
'translate3d(0, ' + (win.height/2+10) + 'px, 0)', // transforms for panel 1
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)', // transforms for panel 2
'translate3d(' + (win.width/2+10) + 'px, 0, 0)', // transforms for panel 3
'translate3d(0, -' + (win.height/2+10) + 'px, 0)' // transforms for panel 4
],
'prev' : [
'translate3d(' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(0, ' + (win.height/2+10) + 'px, 0)',
'translate3d(0, -' + (win.height/2+10) + 'px, 0)',
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)'
]
},
'effect-2' : {
'next' : [
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(' + (win.width/2+10) + 'px, 0, 0)'
],
'prev' : [
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)'
]
},
'effect-3' : {
'next' : [
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)'
],
'prev' : [
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)'
]
}
};
}
Next thing to do is to initialize the events on the navigation arrows, and the window resize event (we need to reset our transforms):
接下来要做的是初始化导航箭头上的事件以及窗口调整大小事件(我们需要重置变换):
BoxesFx.prototype._initEvents = function() {
var self = this, navctrls = this.nav.children;
// previous action
navctrls[0].addEventListener( 'click', function() { self._navigate('prev') } );
// next action
navctrls[1].addEventListener( 'click', function() { self._navigate('next') } );
// window resize
window.addEventListener( 'resize', function() { self._resizeHandler(); } );
}
Let’s take a look at the navigate function. First, we get both, the current and the “upcoming” panels. We also need to reset the current variable value depending on the navigation action we take. Next, we add the active class to the current panel in order to trigger any animation or transition the element might have (as previously defined in our style sheet). We finally set the transforms to the current panel which we defined before. This should make the four panels animate and cause the next slide to reveal. We just need to make sure we reset both, the classes we’ve added and the transforms on the elements. We do that once all the transitions for all four panels have finished:
让我们看一下导航功能。 首先,我们得到了当前面板和“即将到来的”面板。 我们还需要根据我们执行的导航操作来重置当前变量值。 接下来,我们将活动类添加到当前面板中,以触发元素可能具有的任何动画或过渡(如先前在样式表中定义的那样)。 最后,我们将转换设置为之前定义的当前面板。 这应该使四个面板具有动画效果,并使下一张幻灯片显示出来。 我们只需要确保同时重置已添加的类和元素上的转换即可。 一旦完成所有四个面板的所有转换,我们便会这样做:
BoxesFx.prototype._navigate = function( dir ) {
if( this.isAnimating ) return false;
this.isAnimating = true;var self = this, currentPanel = this.panels[ this.current ];if( dir === 'next' ) {
this.current = this.current < this.panelsCount - 1 ? this.current + 1 : 0;
}
else {
this.current = this.current > 0 ? this.current - 1 : this.panelsCount - 1;
}// next panel to be shown
var nextPanel = this.panels[ this.current ];
// add class active to the next panel to trigger its animation
classie.add( nextPanel, 'active' );
// apply the transforms to the current panel
this._applyTransforms( currentPanel, dir );// let´s track the number of transitions ended per panel
var cntTransTotal = 0,
// transition end event function
onEndTransitionFn = function( ev ) {
if( ev && !classie.has( ev.target, 'bg-img' ) ) return false;// return if not all panel transitions ended
++cntTransTotal;
if( cntTransTotal < self.panelsCount ) return false;if( support.transitions ) {
this.removeEventListener( transEndEventName, onEndTransitionFn );
}// remove current class from current panel and add it to the next one
classie.remove( currentPanel, 'current' );
classie.add( nextPanel, 'current' );
// reset transforms for the currentPanel
self._resetTransforms( currentPanel );
// remove class active
classie.remove( nextPanel, 'active' );
self.isAnimating = false;
};if( support.transitions ) {
currentPanel.addEventListener( transEndEventName, onEndTransitionFn );
}
else {
onEndTransitionFn();
}
}BoxesFx.prototype._applyTransforms = function( panel, dir ) {
var self = this;
[].slice.call( panel.querySelectorAll( 'div.bg-img' ) ).forEach( function( tile, pos ) {
tile.style.WebkitTransform = self.transforms[self.effect][dir][pos];
tile.style.transform = self.transforms[self.effect][dir][pos];
} );
}BoxesFx.prototype._resetTransforms = function( panel ) {
[].slice.call( panel.querySelectorAll( 'div.bg-img' ) ).forEach( function( tile ) {
tile.style.WebkitTransform = 'none';
tile.style.transform = 'none';
} );
}
And that's it! I hope you enjoyed this tutorial and find it useful!
就是这样! 我希望您喜欢本教程并发现它有用!
翻译自: https://tympanus.net/codrops/2014/06/11/how-to-create-a-tiled-background-slideshow/
如何将一个幻灯片的照片平铺
这篇关于如何将一个幻灯片的照片平铺_如何创建平铺背景幻灯片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!