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. 17
      src/views/pageBasement/index.vue
  6. 17
      src/views/pageFullView/index.vue
  7. 19
      src/views/pageThirdFloor/index.vue
  8. 17
      src/views/pageWaterPumpHouse/index.vue

90
public/webThird/index.js

@ -21,6 +21,20 @@ var drag = null
var isRotating = true var isRotating = true
var clickParentRotate = false 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 var camera
BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI = function() { BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI = function() {
if (document.getElementById('customLoadingScreenDiv')) { if (document.getElementById('customLoadingScreenDiv')) {
@ -401,6 +415,10 @@ var createScene = function() {
}) })
// 将加载的资产添加到场景中 // 将加载的资产添加到场景中
container.addAllToScene() container.addAllToScene()
setTimeout(() => {
moveCameraTo('alarm')
}, 3000)
}).catch((error) => { }).catch((error) => {
console.error('加载模型时出错:', error) console.error('加载模型时出错:', error)
}) })
@ -522,6 +540,7 @@ window.addEventListener('resize', function() {
function cameraClick(TheCamera) { function cameraClick(TheCamera) {
window.parent.postMessage( window.parent.postMessage(
{ {
type: 'cameraClick',
data: TheCamera.nameID data: TheCamera.nameID
}, },
'*' '*'
@ -557,6 +576,7 @@ function handleAlarm(deviceId, isAlarm) {
console.log(`未找到设备 ID 为 ${deviceId} 的设备`) console.log(`未找到设备 ID 为 ${deviceId} 的设备`)
} }
} }
window.addEventListener( window.addEventListener(
'message', 'message',
function(e) { function(e) {
@ -592,3 +612,73 @@ function toggleAutoRotation(isAutoRotating) {
camera.angularSpeed = 0 // 停止旋转 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 isRotating = true
var clickParentRotate = false 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 var camera
BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI = function() { BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI = function() {
@ -405,6 +419,10 @@ var createScene = function() {
}) })
// 将加载的资产添加到场景中 // 将加载的资产添加到场景中
container.addAllToScene() container.addAllToScene()
setTimeout(() => {
moveCameraTo('alarm')
}, 3000)
}).catch((error) => { }).catch((error) => {
console.error('加载模型时出错:', error) console.error('加载模型时出错:', error)
}) })
@ -538,6 +556,7 @@ window.addEventListener('resize', function() {
function cameraClick(TheCamera) { function cameraClick(TheCamera) {
window.parent.postMessage( window.parent.postMessage(
{ {
type: 'cameraClick',
data: TheCamera.nameID 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>
<div class="topRight-btn"> <div class="topRight-btn">
<div class="btn-style" @click="handleRotate"> <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" /> <svg-icon v-else icon-class="srotate" class-name="msg-list-svg" />
</div> </div>
<div class="btn-style" @click="handleClear"> <div class="btn-style" @click="handleClear">
@ -59,14 +59,17 @@ export default {
default: function() { default: function() {
return 0 return 0
} }
},
isGetRotate: {
type: Boolean,
default: false
} }
}, },
data() { data() {
return { return {
nowDate: '', nowDate: '',
currentWeek: this.getCurrentWeek(), currentWeek: this.getCurrentWeek(),
isClear: false,
isRotate: false
isClear: false
} }
}, },
watch: { watch: {
@ -91,8 +94,8 @@ export default {
this.$emit('onClickClearPage', this.isClear) this.$emit('onClickClearPage', this.isClear)
}, },
handleRotate() { 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> <dv-loading>Loading...</dv-loading>
</div> </div>
<!-- Header --> <!-- 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"> <div class="page-nav">
@ -23,7 +23,7 @@
</ul> </ul>
</div> </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}"> <ul v-if="isGetClear" :class="{ 'right-fixed': true, 'animate__fadeInRight': isGetClear}">
<li>20</li> <li>20</li>

17
src/views/pageBasement/index.vue

@ -118,7 +118,17 @@ export default {
}, '*') }, '*')
}, },
handleMessageEvent(event) { handleMessageEvent(event) {
if (event.data && event.data.data) {
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)
}
break
case 'cameraClick':
{
const data = event.data.data const data = event.data.data
console.log(data) console.log(data)
// //
@ -133,6 +143,11 @@ export default {
}) })
} }
} }
break
default:
console.log('errorwww:', event.data)
}
}
}, },
handleViewVideo(item) { handleViewVideo(item) {
this.$refs.camera.videoTitle = item.name this.$refs.camera.videoTitle = item.name

17
src/views/pageFullView/index.vue

@ -178,7 +178,17 @@ export default {
}, '*') }, '*')
}, },
handleMessageEvent(event) { handleMessageEvent(event) {
if (event.data && event.data.data) {
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)
}
break
case 'cameraClick':
{
const data = event.data.data const data = event.data.data
console.log(data) console.log(data)
// //
@ -193,6 +203,11 @@ export default {
}) })
} }
} }
break
default:
console.log('errorwww:', event.data)
}
}
}, },
handleViewVideo(item) { handleViewVideo(item) {
this.$refs.camera.videoTitle = item.name this.$refs.camera.videoTitle = item.name

19
src/views/pageThirdFloor/index.vue

@ -98,7 +98,7 @@ export default {
if (value === 'false') { if (value === 'false') {
const data = [ const data = [
{ {
'deviceId': 'S004',
'deviceId': 'S003',
'isAlarm': true 'isAlarm': true
}, },
{ {
@ -125,7 +125,17 @@ export default {
}, '*') }, '*')
}, },
handleMessageEvent(event) { handleMessageEvent(event) {
if (event.data && event.data.data) {
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)
}
break
case 'cameraClick':
{
const data = event.data.data const data = event.data.data
console.log(data) console.log(data)
// //
@ -140,6 +150,11 @@ export default {
}) })
} }
} }
break
default:
console.log('errorwww:', event.data)
}
}
}, },
handleViewVideo(item) { handleViewVideo(item) {
this.$refs.camera.videoTitle = item.name this.$refs.camera.videoTitle = item.name

17
src/views/pageWaterPumpHouse/index.vue

@ -163,7 +163,17 @@ export default {
}, '*') }, '*')
}, },
handleMessageEvent(event) { handleMessageEvent(event) {
if (event.data && event.data.data) {
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)
}
break
case 'cameraClick':
{
const data = event.data.data const data = event.data.data
console.log(data) console.log(data)
// //
@ -178,6 +188,11 @@ export default {
}) })
} }
} }
break
default:
console.log('errorwww:', event.data)
}
}
}, },
handleViewVideo(item) { handleViewVideo(item) {
this.$refs.camera.videoTitle = item.name this.$refs.camera.videoTitle = item.name

Loading…
Cancel
Save