css3d 您所在的位置:网站首页 旋转木马拼接 css3d

css3d

2024-04-06 13:15| 来源: 网络整理| 查看: 265

目录 CSS 3D 转换 旋转木马 使用 JavaScript 的 3D 轮播 CSS 3D 转换 旋转木马 目录 介绍 透视 3D transform 函数 卡片翻转 立方体 盒子 旋转木马 总结 返回列表

在内容轮播方面,前端开发人员有无数的选择。我可以推荐 Flickity 吗? (备注:这是原作者的推荐,不是译者加)既然我们的浏览器具有 3D 功能,为什么不尝试创建一个真正的 3D 轮播呢?

此HTML结构采用与盒子、立方体和卡片相同的形式。让我们让它变得有趣并有一个带有 9 个面板的旋转木马。

1 2 3 4 5 6 7 8 9

现在应用基本布局样式。让我们给每个单元格彼此之间设置 20px 的间隙,在这里使用left: 10px. 每个面板的有效宽度保持为 210px。

.scene { width: 210px; height: 140px; position: relative; perspective: 1000px; }   .carousel { width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; }   .carousel__cell { position: absolute; width: 190px; height: 120px; left: 10px; top: 10px; }

下一步:旋转各个面。这个旋转木马有 9 个面。如果每个面在旋转木马上均等分布,则每个面将比上一个面多旋转 40 度 ( 360 / 9 )。

.carousel__cell:nth-child(1) { transform: rotateY( 0deg); } .carousel__cell:nth-child(2) { transform: rotateY( 40deg); } .carousel__cell:nth-child(3) { transform: rotateY( 80deg); } .carousel__cell:nth-child(4) { transform: rotateY(120deg); } .carousel__cell:nth-child(5) { transform: rotateY(160deg); } .carousel__cell:nth-child(6) { transform: rotateY(200deg); } .carousel__cell:nth-child(7) { transform: rotateY(240deg); } .carousel__cell:nth-child(8) { transform: rotateY(280deg); } .carousel__cell:nth-child(9) { transform: rotateY(320deg); }

现在向外转移。回到我们创建立方体和盒子的时候,这个translate值很容易计算,因为它等于对象的宽度、高度或深度的一半。现在有了旋转木马,我们无法立即参考尺寸。我们将通过其他方式计算移位的距离。

根据这个轮播画一个简图,我们目前知道两件事:每个面板的宽度为210px,每个面板从下一个旋转40度。如果我们将这些三角形中的一个沿其中心分开,我们就会得到一个直角三角形。

我们可以用一个基本的切线方程来确定这个图中r的长度。

这288px就是在 3D 空间中将面板平移出来的距离。

.carousel__cell:nth-child(1) { transform: rotateY( 0deg) translateZ(288px); } .carousel__cell:nth-child(2) { transform: rotateY( 40deg) translateZ(288px); } .carousel__cell:nth-child(3) { transform: rotateY( 80deg) translateZ(288px); } .carousel__cell:nth-child(4) { transform: rotateY(120deg) translateZ(288px); } .carousel__cell:nth-child(5) { transform: rotateY(160deg) translateZ(288px); } .carousel__cell:nth-child(6) { transform: rotateY(200deg) translateZ(288px); } .carousel__cell:nth-child(7) { transform: rotateY(240deg) translateZ(288px); } .carousel__cell:nth-child(8) { transform: rotateY(280deg) translateZ(288px); } .carousel__cell:nth-child(9) { transform: rotateY(320deg) translateZ(288px); }

如果我们决定改变面板的宽度或面板的数量,我们只需要将这两个变量插入到我们的方程中以获得适当的 translateZ 值。用JavaScript计算,该等式将是:

var tz = Math.round( ( cellSize / 2 ) / Math.tan( ( ( Math.PI * 2 ) / numberOfCells ) / 2 ) ); // or simplified to var tz = Math.round( ( cellSize / 2 ) / Math.tan( Math.PI / numberOfCells ) );

就像我们之前的 3D 对象一样,要显示任何一个面板,我们只需要在旋转木马上应用反向变换。

/* show fifth cell */ .carousel { transform: translateZ(-288px) rotateY(-160deg); }

在 CodePen 上编辑此演示

完整代码:

1 2 3 4 5 6 7 8 9

