使用jQuery动态构建元素的3D圆柱体 [英] Dynamically build a 3d cylinder of elements with jquery

查看:160
本文介绍了使用jQuery动态构建元素的3D圆柱体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:我已经对此进行了很多清理(我认为),但情况似乎还更糟.这是一个带有一些附加功能的小提琴,例如使用箭头键旋转对象.这样可以更轻松地发现问题.

https://jsfiddle.net/scottbeeson/ue4c7ocj/


原始问题

我正在尝试基于教程和演示在这里.我正在尝试以尽可能基本和动态的方式开始,但并没有(从字面上看)融为一体.

这就是我所拥有的:

 function RotaMenu ( e ) {
	this.element = e;
	this.rotation = 0;
	this.panelCount = this.element.children().length;
	this.panelSize = $(this.element).outerHeight();
	this.theta = 360 / this.panelCount;
	this.radius = Math.round( ( this.panelSize / 2) / Math.tan( Math.PI / this.panelCount ) );
	console.log("Created new menu: panelCount=" + this.panelCount + ", panelSize=" + this.panelSize + ", theta=" + this.theta + ", radius=" + this.radius);
}

RotaMenu.prototype.update = function() {
	this.theta = 360 / this.panelCount;
	this.radius = Math.round( ( this.panelSize / 2) / Math.tan( Math.PI / this.panelCount ) );
	for ( i = 0; i < this.panelCount; i++ ) {
		panel = $(this.element).children()[i];
		angle = this.theta * i;
		$(panel).css('transform','rotateX(' + angle + 'deg) rotateY(0deg) translateZ(' + this.radius + 'px)');
	}
};


$(function() {
	var mainmenu = new RotaMenu($('#mainmenu'));
	mainmenu.update();
}); 

 .rmenu {
  margin-top: 100px;
}
.rmenu div {
  border: 1px solid gray;
  width: 100px;
  height: 20px;
} 

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mainmenu" class="rmenu">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
  </div> 

这里是6个孩子的样子.我在做什么错了?

解决方案

已更新

所以现在我在计算机上看到了为什么以前的版本需要调整我之前添加的半径.这是因为您是根据高度正确计算的,所以您的目标当然是垂直的.只有两个较小的更改可以实现这种差异:rotateX代替 Y 并使用您之前使用的正确半径计算.为了反映这些变化,我对答案进行了编辑.我相信这将是您想要的.

解决方案

我认为您的主要问题是缺少一些CSS,这使得更容易建立基本结构,因此可以对其进行调试.您还需要外部容器,以便可以为透视图添加摄影机点,以使变换看起来很漂亮,否则它将看起来很平坦.

这是我的示例: https://jsfiddle.net/8ymm7xu6/2/

重要的CSS:

.rmenu {
  position: absolute;
  transform-style: preserve-3d;
  margin-top: 100px;
}
.rmenu div {
  border: 1px solid gray;
  width: 100px;
  height: 20px;
  margin: 0;
  position: absolute;
}
.container {
  position: relative;
  perspective: 1000px;
  display: flex;
  align-items: center;
  justify-content: center;
}

和html更改

<section class="container">
  <div id="mainmenu" class="rmenu">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
  </div>  
</section>

jquery也有所更改:

function RotaMenu ( e ) {
    this.element = e;
    this.rotation = 0;
    this.panelCount = this.element.children().length;
    this.panelSize = $(this.element).children().first().outerHeight();
    this.theta = 360 / this.panelCount;
    this.radius = Math.round( ( this.panelSize / 2) / Math.tan( Math.PI / this.panelCount ) )
    console.log("Created new menu: panelCount=" + this.panelCount + ", panelSize=" + this.panelSize + ", theta=" + this.theta + ", radius=" + this.radius);
}

RotaMenu.prototype.update = function() {
    for ( i = 0; i < this.panelCount; i++ ) {
        panel = $(this.element).children()[i];
        angle = Math.round(this.theta * i);
        $(panel).css('transform','rotateX(' + angle + 'deg) translateZ(' + this.radius + 'px)');
    }
};


$(function() {
    var mainmenu = new RotaMenu($('#mainmenu'));
    mainmenu.update();
});

  • panelSize需要离开面板,而不是面板容器
  • 半径需要增加panelCount
  • 没有轴外旋转(至少现在还没有!)

