news 2026/10/24 2:17:19

第73篇:位置信息栏控件——把相机状态和鼠标坐标钉成一行常显

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第73篇:位置信息栏控件——把相机状态和鼠标坐标钉成一行常显

上一次我们拆了提示浮层,结尾我埋了个话头:控件家族那位"常驻角落"的常客还没出场,下一个登场的是位置信息栏控件——它不跟光标跑,而是钉在屏幕底部,把当前相机的经纬度、视角、高度,连同鼠标此刻脚下的经纬度、海拔,一起焊成一行常显的状态条。今天就把这行字拆开。

顺带把进度摆一下:地图控件这条线一路走来,罗盘读相机朝向(#68)、气泡写浮层追地表点(#69)、图表焊图到地球(#70)、缩放挪相机对准焦点(#71)、提示浮层跟光标报坐标(#72),现在轮到位置信息栏把这家人凑成第六位——而且它最像"把前面几个人的活合并成一行字"。

💡 本文涉及的全部代码均已开源,完整的仓库地址见文末,可自行取用、随意魔改。


你大概率在无数 GIS 网站的底部见过它:屏幕下方一行小字,左边是"经度 118.8° / 纬度 32.05° / 海拔 0.0 米",右边是"视角 −90.0° / 视高 260000.0 米"。看起来天经地义,仿佛 Cesium 自带一个LocationBar类,你只要viewer.locationBar.show()就完事。

但和前面几篇一样,第一件事还是先拆穿:Cesium 的公开 API 里,根本没有 LocationBar / StatusBar 这种东西。

屏幕底下那行字,本质是一个普通的<div>,加上两段"监听 → 翻译 → 填字"的逻辑。Cesium 从头到尾只负责两件事——"屏幕像素 → 地球坐标"的翻译(鼠标部分),和把相机自身状态读给你(相机部分)。其余全是你的 DOM 手艺。


一、先拆穿:位置信息栏不是新物种,是"鼠标坐标 + 相机状态"并排成一行

先看 demo 里那行状态条到底长什么样。它就是一个挂在地图容器底部的<div>:

<divv-if="enabled"class="cesium-location-bar"><spanclass="mouse-location">经度:{{ mouseLng.toFixed(6) }}</span><spanclass="mouse-location">纬度:{{ mouseLat.toFixed(6) }}</span><spanclass="mouse-location">海拔:{{ mouseAlt.toFixed(1) }} 米</span><span>视角:{{ cameraPitch.toFixed(1) }}°</span><span>视高:{{ cameraHeight.toFixed(1) }} 米</span></div>

cesium-location-bar的样式很朴素:position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%)——也就是钉在画布底部正中、左右居中;深黑半透明底、一行白字、user-select: none、不换行。没有任何 Cesium 特有的标签——它就是网页里最普通的绝对定位浮层。

真正值得注意的是它身上的五个数,它们其实分属两件事:

  • 左边三个(鼠标经度 / 纬度 / 海拔)回答的是"鼠标这会儿踩在地球的哪个点"——这正是 #14 鼠标坐标、#27 移动提示、#72 提示浮层反复在做的那道题;
  • 右边两个(视角 / 视高)回答的是"相机这会儿站在哪儿、朝哪看"——这正是 #19 相机参数那篇十个数里的两个。

所以位置信息栏的真身可以压成一句话:一个常驻底部的 DOM div + 两条更新链路(一条跟鼠标、一条跟相机)+ 把"鼠标在哪"和"相机在哪"这两道题的答案并排焊成一行字。Cesium 只卖中间的翻译,浮层长相和并排逻辑全是你自己搭的。

顺带把这个 demo 的开关讲清楚,因为它正好对应"状态条要不要动"的两种层级。显示状态栏开关切的是enabled——它为真时把MOUSE_MOVE监听挂上 canvas、并把camera.changed的监听也加上;为假时直接removeInputAction摘掉鼠标监听、camera.changed.removeEventListener摘掉相机监听、并隐藏整条 div:这是"彻底不干活"。这和前面几篇讲过的"显隐到底摘不摘监听"是同一道设计题——彻底不用时连监听一起摘,省得空转。

