前言:3D模型编辑的核心是对顶点位置和纹理颜色的编辑,这个研究的目的在于寻找一种通过编程方式直接对模型进行编辑的方法,这种编辑方法和时下流行的通过鼠标点选、拖拽进行编辑的方法之间的关系,和前端编程中“程序员编写静态网页”与“美工进行网页切图”之间的关系很相似。

前端时间,开发了一个资讯类的项目,但销售部门进行微信推广时,分享的链接直接是网页链接加分享符号,即难看又不正规,于是研究了一下微信自定义的分享功能

CSS动画:animation、transition、transform、translate傻傻分不清

2018/06/19 · CSS ·
Animation,
transform,
transition,
translate,
动画

原文出处: Vince   

一、工具用法:

未配置自义定分享时,分享的页面:图片 1

前言

在平时开发过程中,由于都是自己捣鼓玩的项目,并没有UI设计给我的设计图,更没有什么特效要求,导致对css动画一直都不是很熟悉,但是作为即将进入实习单位的萌新程序员,要时刻准备着设计师要求的各种动画,于是有了这一篇文章。

1、访问 

成功配置后:图片 2  

容易混淆的几个css属性

css属性很多,并且有些无论是字母的拼写还是字面上的意思,都容易混淆,比如我列出来的几个属性,是不是也混淆过你~

属性 含义
animation(动画) 用于设置动画属性,他是一个简写的属性,包含6个属性
transition(过渡) 用于设置元素的样式过度,和animation有着类似的效果,但细节上有很大的不同
transform(变形) 用于元素进行旋转、缩放、移动或倾斜,和设置样式的动画并没有什么关系,就相当于color一样用来设置元素的“外表”
translate(移动) translate只是transform的一个属性值,即移动。

弄清楚这几个问题,我们就可以头脑清醒的状态下去学习css的动画

图片 3

前期准备工作:

transition

什么叫过渡?字面意思上来讲,就是元素从这个属性(color)的某个值(red)过渡到这个属性(color)的另外一个值(green),这是一个状态的转变,需要一种条件来触发这种转变,比如我们平时用到的:hoever、:focus、:checked、媒体查询或者JavaScript。

先从一个简单的demo来看看transition的效果

XHTML

<!DOCTYPE html> <html lang=”en”> <head>
<title>transition</title> <style> #box { height:
100px; width: 100px; background: green; transition: transform 1s ease-in
1s; } #box:hover { transform: rotate(180deg) scale(.5, .5); }
</style> </head> <body> <div
id=”box”></div> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
  <title>transition</title>
  <style>
    #box {
      height: 100px;
      width: 100px;
      background: green;
      transition: transform 1s ease-in 1s;
    }
 
    #box:hover {
      transform: rotate(180deg) scale(.5, .5);
    }
  </style>
</head>
<body>
  <div id="box"></div>
</body>
</html>

效果:

图片 4

我们来分析这一整个过程,首先transition给元素设置的过渡属性是transform,当鼠标移入元素时,元素的transform发生变化,那么这个时候就触发了transition,产生了动画,当鼠标移出时,transform又发生变化,这个时候还是会触发transition,产生动画,所以transition产生动画的条件是transition设置的property发生变化,这种动画的特点是需要“一个驱动力去触发”,有着以下几个不足:

  1. 需要事件触发,所以没法在网页加载时自动发生
  2. 是一次性的,不能重复发生,除非一再触发
  3. 只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态
  4. 一条transition规则,只能定义一个属性的变化,不能涉及多个属性。

语法:transition: property duration timing-function delay;

描述
transition-property 规定设置过渡效果的 CSS 属性的名称
transition-duration 规定完成过渡效果需要多少秒或毫秒
transition-timing-function 规定速度效果的速度曲线
transition-delay 定义过渡效果何时开始

在场景世界坐标系的(0,-10,0),(0,0,0),(0,10,0)处各有一个绿色小球作为参考点,使用上下左右和鼠标拖动可以进行场景漫游。

1.认证公众号的appId,appSecret

animation

