实时光照数据存储

This commit is contained in:
2025-11-11 09:27:49 +08:00
parent 64cad82a92
commit b6324bcbd6
4 changed files with 611 additions and 64 deletions

View File

@ -10,6 +10,7 @@
<span class="text">光照效果</span>
<svg-icon
class="switchClass"
id="weatherSwitch"
name="switch"
:size="16"
:title="switchStatus ? '关闭光照' : '开启光照'"
@ -24,6 +25,7 @@
<div class="col">
<span class="label">实时光照</span>
<el-switch
id="shineSwitch"
v-model="weatherData.currWeather"
style="
--el-switch-on-color: rgba(var(--color-base1), 1);
@ -172,6 +174,11 @@ import { Decimal } from 'decimal.js'
import { ElMessage } from 'element-plus'
import TimeLine from './timeLIne'
import { before } from 'node:test'
import { set } from 'date-fns'
const props = defineProps({
parentClick: Boolean
})
var sunshine
var timeline
var list = reactive([
@ -243,23 +250,91 @@ var weatherData: any = reactive({
})
onMounted(() => {
timeline = new TimeLine(window.earth, weatherData.speed)
//判断是否在外面开启光照
let myData = null
if (window.sunshine) {
let data = JSON.parse(localStorage.getItem('shineSetting'))
// weatherData.currWeather = data.currWeather
//是否是实时光照
if (!data.currWeather) {
weatherData.time = data.time
}
weatherData.softShadow = data.softShadow
weatherData.darkness = data.darkness
weatherData.speed = data.speed
data.wearther.forEach((item, index) => {
list[index].status = item.status
})
// list = data.wearther
switchStatus.value = true
sunshine = window.sunshine
myData = formatTimeToBeijing()
}
timeline && timeline.clear()
timeline = new TimeLine(window.earth, weatherData.speed, switchStatus.value, myData, initCallback)
window.pauseBut && document.getElementById('timePause').click()
// sunshine = new YJ.Global.efflect.Sunshine(window.earth, { id: 123 })
timeline.moveComplay((item) => {
weatherData.currWeather = false
sunshine.timeBar = item
})
// timeline.setTime(myData)
//如果实时天气打开,时间条移动
if (weatherData.currWeather) {
document.getElementById('timePause')?.click()
}
// timeline.updateTime()
// timeline.setCurrBar()
})
onBeforeUnmount(() => {
sunshine && sunshine.remove()
//关闭弹框时存储数据
let data = {
currWeather: weatherData.currWeather,
softShadow: weatherData.softShadow,
darkness: weatherData.darkness,
speed: weatherData.speed,
time: weatherData.time,
timeerTime: document.getElementById('currentTime').textContent,
wearther: list
}
localStorage.setItem('shineSetting', JSON.stringify(data))
// sunshine && sunshine.remove()
timeline && timeline.clear()
emit('isPause', document.getElementById('timePause').textContent == '播放')
})
var formatTimeToBeijing = () => {
let time = window.earth.viewer.clock.currentTime
// 创建新的JulianDate对象
var julianDT = new Cesium.JulianDate()
// 添加8小时时区偏移转换为北京时间:ml-citation{ref="1,4" data="citationList"}
Cesium.JulianDate.addHours(time, 8, julianDT)
// 转换为公历日期:ml-citation{ref="4,6" data="citationList"}
var gregorianDT = Cesium.JulianDate.toGregorianDate(julianDT)
// 格式化为时分秒字符串,确保两位数显示:ml-citation{ref="4,6" data="citationList"}
var hour = gregorianDT.hour.toString().padStart(2, '0')
var minute = gregorianDT.minute.toString().padStart(2, '0')
var second = gregorianDT.second.toString().padStart(2, '0')
return `${hour}:${minute}:${second}`
}
let currWeatherData = false
//js返回数据
var initCallback = (data) => {
weatherData.currWeather = data
}
var weatherChange = () => {
currWeatherData = true
if (weatherData.currWeather) {
let ss = getCurrentTime()
sunshine && (sunshine.timeBar = ss)
@ -276,6 +351,14 @@ var weatherChange = () => {
timeline.closeChangeDate()
// sunshine && (sunshine.time = weatherData.time)
if (!switchStatus && document.getElementById('timePause').textContent == '播放') {
document.getElementById('timePause').click()
}
} else {
if (!switchStatus && document.getElementById('timePause').textContent == '暂停') {
//如果光照开关关闭,关闭实时光照,停止时间条
document.getElementById('timePause').click()
}
}
}
var getDateTimeString = () => {
@ -337,10 +420,16 @@ var getCurrentTime = () => {
return `${hours}:${minutes}:${seconds}`
}
var switchFunc = () => {
switchStatus.value = !switchStatus.value
if (switchStatus.value) {
//开启
const emit = defineEmits(['childEvent', 'isPause'])
//监听父组件点击
watch(
() => props.parentClick,
(newVal, oldVal) => {
switchStatus.value = newVal
// 如果点击icon时当前设置页面一打开使用当前数据
if (newVal) {
sunshine = new YJ.Global.efflect.Sunshine(window.earth, {
id: 123,
speed: weatherData.speed,
@ -348,15 +437,43 @@ var switchFunc = () => {
// @ts-ignore
hour: document.getElementById('currentTime').textContent
})
timeline.setSunShine(true)
window.sunshine = sunshine
}
}
)
var switchFunc = () => {
switchStatus.value = !switchStatus.value
if (switchStatus.value) {
//开启
if (!window.sunshine) {
sunshine = new YJ.Global.efflect.Sunshine(window.earth, {
id: 123,
speed: weatherData.speed,
time: weatherData.time,
// @ts-ignore
hour: document.getElementById('currentTime').textContent
})
} else {
sunshine = window.sunshine
sunshine.timeBar(document.getElementById('currentTime').textContent)
if (weatherData) {
sunshine.darkness = weatherData.darkness
sunshine.speed = weatherData.speed
sunshine.softShadow = weatherData.softShadow
}
}
// timeline.setSunShine(true)
} else {
//关闭
sunshine && sunshine.remove()
sunshine = null
// let timeData = now.setHours(0, 0, 0, 0) // 设置为当天0点
// timeline.updateTime(timeData)
timeline.setSunShine(false)
// sunshine && sunshine.remove()
// sunshine = null
// delete window.sunshine
// timeline.setSunShine(false)
}
//联动外面的图标
// emit('childEvent', switchStatus.value)
emit('childEvent', weatherData)
}
//雨特效
@ -390,6 +507,7 @@ var clickIcon = (item: any) => {
}
}
var clickTimeIcon = (item: any) => {
weatherData.currWeather = false
if (document.getElementById('timePause').textContent == '播放') {
timelist.forEach((data) => {
if (data.name != item.name) data.status = false

View File

@ -0,0 +1,263 @@
// @ts-nocheck
import { ElMessage } from 'element-plus'
export default class TimeLine {
constructor(sdk, speed) {
this.sdk = { ...sdk };
this.progress = document.getElementById('progress');
this.handle = document.getElementById('handle');
// this.timeline = document.getElementById('timeline');
this.timeline = document.getElementsByClassName('timeline-container')[0];
this.currentTime = document.getElementById('currentTime');
this.timelineCon = document.getElementsByClassName('timeline-container')[0];
this.speed = speed;
this.animationId;
this.startTime = performance.now();
this.manualPosition = null;
// this.manualPosition = this.calculateTimePercentage();
this.isDragging = false;
this.pauseed = true;
this.time = '';
this.sunShine = false;
if (this.pauseed) {
this.pausedTime = this.startTime
}
this.update = this.update.bind(this);
TimeLine.init(this)
}
static init(that) {
for (let i = 0; i <= 24; i++) {
if (i % 6 === 0) {
const label = document.createElement('div');
label.className = 'time-mark';
label.textContent = `${i}:00`;
label.style.left = `${(i / 24) * 100}%`;
document.getElementsByClassName('time-marks')[0].appendChild(label)
const point = document.createElement('div');
point.className = 'time-Point';
document.getElementsByClassName('time-marks')[0].appendChild(point)
}
}
that.setCurrBar()//设置当前时间
that.startTime = performance.now() - ((that.manualPosition || 0) * 86400 * 1000 / that.speed);
that.timeline.addEventListener('mousedown', (e) => {
if (e.srcElement.className === 'handle') {
if (!that.sunShine) {
ElMessage({
message: '请开启光照功能',
type: 'warning'
})
} else {
that.isDragging = true;
}
}
e.preventDefault();
});
that.timeline.addEventListener('mousemove', (e) => {
if (!that.isDragging) return;
const rect = that.timeline.getBoundingClientRect();
let pos = (e.clientX - rect.left) / rect.width;
pos = Math.max(0, Math.min(1, pos));
that.manualPosition = pos;
that.progress.style.width = `${pos * 100}%`;
const seconds = pos * 86400;
that.currentTime.textContent = that.formatTime(seconds);
});
that.update();
document.getElementById('timePause').addEventListener('click', function () {
if (!that.sunShine) {
ElMessage({
message: '请开启光照功能',
type: 'warning'
})
} else {
that.pauseed = !that.pauseed;
if (that.pauseed) {//暂停
that.pausedTime = performance.now(); // 记录暂停时刻
document.getElementById('timePause').textContent = '播放';
that.animationId && cancelAnimationFrame(that.animationId);
that.sdk.viewer.clock.shouldAnimate = false
} else {//播放
let now = performance.now()
const pausedDuration = now - that.pausedTime;
document.getElementById('timePause').textContent = '暂停';
that.manualPosition = null
that.startTime += pausedDuration; // 补偿暂停期间的时间差
if (that.changeDate) {//切换日期后让时间从0开始
if (that.changeDateGrag) {
that.changeDateGrag = undefined
} else {
that.startTime = now
}
that.changeDate = undefined
}
if (document.getElementById('weatherSwitch').style.color === 'rgba(var(--color-base1), 1)') {//判断光照开关是否开启开启则打开cesium阴影
that.sdk.viewer.clock.shouldAnimate = true
}
that.update(); // 重启动画循环
}
}
});
}
setSunShine(v) {
this.sunShine = v
if (this.sunShine) {
document.getElementById('timePause')?.click()
} else {
this.pauseed = true
this.pausedTime = performance.now(); // 记录暂停时刻
document.getElementById('timePause').textContent = '播放';
this.animationId && cancelAnimationFrame(this.animationId);
this.sdk.viewer.clock.shouldAnimate = false
// document.getElementById('timePause')?.click()
}
}
calculateTimePercentage() {
// 获取当前时间
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
const seconds = now.getSeconds();
// 计算当前时间总秒数
const totalSeconds = (hours * 3600) + (minutes * 60) + seconds;
// 24小时总秒数
const totalSecondsInDay = 24 * 3600;
// 计算百分比并保留两位小数
const percentage = (totalSeconds / totalSecondsInDay);
return percentage;
}
moveComplay(func) {
let that = this
// that.timeline.addEventListener('mouseup', () => {
document.addEventListener('mouseup', () => {
if (that.isDragging) {
that.isDragging = false;
if (that.manualPosition !== null) {
// that.sdk.viewer.clock.shouldAnimate = true
that.startTime = performance.now() - (that.manualPosition * 86400 * 1000 / that.speed);
that.manualPosition = null;
that.changeDate && (that.changeDateGrag = true)
if (!that.pauseed) {
that.update()
func(that.time)
} else {
that.pausedTime = performance.now(); // 记录暂停时刻
func(that.currentTime.textContent)
}
}
}
});
}
setCurrBar() {
let pos = this.calculateTimePercentage()
this.manualPosition = pos;
this.progress.style.width = `${pos * 100}%`;
const seconds = pos * 86400;
this.currentTime.textContent = this.formatTime(seconds);
}
formatTime(seconds) {
const hrs = Math.floor(seconds / 3600).toString().padStart(2, '0');
const mins = Math.floor((seconds % 3600) / 60).toString().padStart(2, '0');
const secs = Math.floor(seconds % 60).toString().padStart(2, '0');
return `${hrs}:${mins}:${secs}`;
}
update() {
if (this.manualPosition !== null) return;
if (this.changeDate) {//切换日期后让时间从0开始
this.startTime = performance.now()
}
let elapsed = (performance.now() - this.startTime) * this.speed;
// if (this.elapsed) {
// elapsed = elapsed + this.elapsed
// this.elapsed = undefined
// }
const totalSeconds = elapsed / 1000;//秒
const daySeconds = totalSeconds % 86400;//天
const percentage = daySeconds / 86400;
this.progress.style.width = `${percentage * 100}%`;
this.time = this.formatTime(daySeconds)
this.currentTime.textContent = this.time;
if (!this.pauseed) {
this.animationId && cancelAnimationFrame(this.animationId);
this.animationId = requestAnimationFrame(this.update);
}
}
setSpeed(v) {
let now = performance.now()
if (!this.pauseed) {
const currentProgress = this.manualPosition ??
(performance.now() - this.startTime) * this.speed / (86400 * 1000);
this.speed = v;
this.startTime = performance.now() - (currentProgress * 86400 * 1000 / this.speed);
} else {
let pausedDuration = now - this.pausedTime;
this.startTime += pausedDuration; // 补偿暂停期间的时间差
const currentProgress = this.manualPosition ??
(now - this.startTime) * this.speed / (86400 * 1000);
this.speed = v;
this.startTime = now - (currentProgress * 86400 * 1000 / this.speed);
this.pausedTime = now; // 记录切换speed暂停时刻
// this.speed = v;
}
this.manualPosition = null;
// this.update();
}
setTime(time) {
// 解析传入的时间字符串 "6:40"
const [hours, minutes] = time.split(':').map(Number);
// 设置秒数为0
const seconds = 0;
// 计算传入时间总秒数
const totalSeconds = (hours * 3600) + (minutes * 60) + seconds;
// 24小时总秒数
const totalSecondsInDay = 24 * 3600;
// 计算百分比
const pos = totalSeconds / totalSecondsInDay;
this.manualPosition = pos;
this.progress.style.width = `${pos * 100}%`;
const displaySeconds = pos * 86400;
this.currentTime.textContent = this.formatTime(displaySeconds);
}
closeChangeDate() {
this.changeDate && (this.changeDate = false)
}
updateTime() {
this.manualPosition = null;
this.startTime = performance.now() - ((this.manualPosition || 0) * 86400 * 1000 / this.speed);
this.pauseed && (this.changeDate = true)
this.changeDateGrag = undefined
this.update();
}
clear() {
this.animationId && cancelAnimationFrame(this.animationId);
this.progress.style.width = '0%';
this.currentTime.textContent = '00:00:00';
}
}

View File

@ -1,7 +1,7 @@
// @ts-nocheck
import { ElMessage } from 'element-plus'
export default class TimeLine {
constructor(sdk, speed) {
constructor(sdk, speed, sunShine, timeWords, initCallback) {
this.sdk = { ...sdk };
this.progress = document.getElementById('progress');
this.handle = document.getElementById('handle');
@ -9,6 +9,7 @@ export default class TimeLine {
this.timeline = document.getElementsByClassName('timeline-container')[0];
this.currentTime = document.getElementById('currentTime');
this.timelineCon = document.getElementsByClassName('timeline-container')[0];
this.timeWords = timeWords;
this.speed = speed;
this.animationId;
this.startTime = performance.now();
@ -17,15 +18,15 @@ export default class TimeLine {
this.isDragging = false;
this.pauseed = true;
this.time = '';
this.sunShine = false;
this.sunShine = sunShine || false;
if (this.pauseed) {
this.pausedTime = this.startTime
}
this.update = this.update.bind(this);
TimeLine.init(this)
TimeLine.init(this, initCallback)
}
static init(that) {
static init(that, callback) {
for (let i = 0; i <= 24; i++) {
if (i % 6 === 0) {
@ -40,7 +41,7 @@ export default class TimeLine {
}
}
that.setCurrBar()//设置当前时间
that.setCurrBar(that.timeWords)//设置当前时间
that.startTime = performance.now() - ((that.manualPosition || 0) * 86400 * 1000 / that.speed);
that.timeline.addEventListener('mousedown', (e) => {
@ -73,18 +74,23 @@ export default class TimeLine {
that.update();
document.getElementById('timePause').addEventListener('click', function () {
if (!that.sunShine) {
ElMessage({
message: '请开启光照功能',
type: 'warning'
})
} else {
// if (!that.sunShine) {
// ElMessage({
// message: '请开启光照功能',
// type: 'warning'
// })
// } else {
that.pauseed = !that.pauseed;
if (that.pauseed) {//暂停
that.pausedTime = performance.now(); // 记录暂停时刻
document.getElementById('timePause').textContent = '播放';
that.animationId && cancelAnimationFrame(that.animationId);
that.sdk.viewer.clock.shouldAnimate = false
that.sdk.viewer && (that.sdk.viewer.clock.shouldAnimate = false)
//判断当没有开启光照时,点击停止播放时关闭实时光照按钮
if (document.getElementById('weatherSwitch').style.color == 'rgb(255, 255, 255)') {
callback(false)
}
} else {//播放
let now = performance.now()
const pausedDuration = now - that.pausedTime;
@ -99,10 +105,12 @@ export default class TimeLine {
}
that.changeDate = undefined
}
if (document.getElementById('weatherSwitch').style.color === 'rgba(var(--color-base1), 1)') {//判断光照开关是否开启开启则打开cesium阴影
that.sdk.viewer.clock.shouldAnimate = true
}
that.update(); // 重启动画循环
}
}
// }
});
}
@ -119,20 +127,56 @@ export default class TimeLine {
// document.getElementById('timePause')?.click()
}
}
calculateTimePercentage() {
// calculateTimePercentage() {
// // 获取当前时间
// const now = new Date();
// const hours = now.getHours();
// const minutes = now.getMinutes();
// const seconds = now.getSeconds();
// // 计算当前时间总秒数
// const totalSeconds = (hours * 3600) + (minutes * 60) + seconds;
// // 24小时总秒数
// const totalSecondsInDay = 24 * 3600;
// // 计算百分比并保留两位小数
// const percentage = (totalSeconds / totalSecondsInDay);
// return percentage;
// }
calculateTimePercentage(timeString = null) {
let totalSeconds;
if (timeString) {
// 解析传入的时间字符串 "HH:MM:SS"
const timeParts = timeString.split(':');
const hours = parseInt(timeParts[0]);
const minutes = parseInt(timeParts[1]);
const seconds = parseInt(timeParts[2]);
// 验证时间格式
if (isNaN(hours) || isNaN(minutes) || isNaN(seconds) ||
hours < 0 || hours > 23 ||
minutes < 0 || minutes > 59 ||
seconds < 0 || seconds > 59) {
throw new Error('Invalid time format. Please use "HH:MM:SS" format');
}
totalSeconds = (hours * 3600) + (minutes * 60) + seconds;
} else {
// 获取当前时间
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
const seconds = now.getSeconds();
// 计算当前时间总秒数
const totalSeconds = (hours * 3600) + (minutes * 60) + seconds;
totalSeconds = (hours * 3600) + (minutes * 60) + seconds;
}
// 24小时总秒数
const totalSecondsInDay = 24 * 3600;
// 计算百分比并保留两位小数
// 计算百分比
const percentage = (totalSeconds / totalSecondsInDay);
return percentage;
}
@ -159,8 +203,8 @@ export default class TimeLine {
}
});
}
setCurrBar() {
let pos = this.calculateTimePercentage()
setCurrBar(time) {
let pos = this.calculateTimePercentage(time)
this.manualPosition = pos;
this.progress.style.width = `${pos * 100}%`;

View File

@ -14,14 +14,22 @@
<div class="weather">
<svg-icon
name="weather"
ref="weatherIcon"
:class="weatherClick ? 'weatherClick' : ''"
:size="40"
@click="clickFun"
@contextmenu.prevent="clickFunRight"
></svg-icon>
</div>
</div>
<setTool ref="setToolRef"></setTool>
<weather ref="weatherRef" v-if="weatherClick"></weather>
<weather
ref="weatherRef"
v-if="weatherClickPop"
@childEvent="handleChildData"
@isPause="isPause"
:parentClick="weatherClick"
></weather>
<!-- <headButton class="headButton"></headButton> -->
</div>
@ -58,6 +66,17 @@ const headImg = computed(() => {
}
})
let weatherIcon = ref(null)
const handleChildData = (data) => {
clickFun(data)
}
//存储子组件播放按钮状态true暂停
const isPause = (data) => {
window.pauseBut = weatherClick && data ? true : false
}
const skinInfo = ref(JSON.parse(localStorage.getItem('systemSetting') || '{}').skinInfo || 'color1')
const { t } = useI18n()
@ -67,7 +86,6 @@ const date = ref({
week: 0
})
window.addEventListener('setItemEvent', (e: any) => {
console.log('e', e)
if (e.key == 'systemSetting') {
let obj = JSON.parse(e.newValue)
skinInfo.value = obj.skinInfo
@ -86,6 +104,7 @@ window.addEventListener('setItemEvent', (e: any) => {
}
})
var weatherClick = ref(false)
var weatherClickPop = ref(false)
const setTime = () => {
let date1 = new Date()
let year: any = date1.getFullYear()
@ -113,10 +132,113 @@ const timer = setInterval(setTime, 1000)
onUnmounted(() => {
clearInterval(timer)
})
var clickFun = () => {
let sunshine
var clickFun = (childData) => {
weatherClick.value = !weatherClick.value
console.log('点击天气', weatherClick.value)
if (weatherClick.value) {
let data = JSON.parse(localStorage.getItem('shineSetting'))
if (!data) {
const now = new Date()
const formattedDate = now.toISOString().slice(0, 10)
data = {
currWeather: true,
softShadow: true,
darkness: 0.4,
speed: 1,
time: formattedDate,
timeerTime: '00:00:00',
wearther: [
// 雨
{
name: '雨',
svg: 'rain',
status: false
},
// 雪
{
name: '雪',
svg: 'snow',
status: false
},
//雾
{
name: '雾',
svg: 'fog',
status: false
},
//星空
{
name: '星空',
svg: 'skystarry',
status: false
}
]
}
}
//光照
if (childData.currWeather === undefined && weatherClickPop.value === false) {
sunshine = new YJ.Global.efflect.Sunshine(window.earth, {
id: 123,
speed: data.speed,
time: data.currWeather ? new Date().toISOString().slice(0, 10) : data.time,
// @ts-ignore
hour: data.currWeather ? new Date().toLocaleTimeString() : data.timeerTime
})
window.sunshine = sunshine
sunshine.darkness = data.darkness
sunshine.softShadow = data.softShadow
//天气效果
if ((window as any).checkAuthIsValid) {
data.wearther.forEach((item) => {
if (item.status) {
func[item.svg](item)
}
})
} else {
// ElMessage({
// message: '您没有该功能的权限',
// type: 'warning'
// })
}
} else if (weatherClickPop.value === false) {
sunshine = new YJ.Global.efflect.Sunshine(window.earth, {
id: 123,
speed: childData.speed,
time: childData.time,
// @ts-ignore
hour: document.getElementById('currentTime').textContent
})
window.sunshine = sunshine
sunshine.darkness = childData.darkness
sunshine.softShadow = childData.softShadow
}
} else {
sunshine && sunshine.remove()
sunshine = null
window.sunshine && window.sunshine.remove()
delete window.sunshine
}
}
var func = {
rain: (item) => {
YJ.Global.efflect.rain(window.earth, item.status)
},
//雪
snow: (item) => {
YJ.Global.efflect.snow(window.earth, item.status)
},
//雾
fog: (item) => {
YJ.Global.efflect.fog(window.earth, item.status)
},
// 星空
skystarry: (item) => {
YJ.Global.efflect.skyStarry(window.earth, item.status)
}
}
var clickFunRight = () => {
weatherClickPop.value = !weatherClickPop.value
}
// onMounted(() => {