修改anchorPoint后图层发生变化的解决方案

本文介绍了在实现以特定点为原点进行图层旋转动画时,遇到修改anchorPoint引起图层位置变化的问题。通过重新设置位置以及在drawRect方法中播放动画,并在需要时调用重绘,成功临时解决该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天老大派发了新需求,做一个动画效果,就是以某个点做为原点,使图层做旋转的操作,心里默默盘算,只要修改anchorPoint即可,心中暗喜,奈何真正操作的时候,却遇到了这样那样的问题:在修改anchorPoint后,图层的位置会发生偏移,需要使用下列方法重新设置位置即可

- (void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view
{
    CGPoint oldOrigin = view.frame.origin;
    view.layer.anchorPoint = anchorPoint;
    CGPoint newOrigin = view.frame.origin;

    CGPoint transition;
    transition.x = newOrigin.x - oldOrigin.x;
    transition<
showDevicesOnMap(devices) { // 清除旧图 ["devices-layer", "device-labels", "selection-layer"].forEach( (layerId) => { if (this.mapObj.getLayer(layerId)) this.mapObj.removeLayer(layerId); } ); if (this.mapObj.getSource("devices-source")) { this.mapObj.removeSource("devices-source"); } // 创建GeoJSON数据源 const geojson = { type: "FeatureCollection", features: devices.map((device, index) => ({ type: "Feature", id: device.id, // 添加唯一ID用于特征状态管理 geometry: { type: "Point", coordinates: [device.longitude, device.latitude], }, properties: { ...device, index: index + 1, isSelected: this.selectedDeviceId === device.id, }, })), }; // 添加数据源 this.mapObj.addSource("devices-source", { type: "geojson", data: geojson, generateId: true, // 确保每个特征有唯一ID }); // 预加载图标 const loadImage = (name, url) => { return new Promise((resolve) => { if (this.mapObj.hasImage(name)) return resolve(); this.mapObj.loadImage(url, (error, image) => { if (error) throw error; this.mapObj.addImage(name, image); resolve(); }); }); }; Promise.all([ loadImage("jk_online", "/images/jk_online.png"), loadImage("jk_unline", "/images/jk_unline.png"), ]).then(() => { // 添加设备图标 this.mapObj.addLayer({ id: "devices-layer", type: "symbol", source: "devices-source", layout: { "icon-image": [ "case", ["==", ["get", "online"], true], "jk_online", "jk_unline", ], "icon-size": 0.8, "icon-anchor": "bottom", "icon-allow-overlap": true, }, }); // 解决方案1:使用独立图实现序号标签 this.mapObj.addLayer({ id: "device-labels", type: "symbol", source: "devices-source", layout: { "text-field": ["get", "index"], // 始终显示序号 "text-font": ["Noto Sans Bold"], "text-size": 12, "text-offset": [0, -1.8], "text-anchor": "top", "text-allow-overlap": true, }, paint: { "text-color": "#FFFFFF", "text-halo-color": "rgba(0, 0, 0, 0.5)", "text-halo-width": 1, }, }); // 解决方案2:使用圆形图模拟背景色 this.mapObj.addLayer({ id: "label-backgrounds", type: "circle", source: "devices-source", paint: { "circle-radius": 10, "circle-color": [ "case", ["==", ["feature-state", "isSelected"], true], "#FF6666", // 选中状态 "#45CCDA", // 默认状态 ], "circle-stroke-width": 1, "circle-stroke-color": "#fff", "circle-translate": [0, -22], // 调整位置到图标上方 }, }); }); // 解决方案3:修复点击事件报错 this.mapObj.on( "click", ["devices-layer", "device-labels", "label-backgrounds"], (e) => { if (e.features.length > 0) { const deviceId = e.features[0].properties.id; this.toggleDeviceSelection(deviceId); } } ); }, toggleDeviceSelection(deviceId) { // 更新选中状态 const newSelectedId = this.selectedDeviceId === deviceId ? null : deviceId; this.selectedDeviceId = newSelectedId; // 使用特征状态更新(高性能) const source = this.mapObj.getSource("devices-source"); source._data.features.forEach((feature) => { const isSelected = feature.properties.id === newSelectedId; this.mapObj.setFeatureState( { source: "devices-source", id: feature.id }, { isSelected } ); }); // 通知父组件 this.$emit("device-selected", newSelectedId); },没有报错,有数据但是图标和序号全都不显示
最新发布
07-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值