# 拼图和代码片段

# JS:渲染回调

参数是回调函数

app.renderCallbacks.push(function(){
  //拼图中的函数
  v3d.puzzles.procedures.myfunc();
});
1
2
3
4

参考:https://www.soft8soft.com/docs/api/en/extras/App.html#renderCallbacks (opens new window)

# JS:编译回调

用于添加后期处理效果或雾效,改善性能,v3d 3.2新增。

app.compileCallbacks.push(function(){
  app.scene.fog = new v3d.FogExp2(0xefd1b5, 0.0025);
});
1
2
3

参考:https://www.soft8soft.com/docs/api/en/extras/App.html#compileCallbacks (opens new window)

# JS:雾效

第一个参数支持CSS颜色输入方式,第二个参数是强度

v3d 3.4版新增addfog拼图

app.scene.fog = new v3d.FogExp2(0xefd1b5, 0.0025);
app.scene.fog = new v3d.FogExp2('blue’, 0.02);
1
2

参考:https://www.soft8soft.com/docs/api/en/scenes/FogExp2.html (opens new window)

# JS:禁用渲染和降低帧率

用于提高性能

app.disableRendering();
app.enableRendering(); 
app.setFrameRateDivider(2); // enables maximum 30 FPS instead of 60
1
2
3

参考:https://www.soft8soft.com/docs/api/en/extras/App.html#setFrameRateDivider (opens new window)

# JS:控制阴影开关

app.renderer.shadowMap.enabled = false;
1

# JS:判断物体是否被遮挡

v3d 3.4后可以通过raycast拼图实现。

var obj = app.scene.getObjectByName(obj);
var raycaster = new v3d.Raycaster(app.camera.position, obj.position.sub(app.camera.position).normalize());
var intersects = raycaster.intersectObjects(app.scene.children);
console.log(intersects);
 if (intersects.length > 0) {
      return true;
   } else {
   return false;
            };
1
2
3
4
5
6
7
8
9

参考:https://www.soft8soft.com/docs/api/en/core/Raycaster.html (opens new window)

# JS:获取鼠标点击位置

注意返回的pos坐标(左手坐标)与拼图坐标(右手坐标)不一致,需要转换。

这段代码不计算mesh与相机之间是否存在遮挡物体。

v3d 3.4后可以通过raycast拼图实现。

var raycaster = new v3d.Raycaster();
    var mesh = app.scene.getObjectByName("nav_mesh");
    var mouse = new v3d.Vector2();

    function onClick(event) {
        // 计算鼠标在屏幕空间的位置
        mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
        mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
        // 更新鼠标和相机的射线
        raycaster.setFromCamera(mouse, app.camera);
        // 计算与射线相交的物体
        var intersects = raycaster.intersectObject(mesh);
        if (intersects.length > 0) {
            var pos = intersects[0].point;
            // console.log(pos);
        }
    }

    function onTouch(event) {
        var touch = event.touches[0]; //获取第一个触点
        mouse.x = (touch.pageX / window.innerWidth) * 2 - 1; //页面触点X坐标
        mouse.y = -(touch.pageY / window.innerHeight) * 2 + 1; //页面触点Y坐标
        //记录触点初始位置
        raycaster.setFromCamera(mouse, app.camera);
        // 计算与射线相交的物体
        var intersects = raycaster.intersectObject(mesh);
        if (intersects.length > 0) {
            var pos = intersects[0].point;
            // console.log(pos);
        }
    }
    window.addEventListener('click', onClick, {
        passive: true
    });
    window.addEventListener('touchstart', onTouch, {
        passive: true
    });
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

# JS:从外部调用v3d应用的变量、函数

自定义的代码一般放在v3d自动生成的app.js里面的runcode()函数内部,这样当v3d应用加载完成,会直接执行该函数下的代码。但是,如果想在单独的js文件中编写代码,还要访问v3d内部的变量、函数,这种情况就有些复杂了。

在main.js中:

// 对verge3d的app.js做事件监听
v3d._customEvents = new v3d.EventDispatcher();
v3d._customEvents.addEventListener('onload', function(event) {
  // 还可以调用拼图定义的函数
  v3d.puzzles.procedures.myProcedures();
  // 获取场景中的第一个物体的名称
  var obj = v3d.apps[0].scene.children[0].name;
});
1
2
3
4
5
6
7
8

在app.js中:

function runCode(app) {
    //  运行到此处时v3d应用已加载完成,发送加载事件
    if (v3d._customEvents) {
        v3d._customEvents.dispatchEvent({ type: 'onload' });
    }
}
1
2
3
4
5
6

参考:https://www.soft8soft.com/topic/calling-procedures-from-js/ (opens new window)

# JS:从父级访问iframe中的v3d变量

v3d_variable是iframe内的v3d应用暴露出来的全局变量,要从父级获取它,代码如下:

setTimeout(function(){
  window.frames['child'].contentWindow.v3d_variable
},2000)
1
2
3

这里需要用延迟加载的方法,等iframe下的v3d应用加载完成后,再去访问。

参考:https://www.soft8soft.com/topic/how-to-call-a-v3d-function-from-outside-the-iframe/ (opens new window)

# JS:线框材质透明度

lineObj.material.transparent = true; //开启材质透明
lineObj.material.opacity = 0.5; //透明度
lineObj.material.lineWidth = 2; //线框宽度
1
2
3

参考:https://www.soft8soft.com/docs/api/en/extras/objects/MeshLineMaterial.html (opens new window)

# JS:改变轮廓颜色

v3d 3.2可通过材质编译回调函数添加后期处理效果

v3d.apps[0].postprocessing.outlinePass.visibleEdgeColor = new v3d.Vector4(0,0,1,1) // blue
1

# JS:改变动画播放速度

使用 play animation 拼图控制动画速度时,无法在动画播放过程中改变速度,可以自定义一个函数:

function prepareExternalInterface(app) {
    app.ExternalInterface.setAnimationSpeed = function(animName, speed) {
        var action = v3d.SceneUtils.getAnimationActionByName(app, animName);
        if (action) {
            action.timeScale = speed;
        }
    }
}
1
2
3
4
5
6
7
8

# JS: HTML虚拟摇杆

使用nipplejs.js (opens new window)实现虚拟摇杆

注意 dynamic模式下需要为zone指定宽高100%

Verge3D runcode()下面加入以下代码:

// joystick
var joystick = nipplejs.create({
    zone: document.getElementById('left'),
    mode: 'static', //mode: 'semi','dynamic'
    position: {
        right: '100px',
        bottom: '100px'
    },
    color: 'skyBlue',
    size: 100
});

var dir;
joystick.on("move", function (evt, data) {
    dir = data.direction.angle;
}).on("end", function(evt, data){
    dir = "none";
})

//every frame 
app.renderCallbacks.push(function() {
    v3d.puzzles.procedures.playerMove(dir);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# JS:重力感应功能

// 开启和关闭陀螺仪重力感应
var flag;
var gyro_button = document.getElementById('gyro_button');
var orientationControls = new v3d.DeviceOrientationControls( app.camera );

gyro_button.addEventListener('click', function(){
    flag = !flag;
    if (flag){
        app.controls = orientationControls;
    }else{
        app.enableControls();
    }
}, false);
1
2
3
4
5
6
7
8
9
10
11
12
13

# JS:清除V3D缓存

默认V3D是开启缓存的,想要清除,可以使用如下代码:

v3d.Cache.clear()

# JS:选择被遮挡的物体

如果想忽略当前物体而选择其背后的物体,可以使用如下代码:

var myObj = app.scene.getObjectByName('myObj');
myObj.raycast = function() {};
1
2

使该物体重新可选择,使用代码:

var myObj = app.scene.getObjectByName('myObj');
delete myObj.raycast;
1
2

# 拼图:适配屏幕

mark

# 拼图:为一组物体实现可拖动

mark

# 拼图:高清屏显示设置

mark

# 拼图:XR控制器

以下方法已由get controller prop拼图实现。

webXR控制器名称为:XR_CONTROLLER webXR注视点光标名称为:XR_CONTROLLER_RETICLE 设置新的VR注视点光标时需要将光标的模型父子约束到XR控制器上,并且Y轴位置约束到XR注视点上。

mark

# 拼图:使用文本代替组选择器

名为Collection 1的组在代码中表示为:

['GROUP','Collection 1']

因此,在拼图中可以通过GROUP+组名构成的列表来代替组选择器——

mark

# 拼图:HTML事件属性

以下案例可通过get event property拼图获取事件目标的属性值(JS中的事件代理,根据冒泡机制实现)。 html

<ul>
    <li id="btn1" value="1">按钮</li>
    <li id="btn2" value="2">按钮</li>
    <li id="btn3" value="3">按钮</li>
    <li id="btn4" value="4">按钮</li>
</ul>
1
2
3
4
5
6

mark

# 拼图:增加/移除类.class

利用文本类的replace with拼图移除类

mark

利用create text拼图增加类

mark

疑问?

请在钉钉群:21935218交流。群内除聚集众多开发者,还有最新动态、视频教程、智能客服@宅小呗、答疑、直播、下载等实用功能。如需宅家呗提供技术支持,请加钉钉好友:zjbcool

Verge3D知识社区 客服
上次更新: 2020-10-28 13:40:19