在官方的介绍上介绍这个属性是transition属性的扩展,弥补了transition的很多不足,我理解为animation是由多个transition的效果叠加,并且可操作性更强,能够做出复杂酷炫的效果(前提是你爱折腾),我们以一个例子来介绍animation的威力:

XHTML

<!DOCTYPE html> <html lang=”en”> <head>
<title>animation</title> <style> .box { height: 100px;
width: 100px; border: 15px solid black; animation: changebox 1s
ease-in-out 1s infinite alternate running forwards; } .box:hover {
animation-play-state: paused; } @keyframes changebox { 10% { background:
red; } 50% { width: 80px; } 70% { border: 15px solid yellow; } 100% {
width: 180px; height: 180px; } } </style> </head>
<body> <div class=”box”></div> </body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en">
 
<head>
  <title>animation</title>
  <style>
    .box {
      height: 100px;
      width: 100px;
      border: 15px solid black;
      animation: changebox 1s ease-in-out 1s infinite alternate running forwards;
    }
 
    .box:hover {
      animation-play-state: paused;
    }
 
    @keyframes changebox {
      10% {
        background: red;
      }
      50% {
        width: 80px;
      }
      70% {
        border: 15px solid yellow;
      }
      100% {
        width: 180px;
        height: 180px;
      }
    }
  </style>
</head>
 
<body>
  <div class="box"></div>
</body>
 
</html>

图片 5

分析:

我们先来看看keyframes这个关键点,它定义了一个动画组合叫changebox,里面的10%,50%,70%,100%代表在变化中不同时间点的属性值,比如这个动画的总时间是1s,那么10%就是在0-0.1s中的动画,通过这个我们可以较精确的控制动画变化中任何一个时间点的属性效果,这大大提高了我们对动画的把控,是做复杂动画的基础,我们再回来看animation中整整八个值,是不是有点夸张,还没见过这么长的值,通过控制animation的每个值,控制动画变得非常灵活,我们来具体了解它的语法以及各个值代表着什么:

语法:animation: name duration timing-function delay iteration-count
direction play-state fill-mode;

描述
name 用来调用@keyframes定义好的动画,与@keyframes定义的动画名称一致
duration 指定元素播放动画所持续的时间
timing-function 规定速度效果的速度曲线,是针对每一个小动画所在时间范围的变换速率
delay 定义在浏览器开始执行动画之前等待的时间,值整个animation执行之前等待的时间
iteration-count 定义动画的播放次数,可选具体次数或者无限(infinite)
direction 设置动画播放方向,两个值:normal(按时间轴顺序),alternate(轮流,即来回往复进行)
play-state 控制元素动画的播放状态,通过此来控制动画的暂停和继续,两个值:running(继续),paused(暂停)
fill-mode 控制动画结束后,元素的样式,有四个值:none(回到动画没开始时的状态),forwards(动画结束后动画停留在结束状态),backwords(动画回到第一帧的状态),both(根据animation-direction轮流应用forwards和backwards规则),注意与iteration-count不要冲突(动画执行无限次)

animation与transition
不同的是,keyframes提供更多的控制,尤其是时间轴的控制,这点让css
animation更加强大,使得flash的部分动画效果可以由css直接控制完成,而这一切,仅仅只需要几行代码,也因此诞生了大量基于css的动画库,用来取代flash的动画部分。在我的项目中一般用 Animate.css 来设置一些动画,期待在工作中能够用animation完美实现UI设计师给的设计图~

2、按F12键打开Chrome控制台,在控制台中输入:MakeRibbon(MakeRing(5,12),-10,2,11,”mesh_ribbon”)回车:

2.各种获取微信信息链接,封装在配置文件里(此部分查找微信自定义分享API,地址:)

总结

