Browse Source

动画指定角度/模型旋转

master
xuhuajiao 2 months ago
parent
commit
b057a61bf1
  1. 90
      public/webThird/index.js
  2. 87
      public/webWater/index.js
  3. 13
      src/views/header/index.vue
  4. 4
      src/views/index.vue
  5. 39
      src/views/pageBasement/index.vue
  6. 39
      src/views/pageFullView/index.vue
  7. 41
      src/views/pageThirdFloor/index.vue
  8. 39
      src/views/pageWaterPumpHouse/index.vue

90
public/webThird/index.js

@ -21,6 +21,20 @@ var drag = null
var isRotating = true
var clickParentRotate = false
var targetAngles = {
default: { // 初始视角
alpha: 0,
beta: 0,
radius: 125
},
alarm: { // 报警视角(示例)
alpha: 4.7190, // -π(180度)
beta: 0.0100, // π/4(45度)
radius: 136.5303 // 更近的距离
}
}
var camera
BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI = function() {
if (document.getElementById('customLoadingScreenDiv')) {
@ -401,6 +415,10 @@ var createScene = function() {
})
// 将加载的资产添加到场景中
container.addAllToScene()
setTimeout(() => {
moveCameraTo('alarm')
}, 3000)
}).catch((error) => {
console.error('加载模型时出错:', error)
})
@ -522,6 +540,7 @@ window.addEventListener('resize', function() {
function cameraClick(TheCamera) {
window.parent.postMessage(
{
type: 'cameraClick',
data: TheCamera.nameID
},
'*'
@ -557,6 +576,7 @@ function handleAlarm(deviceId, isAlarm) {
console.log(`未找到设备 ID 为 ${deviceId} 的设备`)
}
}
window.addEventListener(
'message',
function(e) {
@ -592,3 +612,73 @@ function toggleAutoRotation(isAutoRotating) {
camera.angularSpeed = 0 // 停止旋转
}
}
// 相机运动到指定视角(带动画)
function moveCameraTo(targetPreset) {
// 获取目标参数
var target = targetAngles[targetPreset]
if (!target) return console.error('无效的视角预设')
var camera = scene.activeCamera
// 禁用用户交互(可选)
camera.panningInertia = 0 // 禁止平移
// 创建并设置动画
var animationAlpha = new BABYLON.Animation(
'cameraAlphaAnimation',
'alpha',
60, // 帧率
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
)
var animationBeta = new BABYLON.Animation(
'cameraBetaAnimation',
'beta',
60, // 帧率
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
)
var animationRadius = new BABYLON.Animation(
'cameraRadiusAnimation',
'radius',
60, // 帧率
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
)
// 定义关键帧
var keysAlpha = [
{ frame: 0, value: camera.alpha },
{ frame: 120, value: target.alpha }
]
var keysBeta = [
{ frame: 0, value: camera.beta },
{ frame: 120, value: target.beta }
]
var keysRadius = [
{ frame: 0, value: camera.radius },
{ frame: 120, value: target.radius }
]
animationAlpha.setKeys(keysAlpha)
animationBeta.setKeys(keysBeta)
animationRadius.setKeys(keysRadius)
// 设置缓动函数
var easingFunction = new BABYLON.CubicEase()
easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT)
animationAlpha.setEasingFunction(easingFunction)
animationBeta.setEasingFunction(easingFunction)
animationRadius.setEasingFunction(easingFunction)
// 开始动画
scene.beginDirectAnimation(camera, [animationAlpha, animationBeta, animationRadius], 0, 120, false, 1, function() {
// 动画完成后恢复用户交互
camera.panningInertia = 0.1
toggleAutoRotation(true)
window.parent.postMessage({ type: 'autoRotationStatus', value: true }, '*')
})
}

87
public/webWater/index.js

@ -21,6 +21,20 @@ var drag = null
var isRotating = true
var clickParentRotate = false
var targetAngles = {
default: { // 初始视角
alpha: 2.5809,
beta: 0.9804,
radius: 24
},
alarm: { // 报警视角(示例)
alpha: 3.1213, // -π(180度)
beta: 0.5855, // π/4(45度)
radius: 24 // 更近的距离
}
}
var camera
BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI = function() {
@ -405,6 +419,10 @@ var createScene = function() {
})
// 将加载的资产添加到场景中
container.addAllToScene()
setTimeout(() => {
moveCameraTo('alarm')
}, 3000)
}).catch((error) => {
console.error('加载模型时出错:', error)
})
@ -538,6 +556,7 @@ window.addEventListener('resize', function() {
function cameraClick(TheCamera) {
window.parent.postMessage(
{
type: 'cameraClick',
data: TheCamera.nameID
},
'*'
@ -610,3 +629,71 @@ function toggleAutoRotation(isAutoRotating) {
}
}
// 相机运动到指定视角(带动画)
function moveCameraTo(targetPreset) {
// 获取目标参数
var target = targetAngles[targetPreset]
if (!target) return console.error('无效的视角预设')
var camera = scene.activeCamera
// 禁用用户交互(可选)
camera.panningInertia = 0 // 禁止平移
// 创建并设置动画
var animationAlpha = new BABYLON.Animation(
'cameraAlphaAnimation',
'alpha',
60, // 帧率
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
)
var animationBeta = new BABYLON.Animation(
'cameraBetaAnimation',
'beta',
60, // 帧率
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
)
var animationRadius = new BABYLON.Animation(
'cameraRadiusAnimation',
'radius',
60, // 帧率
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
)
// 定义关键帧
var keysAlpha = [
{ frame: 0, value: camera.alpha },
{ frame: 120, value: target.alpha }
]
var keysBeta = [
{ frame: 0, value: camera.beta },
{ frame: 120, value: target.beta }
]
var keysRadius = [
{ frame: 0, value: camera.radius },
{ frame: 120, value: target.radius }
]
animationAlpha.setKeys(keysAlpha)
animationBeta.setKeys(keysBeta)
animationRadius.setKeys(keysRadius)
// 设置缓动函数
var easingFunction = new BABYLON.CubicEase()
easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT)
animationAlpha.setEasingFunction(easingFunction)
animationBeta.setEasingFunction(easingFunction)
animationRadius.setEasingFunction(easingFunction)
// 开始动画
scene.beginDirectAnimation(camera, [animationAlpha, animationBeta, animationRadius], 0, 120, false, 1, function() {
// 动画完成后恢复用户交互
camera.panningInertia = 0.1
toggleAutoRotation(true)
window.parent.postMessage({ type: 'autoRotationStatus', value: true }, '*')
})
}

13
src/views/header/index.vue

@ -32,7 +32,7 @@
</div>
<div class="topRight-btn">
<div class="btn-style" @click="handleRotate">
<svg-icon v-if="!isRotate" icon-class="rotate" class-name="msg-list-svg" />
<svg-icon v-if="!isGetRotate" icon-class="rotate" class-name="msg-list-svg" />
<svg-icon v-else icon-class="srotate" class-name="msg-list-svg" />
</div>
<div class="btn-style" @click="handleClear">
@ -59,14 +59,17 @@ export default {
default: function() {
return 0
}
},
isGetRotate: {
type: Boolean,
default: false
}
},
data() {
return {
nowDate: '',
currentWeek: this.getCurrentWeek(),
isClear: false,
isRotate: false
isClear: false
}
},
watch: {
@ -91,8 +94,8 @@ export default {
this.$emit('onClickClearPage', this.isClear)
},
handleRotate() {
this.isRotate = !this.isRotate
this.$emit('onClickRotate', this.isRotate)
const newIsRotate = !this.isGetRotate
this.$emit('onClickRotate', newIsRotate)
}
}
}

4
src/views/index.vue

@ -6,7 +6,7 @@
<dv-loading>Loading...</dv-loading>
</div>
<!-- Header -->
<Header :header-title="headerTitle" @onClickClearPage="onClickClearPage" @onClickRotate="onClickRotate" />
<Header :header-title="headerTitle" :is-get-rotate="isGetRotate" @onClickClearPage="onClickClearPage" @onClickRotate="onClickRotate" />
<!-- 底部菜单 楼栋 / 房间 -->
<div class="page-nav">
@ -23,7 +23,7 @@
</ul>
</div>
<component :is="comName" :is-get-clear="isGetClear" :is-get-rotate="isGetRotate" />
<component :is="comName" :is-get-clear="isGetClear" :is-get-rotate="isGetRotate" @update:isGetRotate="onClickRotate" />
<ul v-if="isGetClear" :class="{ 'right-fixed': true, 'animate__fadeInRight': isGetClear}">
<li>20</li>

39
src/views/pageBasement/index.vue

@ -118,19 +118,34 @@ export default {
}, '*')
},
handleMessageEvent(event) {
if (event.data && event.data.data) {
const data = event.data.data
console.log(data)
//
if (data.includes('C')) {
this.open = true
this.$nextTick(() => {
this.$refs.camera.camConfig = {
'id': data,
'area_id': '1'
if (event.data) {
switch (event.data.type) {
case 'autoRotationStatus':
{
const newValue = event.data.value
this.$emit('update:isGetRotate', newValue)
console.log('Received auto rotation status:', newValue)
}
this.$refs.camera.getVideoUrl()
})
break
case 'cameraClick':
{
const data = event.data.data
console.log(data)
//
if (data.includes('C')) {
this.open = true
this.$nextTick(() => {
this.$refs.camera.camConfig = {
'id': data,
'area_id': '1'
}
this.$refs.camera.getVideoUrl()
})
}
}
break
default:
console.log('errorwww:', event.data)
}
}
},

39
src/views/pageFullView/index.vue

@ -178,19 +178,34 @@ export default {
}, '*')
},
handleMessageEvent(event) {
if (event.data && event.data.data) {
const data = event.data.data
console.log(data)
//
if (data.includes('C')) {
this.open = true
this.$nextTick(() => {
this.$refs.camera.camConfig = {
'id': data,
'area_id': '0'
if (event.data) {
switch (event.data.type) {
case 'autoRotationStatus':
{
const newValue = event.data.value
this.$emit('update:isGetRotate', newValue)
console.log('Received auto rotation status:', newValue)
}
this.$refs.camera.getVideoUrl()
})
break
case 'cameraClick':
{
const data = event.data.data
console.log(data)
//
if (data.includes('C')) {
this.open = true
this.$nextTick(() => {
this.$refs.camera.camConfig = {
'id': data,
'area_id': '0'
}
this.$refs.camera.getVideoUrl()
})
}
}
break
default:
console.log('errorwww:', event.data)
}
}
},

41
src/views/pageThirdFloor/index.vue

@ -98,7 +98,7 @@ export default {
if (value === 'false') {
const data = [
{
'deviceId': 'S004',
'deviceId': 'S003',
'isAlarm': true
},
{
@ -125,19 +125,34 @@ export default {
}, '*')
},
handleMessageEvent(event) {
if (event.data && event.data.data) {
const data = event.data.data
console.log(data)
//
if (data.includes('C')) {
this.open = true
this.$nextTick(() => {
this.$refs.camera.camConfig = {
'id': data,
'area_id': '2'
if (event.data) {
switch (event.data.type) {
case 'autoRotationStatus':
{
const newValue = event.data.value
this.$emit('update:isGetRotate', newValue)
console.log('Received auto rotation status:', newValue)
}
this.$refs.camera.getVideoUrl()
})
break
case 'cameraClick':
{
const data = event.data.data
console.log(data)
//
if (data.includes('C')) {
this.open = true
this.$nextTick(() => {
this.$refs.camera.camConfig = {
'id': data,
'area_id': '2'
}
this.$refs.camera.getVideoUrl()
})
}
}
break
default:
console.log('errorwww:', event.data)
}
}
},

39
src/views/pageWaterPumpHouse/index.vue

@ -163,19 +163,34 @@ export default {
}, '*')
},
handleMessageEvent(event) {
if (event.data && event.data.data) {
const data = event.data.data
console.log(data)
//
if (data.includes('C')) {
this.open = true
this.$nextTick(() => {
this.$refs.camera.camConfig = {
'id': data,
'area_id': '3'
if (event.data) {
switch (event.data.type) {
case 'autoRotationStatus':
{
const newValue = event.data.value
this.$emit('update:isGetRotate', newValue)
console.log('Received auto rotation status:', newValue)
}
this.$refs.camera.getVideoUrl()
})
break
case 'cameraClick':
{
const data = event.data.data
console.log(data)
//
if (data.includes('C')) {
this.open = true
this.$nextTick(() => {
this.$refs.camera.camConfig = {
'id': data,
'area_id': '3'
}
this.$refs.camera.getVideoUrl()
})
}
}
break
default:
console.log('errorwww:', event.data)
}
}
},

Loading…
Cancel
Save