欢迎大家访问我的个人网站 萌萌的IT人,后续所有的文章都会在此发布
--------------------------------------------------------------------------------------------
在第一部分中介绍了如何使用ASP.net Web API和Entity Framework实现服务器端程序,这篇博客将讲述如何使用JQuery从服务器获取数据并利用WebGL/Three.Js来实现浏览器端魔幻球的渲染。
本文地址:http://www.cnblogs.com/junqilian/archive/2013/03/14/2958698.html
这部分比较简单,就是一个html页面,为了方便,我就利用服务器端ASP.NET MVC中的view – index.cshtml好了。在这个文件中我要添加一些Javascript代码来以REST的方式从服务器获取数据,然后渲染魔幻球。Web页面中利用JavaScript与服务器进行通信,JQuery是很好的选择,实际上JQuery也已经包含在了ASP.NET MVC里面。对于WebGL的渲染,我选用了一个流行的类库Three.Js。类库和源码都可以从GitHub上下载。 里面包含好多示例,是理解和应用Three.Js很好的学习资料。
大家也看到了,这个程序的界面非常简单,就是一个下拉框用来选择用户,还有一个div标签作为魔幻球的渲染容器:
<div id="body"><section class="featured">
<div class="content-wrapper">
<div>
<select id="sel_userName" >
<option value="All_Users">Select a User Name</option>
</select>
</div>
</div>
</section>
<section class="content-wrapper main-content clear-fix">
>
<div id="Containner" style="height:500px; width:800px;
background-color:black;" ></div>
</section>
</div>
首先在document Ready的时候从服务器请求可用的用户列表。这里我使用JQuery发送Ajax请求到“api/AcadCommands”来获取所有的用户命令统计数据,然后从中选择用户名。当然这样效率是不高的,更好的应该是在服务器端实现一个action只返回可用的用户列表就行了。如果你感兴趣,可以自己实现这部分做练习。
$(document).ready(function () {
// Send an AJAX request
$.getJSON("api/AcadCommands/",
function (data) {
// On success, 'data' contains a list of UserCommandsHits.
$.each(data, function (key, val) {
$("select").append(
'<option value="' + val.UserName + '">'
+ val.UserName +
'</option>');
});
});
var container = document.getElementById('Containner'); initThree(container); animate();
});
在document ready的时候还要初始化ThreeJs,这部分一会儿再说。先说说当用户从下列框中选择一个用户后,我们需要获取指定用户的命令统计信息。使用JQuery发送Ajax请求到 api/AcadCommands?username=" + username:
代码如下:
$("#sel_userName").change(this, function () {var username = $(this).children('option:selected').val();
$('#txt_userName').text = username;
var commandHitDic = new Array();
$.getJSON("api/AcadCommands?username=" + username,
function (data) {
var str = data.UserName + ': $' + data.CommandHits;
cmdHits = data.CommandHits;
//add 3D objects to WebGL scene
addObjectsToScene(cmdHits);
})
.fail(
function (jqXHR, textStatus, err) {
alert(err);
$('#txt_userName').text('Error: ' + err);
});
}); //$("#sel_userName").change
获取到用户命令统计数据后,就可以用ThreeJs来渲染了,我把这部分放在一个单独的javascript文件中。直接上代码:
var
mouseX = 0, mouseY = 0,SEPARATION = 200,
AMOUNTX = 10,
AMOUNTY = 10,
camera, scene, renderer;
var magicBall = new THREE.Object3D();
var targetRotation = 0;
var targetRotationOnMouseDown = 0;
var mouseX = 0;
var mouseXOnMouseDown = 0;
///////////////////////////////
var MIN_TEXT_FONT_SIZE = 10;
var MAX_TEXT_FONT_SIZE = 80;
var MIN_LINE_LENGTH = 50;
var MAX_LINE_LENGTH = 450;
var PARTICLE_BALL_RADIUS = 850;
///////////////////////////////
//initThree();
//animate();
var minHitNumber = 0;
var maxHitNumber = 0;
function computeMinMaxHitNum(cmdHits) {
//get min and max hit number
for (var i in cmdHits) {
var hitNum = cmdHits[i].HitNumber;
var cmd = cmdHits[i].CommandName;
if (hitNum > maxHitNumber) maxHitNumber = hitNum;
if (hitNum < minHitNumber) minHitNumber = hitNum;
}
}
function getLineLength(hitNumber) {
var ratio = (hitNumber - minHitNumber) / (maxHitNumber - minHitNumber);
var lineLength = MIN_LINE_LENGTH + ratio * (MAX_LINE_LENGTH - MIN_LINE_LENGTH);
return lineLength;
}
function getTextFontSize(hitNumber) {
var ratio = (hitNumber - minHitNumber) / (maxHitNumber - minHitNumber);
var textSize = MIN_TEXT_FONT_SIZE + ratio * (MAX_TEXT_FONT_SIZE - MIN_TEXT_FONT_SIZE);
return textSize;
}
function initThree(container) {
var separation = 100, amountX = 50, amountY = 50,
particles, particle;
camera = new THREE.PerspectiveCamera(75,
container.clientWidth / container.clientHeight, 1, 10000);
camera.position.z = 1000;
scene = new THREE.Scene();
renderer = new THREE.CanvasRenderer(); //WebGLRenderer()
renderer.setSize(container.clientWidth, container.clientHeight);
container.appendChild(renderer.domElement);
//add particles just for visual effect
var PI2 = Math.PI * 2;
var material = new THREE.ParticleCanvasMaterial({
color: 0xffffff,
program: function (context) {
context.beginPath();
context.arc(0, 0, 1, 0, PI2, true);
context.closePath();
context.fill();
}
});
for (var i = 0; i < 1000; i++) {
particle = new THREE.Particle(material);
particle.position.x = Math.random() * 2 - 1;
particle.position.y = Math.random() * 2 - 1;
particle.position.z = Math.random() * 2 - 1;
particle.position.normalize();
particle.position.multiplyScalar(Math.random() * 10 + PARTICLE_BALL_RADIUS);
scene.add(particle);
}
container.addEventListener('mousedown', onContainerMouseDown, false);
container.addEventListener('touchstart', onContainerTouchStart, false);
container.addEventListener('touchmove', onContainerTouchMove, false);
}
function addObjectsToScene(cmdHits){
//prepartion
computeMinMaxHitNum(cmdHits);
if(magicBall.children.length > 0){
var obj, i;
for ( i = magicBall.children.length - 1; i >= 0 ; i -- ) {
obj = magicBall.children[ i ];
magicBall.remove(obj);
}
scene.remove(magicBall);
}
// add line and text
for (var i in cmdHits) {
var hitNum = cmdHits[i].HitNumber;
var cmdName = cmdHits[i].CommandName;
//draw line and text 3d object
var lineLength = getLineLength(hitNum);
var textSize = getTextFontSize(hitNum);
var lineAndText = creatLineAndText(lineLength, cmdName, textSize);
magicBall.add(lineAndText);
}
magicBall.rotation.x = 0;
magicBall.rotation.y = Math.PI * 2;
scene.add(magicBall);
}
function creatLineAndText(lineLength, textString, textSize) {
var lineAndText = new THREE.Object3D();
//draw line
var startVector = new THREE.Vector3(0, 0, 0);// always start from center of ball.
var endX = Math.random() * 2 - 1;
var endY = Math.random() * 2 - 1;
var endZ = Math.random() * 2 - 1;
var endVector = new THREE.Vector3(endX, endY, endZ);
endVector = endVector.normalize();
endVector.multiplyScalar(lineLength);
var geomLine = new THREE.Geometry();
geomLine.vertices.push(startVector);
geomLine.vertices.push(endVector);
var line = new THREE.Line(geomLine, new THREE.LineBasicMaterial(
{ color: Math.random() * 0xffffff, opacity: 0.5 }));
lineAndText.add(line);
//draw text
//inline function
function creatTextAt(textPosition, textString, textSize) {
var text3d = new THREE.TextGeometry(textString, {
size: textSize,
height: 5, //thickness of the text
curveSegments: 2,
font: "helvetiker"
});
text3d.computeBoundingBox();
var centerOffset = -0.5 * (text3d.boundingBox.max.x - text3d.boundingBox.min.x);
var textMaterial = new THREE.MeshBasicMaterial(
{ color: Math.random() * 0xffffff,
overdraw: true });
text = new THREE.Mesh(text3d, textMaterial);
text.position.x = textPosition.x + centerOffset;
text.position.y = textPosition.y;
text.position.z = textPosition.z;
return text;
};
var text3D = creatTextAt(endVector, textString, textSize);
lineAndText.add(text3D);
return lineAndText;
}
function onContainerMouseDown(event) {
event.preventDefault();
var container = event.srcElement;
container.addEventListener('mousemove', onContainerMouseMove, false);
container.addEventListener('mouseup', onContainerMouseUp, false);
container.addEventListener('mouseout', onContainerMouseOut, false);
var windowHalfX = container.clientWidth / 2;
mouseXOnMouseDown = event.clientX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
function onContainerMouseMove(event) {
var container = event.srcElement;
var windowHalfX = container.clientWidth / 2;
mouseX = event.clientX - windowHalfX;
targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.02;
}
function onContainerMouseUp(event) {
var container = event.srcElement;
container.removeEventListener('mousemove', onContainerMouseMove, false);
container.removeEventListener('mouseup', onContainerMouseUp, false);
container.removeEventListener('mouseout', onContainerMouseOut, false);
}
function onContainerMouseOut(event) {
var container = event.srcElement;
container.removeEventListener('mousemove', onContainerMouseMove, false);
container.removeEventListener('mouseup', onContainerMouseUp, false);
container.removeEventListener('mouseout', onContainerMouseOut, false);
}
function onContainerTouchStart(event) {
if (event.touches.length == 1) {
event.preventDefault();
var container = event.srcElement;
var windowHalfX = container.clientWidth / 2;
mouseXOnMouseDown = event.touches[0].pageX - windowHalfX;
targetRotationOnMouseDown = targetRotation;
}
}
function onContainerTouchMove(event) {
if (event.touches.length == 1) {
event.preventDefault();
var container = event.srcElement;
var windowHalfX = container.clientWidth / 2;
mouseX = event.touches[0].pageX - windowHalfX;
targetRotation = targetRotationOnMouseDown + (mouseX - mouseXOnMouseDown) * 0.05;
}
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * .05;
camera.position.y += (-mouseY + 200 - camera.position.y) * .05;
camera.lookAt(scene.position);
//self rotate
magicBall.rotation.y += ( targetRotation - magicBall.rotation.y ) * 0.05;
//magicBall.rotation.y += 0.05;
renderer.render(scene, camera);
}
好了,到目前为止已经完成了,最后给大家提一下用到的JavaScript文件,注意这个 helvetiker_regular.typeface.js 因为我要把命令名字渲染成文本,使用了 helvetiker_regular字体,所以需要这个文件。这个文件可以在ThreeJS的下载包中找到。
<script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script><script type="text/javascript" src="../../Scripts/Three/three.js"></script>
<script type="text/javascript" src="../../Scripts/Three/Detector.js"></script>
<script type="text/javascript" src="../../Scripts/Three/fonts/helvetiker_regular.typeface.js"></script>
<script type="text/javascript" src="../../Scripts/ACV_MagicBall.js"></script>
好了,打完收工。不过到目前为止,这个程序还是运行在本机的一个aspnet站点,下一步就是把他搬到windows Azure云端去了。下回再说。
相关推荐
AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令AutoCAD命令
autocad命令全集autocad命令全集autocad命令全集autocad命令全集autocad命令全集
AutoCAD命令快捷键大全
AUTOCAD命令大全,该软件的各种常用命令,让你轻松绘图。
AUTO CAD命令快捷方式,作用大,不解释
AutoCAD命令与系统变量 AutoCAD命令与系统变量
详细的AUTOCAD命令大全
AutoCAD 命令大全 TXT word pdf 格式 按字母顺序排列
247 SCRIPT SCR 自动批处理AutoCAD命令 248 SECTION SEC 生成剖面 249 SELECT 选择实体 250 SETUV 设置渲染实体几何特性 251 SETVAR SET 设置AutoCAD系统变量 252 SHADE SHA 着色处理 253 SHAPE 插入形文件...
AUTOCAD的各种专业工具 AUTOCAD实用工具 AUTOCAD新命令 AUTOCAD字体修复 CAD图形到Word转换工具 CAD转Word工具 制图工具WCAD(表格) 图元精简程序
AutoCAD 简化命令AutoCAD 简化命令AutoCAD 简化命令AutoCAD 简化命令
autocad命令参考手册autocad命令参考手册autocad命令参考手册autocad命令参考手册autocad命令参考手册
AUTOCAD命令大全里面记载了大量的autocad常用命令,熟记这些命令将对您高效运用该软件有很大帮助
AutoCAD命令大全(内包含全命令及缩写命令)
AutoCAD命令大全,vba平台,自动化
autocad常用命令图标,快捷键,命令说明
作使用的autocad命令,大家都来看看,多血虚i
autocad2010命令大全,很全很实用的autocad学习资料
在AutoCAD二次开发过程中,一般都是开发自定义的命令,然后在菜单栏/工具栏/菜单面板中添加对应的菜单,通过点击菜单调用开发的命令。 对于实现以上问题,传统的做法就是在二次开发类库中开发一个命令方法,并且...
AutoCAD命令参考(英文版).pdf AutoCAD Command Reference(总共2064页) Chapter 1 3D Commands Chapter 2 A Commands Chapter 3 B Commands Chapter 4 C Commands Chapter 5 D Commands Chapter 6 E Commands ...