唯杰地图 logo唯杰地图
VJMAP
EN

实体常用模块

vjmap3d/references/entity/entityModule.md 8.9 KB331 行
原文

事件模块EventModule

事件模块EventModule主要用来响应实体的hover和click事件。

增加事件模块

// 增加一个事件模块,用来高亮提示
entity.add(vjmap3d.EventModule, {
    clickHighlight: true,
    highlightOpacity: 0.2,
    hoverSelect: true,
    hoverHtmlText: "我是MeshEntity",
    popupOptions: {
        anchor: "bottom"
    },
    clickCallback: (ent, isClick) => {
        if (!isClick) return;
        app.logInfo(`您点击了我`)
    }
});

移除事件模块

entity.removeModule(vjmap3d.EventModule);
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
    render: { // 渲染参数
        alpha: true,
        antialias: true
    },
    scene: {  // 场景设置
        gridHelper: { visible: true } // 是否显示坐标网格
    }
})
//
let box = new THREE.BoxGeometry(2, 2, 2)
const material = new THREE.MeshStandardMaterial({
    color: "#0f0",
    side: THREE.DoubleSide
});
let mesh = new THREE.Mesh(box, material);
let entity = vjmap3d.Entity.fromObject3d(mesh);
entity.addTo(app);
// 增加一个事件模块,用来高亮提示
entity.add(vjmap3d.EventModule, {
    clickHighlight: true,
    highlightOpacity: 0.2,
    hoverSelect: true,
    hoverHtmlText: "我是MeshEntity",
    popupOptions: {
        anchor: "bottom"
    },
    clickCallback: (ent, isClick) => {
        if (!isClick) return;
        app.logInfo(`您点击了我`)
    }
});
let control = new vjmap3d.ButtonGroupControl({
    buttons: [
        {
            id: "id1",
            html: "移除事件模块",
            title: "移除事件模块",
            style: {
                width: "130px"
            },
            onclick: async () => {
               entity.removeModule(vjmap3d.EventModule);
               app.logInfo(`移除事件后,将不会响应事件`)
            }
        }
    ]
});
app.addControl(control, "top-right");

动画模块AnimatorModule

动画模块AnimatorModule主要用来对实体进行动画操作。

加载有动画的模型做为实体对象时,会自动给实体添加动画模块AnimatorModule。

let ent = await vjmap3d.ResManager.loadModel(vjmap3d.ResManager.svrUrl("models/Stork.glb"), {
    splitSubEntity: true,
    scale: 0.1,
    anchor: "front-bottom-right"
});
ent.addTo(app);
let mod = ent.getModule(vjmap3d.AnimatorModule);
if (mod) {
 let animator = mod.getAnimator();
 animator.play(0) // 开启动画
 // animator.stop(0)  // 停止动画
}

⚠️ Animator 实例上 isLoop()/setPosition(time)/removeClip/playAnimation 均为 undefined(d.ts 声明存在但运行时没有——removeClip 宿主是另一个 Animation 内部类、playAnimation 宿主是 SpriteAnimatorEntity,都不在 Animator)——可用的剪辑/循环控制是 addAnimationClip(clip)→AnimationClip/getAnimationClips()/setLoop/reset/stopAllAction/setTime/play(idx),信号袋只有 signal.onLoop/signal.onFinished。另外 new Animator(options) 的 options.object 必填(Object3D/Entity),空 options 会抛 Cannot read properties of undefined (reading 'isEntity')。

let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
     control:{
        initState: { // 相机初始位置 
            cameraTarget: new THREE.Vector3(-15, 0, -10),
            cameraPosition: new THREE.Vector3(-30, 30, -10)
      }
    },
    ui: {
        configPane: {
            title: "设置",
            style: { width: "240px", overflow: "hidden"}
        }
    }
})
let ent = await vjmap3d.ResManager.loadModel(vjmap3d.ResManager.svrUrl("models/Stork.glb"), {
    splitSubEntity: true,
    scale: 0.1,
    anchor: "front-bottom-right"
});
ent.addTo(app);
let mod = ent.getModule(vjmap3d.AnimatorModule);
if (mod) {
 let animator = mod.getAnimator();
 animator.play(0) // 开启动画
 // animator.stop(0)  // 停止动画
}

增加新的动画

如:增加一个闪烁动画