UPDATE: I've cleaned this up a lot (I think), but it also seems to be worse. Here is a fiddle with some added features like using arrow keys to rotate the object. This makes it easier to see the problems.

https://jsfiddle.net/scottbeeson/ue4c7ocj/


original question

I'm trying to create a 3D vertical carousel dynamically using JQuery, based on the tutorial and demo here. I'm trying to start out as basic and dynamic as possible, but it's not coming together (literally).

Here is what I have:

function RotaMenu ( e ) {
	this.element = e;
	this.rotation = 0;
	this.panelCount = this.element.children().length;
	this.panelSize = $(this.element).outerHeight();
	this.theta = 360 / this.panelCount;
	this.radius = Math.round( ( this.panelSize / 2) / Math.tan( Math.PI / this.panelCount ) );
	console.log("Created new menu: panelCount=" + this.panelCount + ", panelSize=" + this.panelSize + ", theta=" + this.theta + ", radius=" + this.radius);
}

RotaMenu.prototype.update = function() {
	this.theta = 360 / this.panelCount;
	this.radius = Math.round( ( this.panelSize / 2) / Math.tan( Math.PI / this.panelCount ) );
	for ( i = 0; i < this.panelCount; i++ ) {
		panel = $(this.element).children()[i];
		angle = this.theta * i;
		$(panel).css('transform','rotateX(' + angle + 'deg) rotateY(0deg) translateZ(' + this.radius + 'px)');
	}
};


$(function() {
	var mainmenu = new RotaMenu($('#mainmenu'));
	mainmenu.update();
});

.rmenu {
  margin-top: 100px;
}
.rmenu div {
  border: 1px solid gray;
  width: 100px;
  height: 20px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mainmenu" class="rmenu">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
  </div>

Here is what it looks like with 6 children. What am I doing wrong?

解决方案

updated

So now I see on my computer why the version you had before needed the adjustment to radius that I had added earlier. This is because you were correctly calculating based on the height, and of course your goal was vertical. There's only two minor changes to effect this difference: rotateX instead of Y and use the correct radius calculation that you had before. Reflecting those changes I have edited the answer. I believe this will be what you are looking for.

solution

I think your main issue is that you are missing some css that makes it easier to get the basic structure up so you can debug it. You also need the outer container so you can add a camera point for the perspective so the transform looks pretty, otherwise it will look flat.

here's my sample: https://jsfiddle.net/8ymm7xu6/2/

important CSS:

.rmenu {
  position: absolute;
  transform-style: preserve-3d;
  margin-top: 100px;
}
.rmenu div {
  border: 1px solid gray;
  width: 100px;
  height: 20px;
  margin: 0;
  position: absolute;
}
.container {
  position: relative;
  perspective: 1000px;
  display: flex;
  align-items: center;
  justify-content: center;
}

and the html change

<section class="container">
  <div id="mainmenu" class="rmenu">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
  </div>  
</section>

there were also changes to the jquery:

function RotaMenu ( e ) {
    this.element = e;
    this.rotation = 0;
    this.panelCount = this.element.children().length;
    this.panelSize = $(this.element).children().first().outerHeight();
    this.theta = 360 / this.panelCount;
    this.radius = Math.round( ( this.panelSize / 2) / Math.tan( Math.PI / this.panelCount ) )
    console.log("Created new menu: panelCount=" + this.panelCount + ", panelSize=" + this.panelSize + ", theta=" + this.theta + ", radius=" + this.radius);
}

RotaMenu.prototype.update = function() {
    for ( i = 0; i < this.panelCount; i++ ) {
        panel = $(this.element).children()[i];
        angle = Math.round(this.theta * i);
        $(panel).css('transform','rotateX(' + angle + 'deg) translateZ(' + this.radius + 'px)');
    }
};


$(function() {
    var mainmenu = new RotaMenu($('#mainmenu'));
    mainmenu.update();
});

  • panelSize needed to go off the panels, not the panels container
  • radius needed to increase by panelCount
  • no off-axis rotation (At least not yet!)

这篇关于使用jQuery动态构建元素的3D圆柱体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