gpt4 book ai didi

javascript - setAbstractView() 防止 mousedown 事件传播到 KmlFeatures

转载 作者:行者123 更新时间:2023-12-04 18:29:37 25 4
gpt4 key购买 nike

使用 Google 地球插件,我希望能够让用户在相机移动时选择地面上的地标,但我不确定这如何实现。似乎当您调用 setAbstractView() 时,即使 flyToSpeed 设置为 SPEED_TELEPORT,Google 地球插件也会忽略除 GEGlobe 之外的任何鼠标按下事件。

这是代码,略有改动(来自 http://code.google.com/apis/ajax/playground/#draggable_placemark )以说明我的问题:

var ge;

var placemark;
var dragInfo = null;
var la;
var lat = 37;
var lon = -122;

google.load("earth", "1");

function init() {
google.earth.createInstance('map3d', initCallback, failureCallback);
}

function tick() {
la.set(lat, lon,
0, // altitude
ge.ALTITUDE_RELATIVE_TO_GROUND,
0, // heading
0, // straight-down tilt
5000 // range (inverse of zoom)
);
ge.getView().setAbstractView(la);
lon = lon + 0.00000001;
}

function initCallback(instance) {
ge = instance;
ge.getWindow().setVisibility(true);

// add a navigation control
ge.getNavigationControl().setVisibility(ge.VISIBILITY_AUTO);

// add some layers
ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);

// create the placemark
placemark = ge.createPlacemark('');

var point = ge.createPoint('');
point.setLatitude(lat);
point.setLongitude(lon);
placemark.setGeometry(point);

// add the placemark to the earth DOM
ge.getFeatures().appendChild(placemark);

// look at the placemark we created
la = ge.createLookAt('');
placemark.setName('Drag Me!');
ge.getOptions().setFlyToSpeed(ge.SPEED_TELEPORT);
tick();

// Comment this next line out and the drag works as expected.
google.earth.addEventListener(ge, "frameend", tick);

// listen for mousedown on the window (look specifically for point placemarks)
google.earth.addEventListener(ge.getWindow(), 'mousedown', function(event) {
console.log("target type = " + event.getTarget().getType());
if (event.getTarget().getType() == 'KmlPlacemark' &&
event.getTarget().getGeometry().getType() == 'KmlPoint') {
//event.preventDefault();
var placemark = event.getTarget();

dragInfo = {
placemark: event.getTarget(),
dragged: false
};
}
});

// listen for mousemove on the globe
google.earth.addEventListener(ge.getGlobe(), 'mousemove', function(event) {
if (dragInfo) {
event.preventDefault();
var point = dragInfo.placemark.getGeometry();
point.setLatitude(event.getLatitude());
point.setLongitude(event.getLongitude());
dragInfo.dragged = true;
}
});

// listen for mouseup on the window
google.earth.addEventListener(ge.getWindow(), 'mouseup', function(event) {
if (dragInfo) {
if (dragInfo.dragged) {
// if the placemark was dragged, prevent balloons from popping up
event.preventDefault();
}

dragInfo = null;
}
});

document.getElementById('installed-plugin-version').innerHTML =
ge.getPluginVersion().toString();
}

function failureCallback(errorCode) {
}

如果您注释掉第 56 行,其中 tick() 在每个帧结束时被调用,一切都像未更改的代码一样工作:您可以成功拖动位置标记。但是当第 56 行进入时,你不能。所以问题实际上是 setAbstractView 阻止 mousedown 事件传播到地球或任何被点击的地标或特征。

有什么想法吗?有解决方法吗?

最佳答案

问题不是setAbstractView方法引起的,而是通过framend重复调用tick方法引起的。

解释一下,您已经将 tick 方法设置为 frameend 事件的事件处理程序。然后 tick 方法立即更新 View ,触发 frameend 事件,无穷无尽...

此模式会导致浏览器消息循环出现问题,实际上它会阻止其他拖动事件。可以把它想象成一个导致死锁的非常紧密的循环。要使用它,您可以使用值为 0 的 setTimeout 来执行代码。这样,在处理完所有其他挂起的拖动消息之前,不会处理动画。

关键部分是对 tick() 方法的修改。

function tick() {
// prevent deadlock
setTimeout(function () {
la.set(lat, lon, 0, ge.ALTITUDE_RELATIVE_TO_GROUND, 0, 0, 5000);
ge.getView().setAbstractView(la);
lon += 0.00001;
}, 0);
};

在这里,我为您制作了一个完整的示例http://jsfiddle.net/fraser/JFLaT/

我对其进行了测试,它可以在 Windows 8 上的 Chrome、IE、Firefox 和 OSX 上的 Chrome、Safari、Firefox 中运行。

关于javascript - setAbstractView() 防止 mousedown 事件传播到 KmlFeatures,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19439287/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com