写这篇文章的目的是提醒自己不要将这四个属性混淆,顺便详细讲解CSS制作动画的方法,简单一次性的动画中推荐使用transition,比较逻辑清晰,可维护性较好。如果遇到比较复杂的动画,这个时候便可以拿出animation开始你的表演,其实不仅仅用css能实现动画,用js同样可以操控元素的样式实现动画,这个时候你脑海里是不是浮现出setTimeout,setInterval来控制样式实现动画,当然可以,但是相比新出的requestAnimationFrame,它能够更高性能地执行动画,这里抛砖引玉,小伙伴们可以尝试去谷歌以下,后面我也会就这个新出的函数写一篇详细的指南。

1 赞 1 收藏
评论

图片 6

图片 7

 # 获取access_token请求地址
  getAccessTokenUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s
  #获取accessToken
  getAccessTokenOAuthUrl: https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code
  # 获取用户基本信息请求地址
  getUserInfoUrl: https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN
  #获取code
  getCodeUrl: https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=%s&scope=%s&state=%s#wechat_redirect
  #获取ticket
  getTicketUrl: https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi

在场景中绘制了一个半径为5,曲面细分度为12,左端位于-10,每两个圆环间距2,共由11个圆环组成的圆柱面。

3.controller层

拉近查看:

       /**
     * 微信配置信息实体
     */
    @Autowired
    private WeiXinProperties weiXinProperties;
    //微信参数
    private String accessToken;
    private String jsApiTicket;
    //获取参数的时刻
    private Long getTiketTime = 0L;
    private Long getTokenTime = 0L;
    //参数的有效时间,单位是秒(s)
    private Long tokenExpireTime = 0L;
    private Long ticketExpireTime = 0L;

 /**
     * 微信自定义分享
     */
    @RequestMapping(value = "/getShareInfo", method = RequestMethod.POST)
    public Map<String, String> getShareInfo(HttpServletRequest request,
                                            HttpServletResponse response, String url) {
        //当前时间
        long now = System.currentTimeMillis();

        //判断accessToken是否已经存在或者token是否过期
        if (StringUtils.isBlank(accessToken) || (now - getTokenTime > tokenExpireTime * 1000)) {
            JSONObject tokenInfo = getAccessToken();
            if (tokenInfo != null) {
                accessToken = tokenInfo.getString("access_token");
                tokenExpireTime = tokenInfo.getLongValue("expires_in");
                //获取token的时间
                getTokenTime = System.currentTimeMillis();
                log.info("accessToken====>" + accessToken);
                log.info("tokenExpireTime====>" + tokenExpireTime + "s");
                log.info("getTokenTime====>" + getTokenTime + "ms");
            } else {
                log.info("====>tokenInfo is null~");
                log.info("====>failure of getting tokenInfo,please do some check~");
            }
        }
        //判断jsApiTicket是否已经存在或者是否过期
        if (StringUtils.isBlank(jsApiTicket) || (now - getTiketTime > ticketExpireTime * 1000)) {
            JSONObject ticketInfo = getJsApiTicket(accessToken);
            if (ticketInfo != null) {
                log.info("ticketInfo====>" + ticketInfo.toJSONString());
                jsApiTicket = ticketInfo.getString("ticket");
                ticketExpireTime = ticketInfo.getLongValue("expires_in");
                getTiketTime = System.currentTimeMillis();
                log.info("jsApiTicket====>" + jsApiTicket);
                log.info("ticketExpireTime====>" + ticketExpireTime + "s");
                log.info("getTiketTime====>" + getTiketTime + "ms");
            } else {
                log.info("====>ticketInfo is null~");
                log.info("====>failure of getting tokenInfo,please do some check~");
            }
        }
        //生成微信权限验证的参数
        Map<String, String> wechatParam = makeWXTicket(jsApiTicket, url);
        return wechatParam;

    }

    //获取accessToken
    private JSONObject getAccessToken() {
        //String accessTokenUrl = https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
        //获取微信端的accessToken
        String requestUrl = String.format(weiXinProperties.getGetAccessTokenUrl(), weiXinProperties.getAppId(), weiXinProperties.getAppSecret());
        String result = send(requestUrl);
        JSONObject jsonObject = JSON.parseObject(result);
        return jsonObject;
    }

    //获取ticket
    private JSONObject getJsApiTicket(String access_token) {
        //String apiTicketUrl = https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
        // 通过acessToken 获取ticket
        String requestUrl = String.format(weiXinProperties.getGetTicketUrl(), access_token);
        String result = send(requestUrl);  //此部分用到了我们项目的工具类,整段复制本代码时,可以用以下代替
     //JSONObject jsonObject = httpUtils.doGet(requestUrl)
        JSONObject jsonObject = JSON.parseObject(result);
        return jsonObject;
    }

    //生成微信权限验证的参数
    public Map<String, String> makeWXTicket(String jsApiTicket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonceStr = createNonceStr();
        String timestamp = createTimestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsApiTicket +
                "&noncestr=" + nonceStr +
                "&timestamp=" + timestamp +
                "&url=" + url;
        log.info("String1=====>" + string1);
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
            log.info("signature=====>" + signature);
        } catch (NoSuchAlgorithmException e) {
            log.error("WeChatController.makeWXTicket=====Start");
            log.error(e.getMessage(), e);
            log.error("WeChatController.makeWXTicket=====End");
        } catch (UnsupportedEncodingException e) {
            log.error("WeChatController.makeWXTicket=====Start");
            log.error(e.getMessage(), e);
            log.error("WeChatController.makeWXTicket=====End");
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsApiTicket);
        ret.put("nonceStr", nonceStr);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        ret.put("appid", weiXinProperties.getAppId());

        return ret;
    }

    /**
     * 发送请求
     *
     * @param url
     * @return
     * @throws Exception
     */
    String send(String url) {
        return HttpClientTools.post(url);
    }

    //字节数组转换为十六进制字符串
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    //生成随机字符串
    private static String createNonceStr() {
        return UUID.randomUUID().toString();
    }

    //生成时间戳
    private static String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