Previous Next

  * { box-sizing: border-box; }   body { font-family: sans-serif; }   .scene { border: 1px solid #CCC; margin: 40px 0; position: relative; width: 210px; height: 140px; margin: 40px auto; perspective: 1000px; }   .carousel { width: 100%; height: 100%; position: absolute; transform: translateZ(-288px); transform-style: preserve-3d; transition: transform 1s; }   .carousel__cell { position: absolute; width: 190px; height: 120px; left: 10px; top: 10px; border: 2px solid black; line-height: 116px; font-size: 80px; font-weight: bold; color: white; text-align: center; }   .carousel__cell:nth-child(9n+1) { background: hsla( 0, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+2) { background: hsla( 40, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+3) { background: hsla( 80, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+4) { background: hsla(120, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+5) { background: hsla(160, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+6) { background: hsla(200, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+7) { background: hsla(240, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+8) { background: hsla(280, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+0) { background: hsla(320, 100%, 50%, 0.8); }   .carousel__cell:nth-child(1) { transform: rotateY( 0deg) translateZ(288px); } .carousel__cell:nth-child(2) { transform: rotateY( 40deg) translateZ(288px); } .carousel__cell:nth-child(3) { transform: rotateY( 80deg) translateZ(288px); } .carousel__cell:nth-child(4) { transform: rotateY(120deg) translateZ(288px); } .carousel__cell:nth-child(5) { transform: rotateY(160deg) translateZ(288px); } .carousel__cell:nth-child(6) { transform: rotateY(200deg) translateZ(288px); } .carousel__cell:nth-child(7) { transform: rotateY(240deg) translateZ(288px); } .carousel__cell:nth-child(8) { transform: rotateY(280deg) translateZ(288px); } .carousel__cell:nth-child(9) { transform: rotateY(320deg) translateZ(288px); }     var carousel = document.querySelector('.carousel'); var cellCount = 9; var selectedIndex = 0;   function rotateCarousel() { var angle = selectedIndex / cellCount * -360; carousel.style.transform = 'translateZ(-288px) rotateY(' + angle + 'deg)'; }   var prevButton = document.querySelector('.previous-button'); prevButton.addEventListener( 'click', function() { selectedIndex--; rotateCarousel(); });   var nextButton = document.querySelector('.next-button'); nextButton.addEventListener( 'click', function() { selectedIndex++; rotateCarousel(); });   使用 JavaScript 的 3D 轮播

到现在为止,您可能在想为每个面板重新编写变换样式是多么无趣。你是完全正确的。3D 对象的重复性使其适合编写JavaScript脚本。我们可以将所有单调的变换样式转移到我们的 JavaScript 中,如果处理得当,这将比写在CSS里怼硬编码版本要更灵活。

在 CodePen 上编辑此演示

完整代码

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  

Cells

Previous Next

Orientation: horizontal vertical

  * { box-sizing: border-box; }   body { font-family: sans-serif; text-align: center; }   .scene { border: 1px solid #CCC; margin: 40px 0; position: relative; width: 210px; height: 140px; margin: 80px auto; perspective: 1000px; }   .carousel { width: 100%; height: 100%; position: absolute; transform: translateZ(-288px); transform-style: preserve-3d; transition: transform 1s; }   .carousel__cell { position: absolute; width: 190px; height: 120px; left: 10px; top: 10px; border: 2px solid black; line-height: 116px; font-size: 80px; font-weight: bold; color: white; text-align: center; transition: transform 1s, opacity 1s; }   .carousel__cell:nth-child(9n+1) { background: hsla( 0, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+2) { background: hsla( 40, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+3) { background: hsla( 80, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+4) { background: hsla(120, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+5) { background: hsla(160, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+6) { background: hsla(200, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+7) { background: hsla(240, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+8) { background: hsla(280, 100%, 50%, 0.8); } .carousel__cell:nth-child(9n+0) { background: hsla(320, 100%, 50%, 0.8); }   .carousel__cell:nth-child(1) { transform: rotateY( 0deg) translateZ(288px); } .carousel__cell:nth-child(2) { transform: rotateY( 40deg) translateZ(288px); } .carousel__cell:nth-child(3) { transform: rotateY( 80deg) translateZ(288px); } .carousel__cell:nth-child(4) { transform: rotateY(120deg) translateZ(288px); } .carousel__cell:nth-child(5) { transform: rotateY(160deg) translateZ(288px); } .carousel__cell:nth-child(6) { transform: rotateY(200deg) translateZ(288px); } .carousel__cell:nth-child(7) { transform: rotateY(240deg) translateZ(288px); } .carousel__cell:nth-child(8) { transform: rotateY(280deg) translateZ(288px); } .carousel__cell:nth-child(9) { transform: rotateY(320deg) translateZ(288px); }       .carousel-options { text-align: center; position: relative; z-index: 2; background: hsla(0, 0%, 100%, 0.8); }   var carousel = document.querySelector('.carousel'); var cells = carousel.querySelectorAll('.carousel__cell'); var cellCount; // cellCount set from cells-range input value var selectedIndex = 0; var cellWidth = carousel.offsetWidth; var cellHeight = carousel.offsetHeight; var isHorizontal = true; var rotateFn = isHorizontal ? 'rotateY' : 'rotateX'; var radius, theta; // console.log( cellWidth, cellHeight );   function rotateCarousel() { var angle = theta * selectedIndex * -1; carousel.style.transform = 'translateZ(' + -radius + 'px) ' + rotateFn + '(' + angle + 'deg)'; }   var prevButton = document.querySelector('.previous-button'); prevButton.addEventListener( 'click', function() { selectedIndex--; rotateCarousel(); });   var nextButton = document.querySelector('.next-button'); nextButton.addEventListener( 'click', function() { selectedIndex++; rotateCarousel(); });   var cellsRange = document.querySelector('.cells-range'); cellsRange.addEventListener( 'change', changeCarousel ); cellsRange.addEventListener( 'input', changeCarousel );       function changeCarousel() { cellCount = cellsRange.value; theta = 360 / cellCount; var cellSize = isHorizontal ? cellWidth : cellHeight; radius = Math.round( ( cellSize / 2) / Math.tan( Math.PI / cellCount ) ); for ( var i=0; i < cells.length; i++ ) { var cell = cells[i]; if ( i < cellCount ) { // visible cell cell.style.opacity = 1; var cellAngle = theta * i; cell.style.transform = rotateFn + '(' + cellAngle + 'deg) translateZ(' + radius + 'px)'; } else { // hidden cell cell.style.opacity = 0; cell.style.transform = 'none'; } }   rotateCarousel(); }   var orientationRadios = document.querySelectorAll('input[name="orientation"]'); ( function() { for ( var i=0; i < orientationRadios.length; i++ ) { var radio = orientationRadios[i]; radio.addEventListener( 'change', onOrientationChange ); } })();   function onOrientationChange() { var checkedRadio = document.querySelector('input[name="orientation"]:checked'); isHorizontal = checkedRadio.value == 'horizontal'; rotateFn = isHorizontal ? 'rotateY' : 'rotateX'; changeCarousel(); }   // set initials onOrientationChange();

我们不仅可以改变单元格的数量,我们甚至可以将旋转木马的方向从水平改为垂直。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有