let mod = ent.add(vjmap3d.AnimatorModule);
let animator = mod.getAnimator();
let clip = animator.addVisibilityAnimation();
animator.play(clip);
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
    scene: {  // 场景设置
        gridHelper: { visible: true } // 是否显示坐标网格
    }
})
//
let box = new THREE.BoxGeometry(2, 2, 2)
const material = new THREE.MeshStandardMaterial({
    color: "#0f0",
    side: THREE.DoubleSide
});
let mesh = new THREE.Mesh(box, material);
let entity = vjmap3d.Entity.fromObject3d(mesh);
entity.addTo(app);
let mod = entity.add(vjmap3d.AnimatorModule);
let animator = mod.getAnimator();
let clip = animator.addVisibilityAnimation();
animator.play(clip);

路径动画模块PathAnimateModule

路径动画模块PathAnimateModule是实体沿指定路径行走的动画模块。

let pathAnmiMod = ent.add(vjmap3d.PathAnimateModule)
pathAnmiMod.start({
    paths: line.data.coordinates,
    cameraFollow: true, 
    animation: {
        duration: 10000,
        yoyoForever: true
    },
    startAimatorClipName: 'Walk',
    stopAimatorClipName: ""
})
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
    scene: {  // 场景设置
        gridHelper: { visible: true } // 是否显示坐标网格
    }
})
let ent = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/soldier.glb", {
    splitSubEntity: true
});
app.logInfo("请在图上绘制一条要行走的路径线,双击结束", 60000)
let line = await app.actionDrawLineSting({
    isAddToApp: true
});
if (line.isCancel) return
ent.addTo(app);
let pathAnmiMod = ent.add(vjmap3d.PathAnimateModule)
pathAnmiMod.start({
    paths: line.data.coordinates,
    cameraFollow: true, 
    animation: {
        duration: 10000,
        yoyoForever: true
    },
    startAimatorClipName: 'Walk',
    stopAimatorClipName: ""
})
let miniMapControl = true; // 是否显示小地图
if (miniMapControl) {
    let miniMapControl = new vjmap3d.MiniMapControl({
        followTarget: ent.node,
        // mapSyncRotateZ: true,
        mapSize: 10,
    });
    app.addControl(miniMapControl)
}

每段路径设置不同动画和速度

let pathSegs = [
    {
        point: [0,0,0]
    },
    {
        point: [10,0,10],
        time: 1000
    },
    {
        point: [10, 0, 20],
        time: 2000
    },
    {
        point: [20, 0, 20],
        time: 1000
    },
    {
        point: [20, 0, 10],
        time: 3000
    },
    {
        point: [10, 0, 10],
        time: 2000
    }
]

let pathAnmiMod = ent.add(vjmap3d.PathAnimateModule)
for(let n = 1; n < pathSegs.length; n++) {
    await pathAnmiMod.start({
        paths: [pathSegs[n - 1].point, pathSegs[n].point],
        animation: {
            // @ts-ignore
            duration: pathSegs[n].time
        },
        cameraFollow: true,
        startAimatorClipName: 'Walk',
        stopAimatorClipName: n == pathSegs.length - 1 ? "" : "Walk"
    })
}
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
    scene: {  // 场景设置
        gridHelper: { visible: true } // 是否显示坐标网格
    }
})
let ent = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/soldier.glb", {
    splitSubEntity: true
});
ent.addTo(app);
let pathSegs = [
    {
        point: [0,0,0]
    },
    {
        point: [10,0,10],
        time: 1000
    },
    {
        point: [10, 0, 20],
        time: 2000
    },
    {
        point: [20, 0, 20],
        time: 1000
    },
    {
        point: [20, 0, 10],
        time: 3000
    },
    {
        point: [10, 0, 10],
        time: 2000
    }
]
// 
let pathAnmiMod = ent.add(vjmap3d.PathAnimateModule)
for(let n = 1; n < pathSegs.length; n++) {
    await pathAnmiMod.start({
        paths: [pathSegs[n - 1].point, pathSegs[n].point],
        animation: {
            // @ts-ignore
            duration: pathSegs[n].time
        },
        cameraFollow: true,
        startAimatorClipName: 'Walk',
        stopAimatorClipName: n == pathSegs.length - 1 ? "" : "Walk"
    })
}