图片 8

4.引入share.js.要分享的页面

3、输入ShowNormals(mesh_origin)将用红色线段显示每个顶点的法线方向

$(function(){
    var url = location.href.split('#').toString();//url不能写死
    $.ajax({
        type : "post",
        url : "/user/login/getShareInfo",
        dataType : "json",
        async : false,
        data:{url:url},
        success : function(data) {
            wx.config({
                debug: false,////生产环境需要关闭debug模式
                appId: data.appid,//appId通过微信服务号后台查看
                timestamp: data.timestamp,//生成签名的时间戳
                nonceStr: data.nonceStr,//生成签名的随机字符串
                signature: data.signature,//签名
                jsApiList: [//需要调用的JS接口列表
                    'checkJsApi',//判断当前客户端版本是否支持指定JS接口
                    'onMenuShareTimeline',//分享给好友
                    'onMenuShareAppMessage'//分享到朋友圈
                ]
            });
        },
        error: function(xhr, status, error) {
            //alert(status);
            //alert(xhr.responseText);
        }
    })
});

图片 9

5.在要分享的页面中引入,微信分享的核心js和share.js

输入DeleteMeshes([lines_normal])可以删除所有的法线,输入DeleteMeshes([mesh_origin])则删除圆柱面网格。

<script type=”text/javascript”
src=”/resources/js/jweixin-1.2.0.js”></script>

4、鼠标移入网格上的三角形,会显示三角形的顶点信息:

<script type=”text/javascript”
src=”/resources/js/share.js”></script>

图片 10

6.在当前页面<script>中,此部分可以直接写到share.js中

其中“1:2-5”表示这是三角形的第一个顶点,这个顶点位于索引是2的圆环上(第三个圆环),这个顶点在圆环中的索引是5(也就是第六个顶点)。

        /*分享代码*/
        wx.ready(function() {
            // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
            console.log('weixin 验证成功');
            // 分享到朋友圈
            wx.onMenuShareTimeline({
                title: detail_title, // 分享标题
                link: link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                imgUrl: 'http://develop.fangxinyuesao.com/resources/images/logo.png', // 分享图标
                success: function() {
                    // 用户确认分享后执行的回调函数
                },
                cancel: function() {
                    // 用户取消分享后执行的回调函数
                }
            });

            // 分享给朋友
            wx.onMenuShareAppMessage({
                title: detail_title, // 分享标题
                desc: '来自妇幼头条的分享', // 分享描述
                link: link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                imgUrl: 'http://develop.fangxinyuesao.com/resources/images/logo.png', // 分享图标
                type: '', // 分享类型,music、video或link,不填默认为link
                dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                success: function() {
                    // 用户确认分享后执行的回调函数
                },
                cancel: function() {
                    // 用户取消分享后执行的回调函数
                }
            });

        });

        wx.error(function(res) {
            // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
            console.log('weixin 验证失败');
            console.log(res);
        });