还有个细节:状态条里鼠标海拔用的是{{ mouseAlt.toFixed(1) }},只留一位小数;而经度纬度是.toFixed(6),留六位。这不是随便定的:六位小数在 40°N 附近,纬度末位一格 ≈ 11 厘米、经度末位 ≈ 8.5 厘米(#27 实测过),够精细;海拔受地形采样精度限制,一位小数足矣,多写也写不出真精度。这个"不同读数不同位数"的讲究,恰恰是状态条比浮层更"像个仪表盘"的地方。

把位置信息栏和提示浮层(#72)摆在一起对照,差异会更刺眼:

维度提示浮层(#72)位置信息栏(#73)
锚定对象鼠标光标(div 跟着光标走)画布底部正中(div 固定不动)
显示内容鼠标所在点经纬度鼠标点经纬度海拔 + 相机视角视高
更新触发每次 MOUSE_MOVEMOUSE_MOVE(鼠标部分)+ camera.changed(相机部分)
冷启动没动就不存在显示一串 0,直到首次交互
典型坑浮层吞鼠标事件冷启动全 0、相机死区过大

一句话:提示浮层是"移了就报、跟着光标",位置信息栏是"钉在底部、把鼠标和相机两路答案常驻显示"。它们共用"div + 屏幕→地球翻译"的内核,却在安家和报数范围上分道扬镳。

顺带说一句"为什么 Cesium 不内置"。Cesium 的定位是"渲染引擎 + 一堆地理原语"——它给你球、相机、图元、拾取这些底层能力,但 UI 层(状态条、按钮、面板)从来不是它的活。状态条本质是 HTML/CSS 的事:在哪显示、什么样式、显示哪几个数、更新多频繁,全是浏览器 DOM 的管辖范围。Cesium 即便真给你一个LocationBar类,最后也得往 DOM 塞文字、定位置——和你自己写 div 没两样,还多一层 API 约束。所以"没有 LocationBar 类"不是疏漏,是边界划得清楚:读数归我,怎么摆字归你。


二、常驻 vs 跟随:和提示浮层(#72)长得像,住的院子却不一样

上一节那张对照表里最要命的一行是"锚定对象":提示浮层整个 div 跟着光标跑,位置信息栏整个 div 钉在底部不动、只有字在变。这层差异看着小,实则决定了后面一系列踩坑的走向。

提示浮层(#72)的定位算术是left = x + 12, top = y - 15——它把 div 摆到光标的右下方,光标挪到哪、div 跟到哪。所以#72 那篇的核心焦虑是"怎么让 div 不挡住光标、又不被光标吞掉事件"。

位置信息栏完全不操这份心:它的 div 用left: 50%; bottom: 12px; transform: translateX(-50%)焊死在底部正中,光标爱往哪飞都不影响它的位置。它唯一要更新的,是 div里面那五个<span>的文本。鼠标动一下,变的不是"条在哪",而是"经度那格写几度"。

这就引出一个容易混的点:位置信息栏的"鼠标经度/纬度"明明也跟着鼠标变,凭什么说它"不跟光标"?本猿给个干净的切分——div 的"位置"不跟光标,div 的"内容"跟鼠标。提示浮层是位置跟着走、内容也跟着走;位置信息栏是位置不动、内容(部分)跟着走。前者是"一块会飞的牌子",后者是"一块固定的仪表盘、指针在动"。这个切分很重要,因为它直接决定了坑的类型:提示浮层要防"浮层盖住光标、吞掉鼠标事件"(所以pointer-events: none是命门),位置信息栏因为 div 不挡光标、还稳稳压在底部,那条命门自动免了——但代价是它得操心另一类坑,第五节再说。

再往深一层看"并排成一行"这件事。状态条把鼠标三数和相机两数并排,意味着两条链路在写同一个 DOM 的不同格子,互不干扰:鼠标链写前三个<span>,相机链写后两个<span>。这比"一个浮层只报一件事"要克制得多——你不会为了让状态条多显示一个视角,就新增一个浮层,而是往那条已有的 div 里再塞一个<span>。这种"信息密度靠往固定容器里加字段"的做法,正是状态条(status bar)这个 UI 范式的精髓:位置固定、字段可变、不动如山。

也正是因为它"不动如山",它和提示浮层在"屏幕空间"里的角色恰好互补:提示浮层是"跟着你眼睛走的小跟班"(你盯着哪、它报哪),位置信息栏是"门口那块永远亮着的公告牌"(无论你看不看,它都告诉你全局状态)。一个近、一个远,一个追光标、一个守角落。这家人写到第六位,本猿越来越觉得:所谓"地图控件",大半是在"屏幕 ↔ 地球"之间反复横跳时,决定"答案往哪摆、怎么摆"的那点事——浮层往光标摆、状态条往角落摆、气泡往地表点摆,仅此而已。


三、两条更新链路:MOUSE_MOVE 管鼠标,camera.changed 管相机

把状态条拆成两路,最见功力的地方在"谁触发更新"。demo 里这两条链路用的是两种完全不同的驱动机制——这是整篇最该讲清、也最容易被想当然的地方。

鼠标那一路,走的是我们熟悉的老朋友MOUSE_MOVE:

functionmoveHandler(movement){if(!viewer||viewer.isDestroyed())return;constnow=performance.now();if(now<lastMouseUpdate+300)return;// 300ms 节流lastMouseUpdate=now;constscene=viewer.scene;constellipsoid=Ellipsoid.WGS84;letsurfacePosition;if(scene.mode===SceneMode.SCENE3D){constray=scene.camera.getPickRay(movement.endPosition);surfacePosition=ray?scene.globe.pick(ray,scene)??undefined:undefined;}else{surfacePosition=scene.camera.pickEllipsoid(movement.endPosition,ellipsoid)??undefined;}constcartographic=surfacePosition?ellipsoid.cartesianToCartographic(surfacePosition):undefined;mouseLng.value=CesiumMath.toDegrees(cartographic?.longitude??0);mouseLat.value=CesiumMath.toDegrees(cartographic?.latitude??0);mouseAlt.value=cartographic?scene.globe.getHeight(cartographic)??0:0;}

这段和 #72 提示浮层那一节几乎同宗:3D 下getPickRay+globe.pick打地球表面(有地形带高度、无则椭球面 h≈0、不认 3D 物体),2D/Columbus 下pickEllipsoid(纯椭球几何、永远 h=0);翻译出cartographic后取经纬度,再额外用globe.getHeight取海拔。区别只在末端:#72 把结果塞进"跟着光标的浮层",#73 把结果塞进"底部状态条的前三个格子"。

真正新鲜的是相机那一路——它没有用postUpdate每帧去读相机,而是挂在了camera.changed事件上:

functioncameraHandler(){if(!viewer||viewer.isDestroyed())return;constnow=performance.now();if(now<lastCameraUpdate+300)return;// 同样 300ms 节流lastCameraUpdate=now;constposition=Ellipsoid.WGS84.cartesianToCartographic(viewer.camera.positionWC);cameraPitch.value=CesiumMath.toDegrees(viewer.camera.pitch);cameraHeight.value=position.height;}// 挂载:viewer.camera.changed.addEventListener(cameraHandler);

这里有个关键判断本猿要拎出来说:为什么是camera.changed而不是 #14 用过的scene.postUpdate?

读Camera.js源码(Cesium 1.144,Build/CesiumUnminified/Cesium.js)能确认两件事。第一,camera.changed是一个货真价实的Event——构造函数里this._changed = new Event()(L224004),并通过 getter 暴露(L224705get changed() { return this._changed; })。第二,它有个死区阈值percentageChanged,默认 0.5(L224010)。_updateCameraChanged每帧检查:3D 下,若相机方向变化超过fovy/2 × 0.5、或位置移动超过"当前椭球高 × 0.5",就raiseEvent触发监听(L224211-224214);2D 下则是视口面积变化超过 50% 才触发(L224178)。换句话说,camera.changed自带一个50% 的死区——相机得真挪了一大截,才通知你"我变了"。

这正好是状态条想要的:它要的是"相机大致到哪了",不是"相机每一帧的精确姿态"。用postUpdate(如 #14)会每帧都跑一遍读数与 DOM 写入,静止时纯属空转;用camera.changed,不动就不通知、微小抖动也过滤掉,只有相机真动了足够多才刷新。对一行常驻状态条来说,camera.changed比postUpdate省心得多——它把"要不要刷新"这道题,从"你自己每帧判断"变成了"引擎按死区替你判断"。

把两路摆成一张表,差异一眼就清:

链路触发源节流默认灵敏度写哪些格子
鼠标路MOUSE_MOVE(每次鼠标移动)300ms 丢帧跟手,仅受节流限制经度 / 纬度 / 海拔
相机路camera.changed(方向或位移超 50% 死区)300ms 丢帧高海拔时要挪 130km 才刷新视角 / 视高

注意表里"相机路"那行"高海拔时要挪 130km 才刷新"——这是死区的副作用,值得单说。死区是"位移 > 当前椭球高 × 0.5",demo 初始相机在 260000 米高空,意味着相机得一次性平移超过 130000 米,状态条的视高才会刷新一次。低空时(比如相机离地 2km)只要挪 1km 就刷新,灵敏得多。所以你若在高空慢慢平移,会发现状态条的"视高"半天不更新——不是代码坏了,是 50% 死区在高空被放得很大。生产里要更跟手,可以把camera.percentageChanged调到 0.1,或干脆改回postUpdate(代价是静止时也空转)。这是camera.changed方案最该被权衡的一点。

顺带把enabled开关的链路管理讲完整,因为它是状态条在"彻底不用时"的正确收尾。demo 的onEnableChange在关掉时做了两件事:handler.removeInputAction(MOUSE_MOVE)摘掉鼠标监听、viewer.camera.changed.removeEventListener(cameraHandler)摘掉相机监听——两者一起摘,状态条才真正停更、不留空转。这里有个源码级的红利值得点破:前面读过camera.changed在每帧检查前先if (camera._changed.numberOfListeners === 0) return(L224114),也就是说你把监听摘掉之后,引擎连"判断相机动没动"这道计算都跳过,彻底零成本。反过来,重新打开时addEventListener挂回监听,计算才恢复。这比"一直挂着监听、只是不更新 DOM"要干净——状态条不用时,连引擎那点开销都还给你了。这条"显隐到底摘不摘监听"的题,从 #69 气泡到 #72 浮层到 #73 状态条反复出现,答案始终是:确定不用,就连监听一起摘。


四、海拔、视角、视高:三个读数分别怎么爬出来的

状态条五个读数里,只有"鼠标经度/纬度"是纯翻译(#72 讲透了),剩下三个——鼠标海拔、相机视角、相机视高——各有各的来历,且都藏着"读的是椭球还是真实地形"的陷阱。

鼠标海拔:来自globe.getHeight,本质是 CPU 地形采样。
mouseAlt.value = cartographic ? scene.globe.getHeight(cartographic) ?? 0 : 0。globe.getHeight是 CPU 端用射线和地形瓦片网格求交取高度(#22/#23 都扒过它),瓦片没加载好就返undefined,demo 用?? 0兜底。这就把 #72 那个"裸椭球基线"的结论又搬了一次:只要没加载地形,globe.getHeight落点永远是椭球面,鼠标海拔稳定显示0.0——不是算错了,是它压根没去量山。本猿用探针实测过:相机在 (118.8°, 32.05°) 上方 260km 垂直俯视,未加载地形时任何屏幕点的地表高度h = 0.000000,加载地形后才会跳出真实海拔。要看到非 0 海拔,要么先sampleTerrainMostDetailed把地形瓦片拉下来,要么像 #72 说的用pickPosition走深度缓冲。

相机视角:来自camera.pitch,纯几何、和地形无关。
cameraPitch.value = CesiumMath.toDegrees(viewer.camera.pitch)。Cesium 的pitch是相机绕本地 X 轴的旋转角,取值[-π/2, π/2]。本猿用探针确认了换算:俯视(看向地心方向)pitch = -π/2 → -90.0°,水平看地平线pitch = 0 → 0.0°,仰视 45°pitch = +45.0°。demo 初始setView没指定 orientation,默认就是俯视,所以开局"视角"那一格是-90.0——一眼就能看出相机是正扣下来的。这里有个口径要提醒:状态条报的"视角"是相机自身俯仰,不是"视线与地面的夹角";它和 #19 相机参数那篇的 pitch 是同一个数,纯几何、不查地形。

相机视高:来自camera.positionWC反算椭球高,同样是纯几何。
position = Ellipsoid.WGS84.cartesianToCartographic(viewer.camera.positionWC); cameraHeight.value = position.height。positionWC是相机在世界坐标的位置,cartesianToCartographic把它反算成经纬度和椭球高。本猿用探针实测:demo 的fromDegrees(118.8, 32.05, 260000)落点反算回来,height = 260000.000000、经度纬度分毫不差。所以"视高"读的是相机离 WGS84 椭球面的高度,不是离地形的高度——你飞在 260km 高空、脚下是 4000 米的山,它照样报 260000.0,不会减掉那 4km。要"离地高度"得自己拿globe.getHeight在相机正下方补一刀,状态条没做这步。

把三个读数摆成一张表,来历和陷阱都清楚:

读数来源是否查地形裸椭球/无地形时
鼠标海拔globe.getHeight(cartographic)是(CPU 采样)恒0.0(椭球面)
相机视角camera.pitch否(纯几何)-90.0(默认俯视)
相机视高cartesianToCartographic(camera.positionWC).height否(椭球高)260000.0(初始落点)

一句话点破:状态条五个读数里,只有鼠标海拔真正去量了地形,其余四个全是"椭球/几何"层面的真值。这也是为什么你常看到"经度纬度在变、海拔死死是 0.0"——前四个数不依赖地形,唯独海拔那一格在等你加载地形。本猿反复唠叨这个口径,是因为它直接决定"状态条准不准":准不准不取决于你的 div 代码,而取决于你选了哪条拾取路径、那条路径此刻有没有真实地形可量——这话在 #72 说过一次,到 #73 还是得再说一遍,因为它藏在每一个"坐标类"控件里。


五、300ms 节流与冷启动:两个常被忽略的细节

把前面几节串起来,有两个细节几乎每次写状态条都要单独点名,因为它们太容易想当然——一个是节流,一个是冷启动。

细节一:300ms 节流是"丢帧"不是"合帧",且它连便宜的经纬度一起卡了。
两条链路都写了if (now < last + 300) return,意思是"距上次更新不足 300ms 就直接跳过"。本猿算过:300ms 相当于每秒最多更新约 3.33 次。要明白它是"丢帧"式——它保留的是"最近一次被接受的那次坐标",中间快速划过的点全丢了。所以鼠标飞快划过地球时,状态条的经度纬度会滞后光标最多 300ms,肉眼大致无感,但高速甩动时能看出条比光标慢半拍。

更要命的是:demo 把整段moveHandler一起节流了,包括最便宜的经纬度翻译。可经纬度翻译(getPickRay+globe.pick+cartesianToCartographic)本身不贵,贵的是末尾那句globe.getHeight地形采样(CPU 射线求交)。更"外科手术式"的写法是把节流拆开:经纬度每帧(或每 ~50ms)更新、海拔单独 300ms 更新——这样坐标跟手、海拔省算力。demo 为了简单把两者绑在一起,是个能跑但不最优的选择,生产里你大概率要拆。这点和前面每篇讲"性能"时的结论一脉相承:节流要卡在贵的那一步,别连免费的也一起卡。

细节二:冷启动全 0,直到你第一次动。
状态条五个格子初始都是ref(0)——经度 0、纬度 0、海拔 0、视角 0、视高 0。问题在:鼠标链要等第一次MOUSE_MOVE才填,相机链要等camera.changed第一次触发才填。而camera.changed在首帧有个陷阱:源码里若_changedPosition还没初始化,它只clone一下当前相机位置就return(L224188-224197),根本不raiseEvent——所以即便onMounted里setView把相机摆到了 260km 高空,camera.changed在头一帧也不会通知你,状态条的"视角/视高"会一直停在 0,直到你真的拖动一次镜头。

本猿第一次跑这个 demo 时就愣了一下:地球都飞到 260km 了,底部还写着"视角 0.0° / 视高 0.0 米"。这不是 bug,是"事件驱动 + 冷启动未预填"的天然结果。修法很简单、也该写进生产:在onMounted末尾主动调一次cameraHandler()(把初始相机姿态填进状态条),再模拟一次moveHandler把鼠标默认点填进去。一句话——事件驱动的 UI,加载完要手动预填一次,别等第一次交互。

还有个和 #72 同源的坑要再点一次:光标移出地球、globe.pick返undefined时,demo 用surfacePosition ? ... : undefined挡了一道,再cartographic ? ... : 0兜底——绝不能拿undefined去cartesianToCartographic,否则浮层变NaN、状态条闪一串乱码。这条"打空必判空"的护身符,从 #66 比例尺到 #72 浮层到 #73 状态条,本猿说过三遍了,但它每次都还在咬新人,所以再说一遍不嫌多。

把两个细节压成一句提醒:节流要卡在贵的那步、别连便宜的也卡;事件驱动的状态条加载完要手动预填,否则开局全是 0——这两点漏掉任何一个,状态条都会在你看不见的地方悄悄失真。


六、写在最后

把这一篇收一下,位置信息栏的真身可以压成三句话:先并排(一个钉在底部的常驻 div,把"鼠标坐标 + 相机状态"焊成一行)、再分流(鼠标三数走MOUSE_MOVE、相机两数走camera.changed这个自带 50% 死区的事件)、最后填字(三个读数里只有鼠标海拔真去量地形,视角/视高/经纬度全是椭球或几何真值,且别忘了 300ms 节流要卡在贵处、冷启动要手动预填)。它和提示浮层(#72)最像——都是 div、都靠"屏幕→地球"的翻译——却又因为一个"锚光标、整块飞"、一个"锚角落、只动字",在定位算术、命门坑、更新机制上走上两条不同的路。

控件家族这条线现在凑齐了六位常客:罗盘读相机朝向(#68)、气泡写浮层追地表点(#69)、图表焊图到地球(#70)、缩放挪相机对准焦点(#71)、提示浮层跟光标报坐标(#72)、位置信息栏钉角落并排报状态(#73)。前四个站在地球一侧把信息贴上去或读出来,后两个站在屏幕一侧把坐标和状态亮出来。看似各管一摊,底层全是同一道题的变体:如何在"屏幕像素"和"地球坐标"之间反复横跳,且每次都不许漂、不许反、不许在边界翻车。

落到工程上,写状态条有两句口诀:相机部分用camera.changed带死区最省心(但高空死区会被放大,要跟手就调小percentageChanged或改postUpdate),鼠标部分用MOUSE_MOVE配节流(但节流只卡globe.getHeight那步、别连经纬度一起卡);冷启动手动预填一次、打空必判空。把这两句和"只有鼠标海拔真查地形、其余都是椭球/几何真值"一起记住,位置信息栏基本就焊死了。它和前面五位一样,看着是个小控件,背后全是你和"屏幕 ↔ 地球"那道翻译的拉锯——这条主轴你现在已经摸得相当透了。

把六位常客往深里看,其实"用字报状态"只是状态栏的一种脸。这条线往后的站,下一个登场的是鹰眼小地图控件:它不写一行字,而是在角落放一个缩小的全局图、用个矩形框标出你当前视口覆盖了哪块地——和位置信息栏刚好是"用字报状态"vs"用图报状态"的两张脸。这家人还没写到头,咱们下回再拆。

如果你也在 Cesium 上做过状态栏,欢迎留言说说你选了camera.changed还是postUpdate来喂相机读数——那个 50% 死区在高空把你坑过没有?


🌟 项目已开源,欢迎 Star!(你的 Star ⭐ 就是对我最大的支持!)

仓库地址:https://github.com/jianlei-wang/CESIUM-TREASURE-BOX

代码在src/cases/widget-location-bar/目录下,核心就一个WidgetLocationBarDemo.vue。搬去自己项目时,盯住三件事:camera.changed自带 50% 死区(高空刷新会显著变迟钝,要跟手可调小percentageChanged)、MOVE节流只卡globe.getHeight那步别连经纬度一起卡、加载完手动调一次cameraHandler预填冷启动。


Cesium酱の百宝箱 · 第 73 篇
状态条本寻常 div,鼠标相机共一行
2026 年的秋夜,与你共探「角落那行字怎么把世界读给眼睛听」

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/24 2:15:31

浙江法治报刊登债权债务公告登报办理流程

一、浙江法治报债权债务公告概述浙江法治报是浙江省内具有权威性和公信力的法治类专业媒体&#xff0c;是刊登债权债务公告的重要渠道。无论是企业合并、分立、清算过程中的债权申报公告&#xff0c;还是个人债权债务声明&#xff0c;通过浙江法治报刊登发布&#xff0c;能够确…

作者头像 李华
网站建设 2026/10/24 2:15:29

#从裸机到Linux:我的嵌入式开发成长路线图#

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/24 2:15:01

02-JDK 9 模块化与 JShell:项目结构将彻底改变

JDK 8 把写法范式定下来了&#xff0c;JDK 9 干的是另一件大事——给 JDK 自身和你的应用做"模块化"。这是 Java 历史上改动最底层的一次发布&#xff08;连 JDK 内部都拆成了几十个模块&#xff09;&#xff0c;也带来了程序员能直接玩的两个甜点&#xff1a;JShell…

作者头像 李华
网站建设 2026/10/24 2:14:19

RPCS3 固件安装教程:快速装好 PS3 固件并避开 5 个常见报错

RPCS3 固件安装教程&#xff1a;快速装好 PS3 固件并避开 5 个常见报错 【免费下载链接】rpcs3 PlayStation 3 emulator and debugger 项目地址: https://gitcode.com/GitHub_Trending/rp/rpcs3 你打开游戏列表&#xff0c;Play 按钮灰着点不动&#xff0c;日志窗口刷出…

作者头像 李华
网站建设 2026/10/24 2:14:19

桌面宠物DyberPet:3分钟装好一个能喂食、能管番茄钟的数字伙伴

桌面宠物DyberPet&#xff1a;3分钟装好一个能喂食、能管番茄钟的数字伙伴 【免费下载链接】DyberPet Desktop Cyber Pet Framework based on PySide6 项目地址: https://gitcode.com/GitHub_Trending/dy/DyberPet 如果你的桌面除了壁纸和任务栏什么都没有&#xff0c;D…

作者头像 李华