5、输入PickPoints([[2,5],[3,5],[2,6]],mesh_origin)可以选定这些顶点

 

图片 11

注意事项:分享要设置网站白名单,电脑端调试时,推荐使用微信WEB开发工具

被选中顶点所影响的所有边框线标示为黄色,这个“选中”只是改变外观而已。

 

6、输入TransVertex(mesh_origin,arr_ij,BABYLON.Matrix.Translation(0,0,-10))将所选的顶点向z轴负方向移动10,被移动的顶点和前面选中的顶点其实没有关系,其中arr_ij也可以直接用索引数组[[2,5],[3,5],[2,6]]代替。

图片 12

另一类变形可以通过输入:TransVertex(mesh_origin,arr_ij,BABYLON.Matrix.RotationX(Math.PI/2))实现,这可以把被选中的顶点绕X中旋转90度。

输入DeleteMeshes([lines_inpicked])取消被选中的效果,输入ChangeMaterial(mesh_origin,mat_blue)将边框换成蓝色纹理:

图片 13

可以看到变形后的效果,接下来还可以继续选择顶点并变形

7、输入ExportMesh(“1”,mat_blue),以txt格式导出babylon模型文件,文件名为“1.txt”

图片 14

 8、将导出的txt改名为9.babylon后放入网站目录中,访问

二、编程思路:

1、首先要建立一个可以进行各种测试的基础场景,使用的代码如下:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>建立一个条带网格生成器,能够输入参数生成起始条带,然后通过命令行选取并修改pathArray,最后导出生成的条带</title>
  6     <link href="../CSS/newland.css" rel="stylesheet">
  7     <link href="../CSS/stat.css" rel="stylesheet">
  8     <script src="../JS/MYLIB/Events.js"></script>
  9     <script src="../JS/MYLIB/FileText.js"></script>
 10     <script src="../JS/MYLIB/View.js"></script>
 11     <script src="../JS/LIB/babylon.32.all.maxs.js"></script><!--V3.2的稳定版本-->
 12     <script src="../JS/MYLIB/newland.js"></script>
 13     <script src="../JS/LIB/stat.js"></script>
 14 </head>
 15 <body>
 16 <div id="div_allbase">
 17     <canvas id="renderCanvas"></canvas>
 18     <div id="fps" style="z-index: 301;"></div>
 19 </div>
 20 </body>
 21 <script>
 22     var VERSION=1.0,AUTHOR="lz_newland@163.com";
 23     var machine,canvas,engine,scene,gl,MyGame={};
 24     canvas = document.getElementById("renderCanvas");
 25     engine = new BABYLON.Engine(canvas, true);
 26     gl=engine._gl;//可以结合使用原生OpenGL和Babylon.js;
 27     scene = new BABYLON.Scene(engine);
 28     var divFps = document.getElementById("fps");
 29 
 30     window.onload=beforewebGL;
 31     function beforewebGL()
 32     {
 33         if(engine._webGLVersion==2.0)//输出ES版本
 34         {
 35             console.log("ES3.0");
 36         }
 37         else{
 38             console.log("ES2.0");
 39         }
 40         //MyGame=new Game(0,"first_pick","","http://127.0.0.1:8082/");
 41         /*0-startWebGL
 42          * */
 43         webGLStart();
 44     }
 45     //从下面开始分成简单测试和对象框架两种架构
 46     //简单测试
 47     //全局对象
 48     var light0//全局光源
 49             ,camera0//主相机
 50             ;
 51     //四种常用材质
 52     var mat_frame = new BABYLON.StandardMaterial("mat_frame", scene);
 53     mat_frame.wireframe = true;
 54     var mat_red = new BABYLON.StandardMaterial("mat_red", scene);
 55     mat_red.diffuseColor = new BABYLON.Color3(1, 0, 0);
 56     mat_red.backFaceCulling=false;
 57     var mat_green = new BABYLON.StandardMaterial("mat_green", scene);
 58     mat_green.diffuseColor = new BABYLON.Color3(0, 1, 0);
 59     mat_green.backFaceCulling=false;
 60     var mat_blue = new BABYLON.StandardMaterial("mat_blue", scene);
 61     mat_blue.diffuseColor = new BABYLON.Color3(0, 0, 1);
 62     mat_blue.backFaceCulling=false;
 63     var mesh_origin;
 64     var advancedTexture=BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("ui1");//全屏GUI
 65     function webGLStart()
 66     {
 67         window.addEventListener("resize", function () {//自动调整视口尺寸
 68             engine.resize();
 69         });
 70         camera0 =new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(0, 0, -80), scene);
 71         camera0.attachControl(canvas, true);
 72         camera0.speed=0.5;//相机移动速度是默认速度的一半
 73         camera0.minZ=0.01;//相机位置距前视锥截面的距离,也就是说到相机距离小于0.01的图元都不会显示,这个值不能过小,否则Babylon.js内置的鼠标选取将失效
 74         camera0.layerMask=2;//相机的遮罩层次,这个相机将只能显示遮罩层次同为2的网格,如果不设置这个属性,似乎可以显示所有遮罩层次的网格
 75         scene.activeCameras.push(camera0);//将相机加入活跃相机列表,默认情况下Babylon.js只使用一个活跃相机,但是也可以强行使用多个
 76         light0 = new BABYLON.HemisphericLight("Hemi0", new BABYLON.Vector3(0, 1, 0), scene);//半球光源
 77      //三个参照物,MeshBuilder是新版Babylon.js中使用的网格构建对象,之前翻译入门教程时还没有这个对象,它的特点是把一大堆参数统一整理到一个option参数中
 78         var mesh_base=new BABYLON.MeshBuilder.CreateSphere("mesh_base",{diameter:1},scene);
 79         mesh_base.material=mat_green;
 80         mesh_base.position.x=0;
 81         mesh_base.layerMask=2;
 82         var mesh_base1=new BABYLON.MeshBuilder.CreateSphere("mesh_base1",{diameter:1},scene);
 83         mesh_base1.position.y=10;
 84         mesh_base1.position.x=0;
 85         mesh_base1.material=mat_green;
 86         mesh_base1.layerMask=2;
 87         var mesh_base2=new BABYLON.MeshBuilder.CreateSphere("mesh_base2",{diameter:1},scene);
 88         mesh_base2.position.y=-10;
 89         mesh_base2.position.x=0;
 90         mesh_base2.material=mat_green;
 91         mesh_base2.layerMask=2;
 92       。
 93       。
 94       。
 95         MyBeforeRender();
 96     }
 97     function MyBeforeRender()
 98     {
 99         scene.registerBeforeRender(function() {
100             if(scene.isReady())
101             {
102                 。
103                 。
104                 。
105                 。
106                 。
107                 。
108             }
109         });
110         engine.runRenderLoop(function () {
111             engine.hideLoadingUI();
112             if (divFps) {
113                 // Fps
114                 divFps.innerHTML = engine.getFps().toFixed() + " fps";
115             }
116             scene.render();
117         });
118 
119     } 
120 </script>
121 </html>   

这个3D场景包括了简单测试所需要的一些基本元素,这里使用的是包含全部组件的未压缩版Babylon.js库,在实际使用中考虑到节省带宽,可以使用Babylon.js官网提供的工具定制精简版或压缩版的Babylon.js库

2、建立一个基础网格

发表评论

电子邮件地址不会被公开。 必填项已用*标注