You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
6.1 KiB
JavaScript
214 lines
6.1 KiB
JavaScript
import Cartesian2 from "../../Core/Cartesian2.js";
|
|
import defaultValue from "../../Core/defaultValue.js";
|
|
import defined from "../../Core/defined.js";
|
|
import DeveloperError from "../../Core/DeveloperError.js";
|
|
import EasingFunction from "../../Core/EasingFunction.js";
|
|
import SceneTransforms from "../../Scene/SceneTransforms.js";
|
|
import knockout from "../../ThirdParty/knockout.js";
|
|
|
|
var screenSpacePos = new Cartesian2();
|
|
var offScreen = "-1000px";
|
|
|
|
/**
|
|
* The view model for {@link SelectionIndicator}.
|
|
* @alias SelectionIndicatorViewModel
|
|
* @constructor
|
|
*
|
|
* @param {Scene} scene The scene instance to use for screen-space coordinate conversion.
|
|
* @param {Element} selectionIndicatorElement The element containing all elements that make up the selection indicator.
|
|
* @param {Element} container The DOM element that contains the widget.
|
|
*/
|
|
function SelectionIndicatorViewModel(
|
|
scene,
|
|
selectionIndicatorElement,
|
|
container
|
|
) {
|
|
//>>includeStart('debug', pragmas.debug);
|
|
if (!defined(scene)) {
|
|
throw new DeveloperError("scene is required.");
|
|
}
|
|
|
|
if (!defined(selectionIndicatorElement)) {
|
|
throw new DeveloperError("selectionIndicatorElement is required.");
|
|
}
|
|
|
|
if (!defined(container)) {
|
|
throw new DeveloperError("container is required.");
|
|
}
|
|
//>>includeEnd('debug')
|
|
|
|
this._scene = scene;
|
|
this._screenPositionX = offScreen;
|
|
this._screenPositionY = offScreen;
|
|
this._tweens = scene.tweens;
|
|
this._container = defaultValue(container, document.body);
|
|
this._selectionIndicatorElement = selectionIndicatorElement;
|
|
this._scale = 1;
|
|
|
|
/**
|
|
* Gets or sets the world position of the object for which to display the selection indicator.
|
|
* @type {Cartesian3}
|
|
*/
|
|
this.position = undefined;
|
|
|
|
/**
|
|
* Gets or sets the visibility of the selection indicator.
|
|
* @type {Boolean}
|
|
*/
|
|
this.showSelection = false;
|
|
|
|
knockout.track(this, [
|
|
"position",
|
|
"_screenPositionX",
|
|
"_screenPositionY",
|
|
"_scale",
|
|
"showSelection",
|
|
]);
|
|
|
|
/**
|
|
* Gets the visibility of the position indicator. This can be false even if an
|
|
* object is selected, when the selected object has no position.
|
|
* @type {Boolean}
|
|
*/
|
|
this.isVisible = undefined;
|
|
knockout.defineProperty(this, "isVisible", {
|
|
get: function () {
|
|
return this.showSelection && defined(this.position);
|
|
},
|
|
});
|
|
|
|
knockout.defineProperty(this, "_transform", {
|
|
get: function () {
|
|
return "scale(" + this._scale + ")";
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Gets or sets the function for converting the world position of the object to the screen space position.
|
|
*
|
|
* @member
|
|
* @type {SelectionIndicatorViewModel.ComputeScreenSpacePosition}
|
|
* @default SceneTransforms.wgs84ToWindowCoordinates
|
|
*
|
|
* @example
|
|
* selectionIndicatorViewModel.computeScreenSpacePosition = function(position, result) {
|
|
* return Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position, result);
|
|
* };
|
|
*/
|
|
this.computeScreenSpacePosition = function (position, result) {
|
|
return SceneTransforms.wgs84ToWindowCoordinates(scene, position, result);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Updates the view of the selection indicator to match the position and content properties of the view model.
|
|
* This function should be called as part of the render loop.
|
|
*/
|
|
SelectionIndicatorViewModel.prototype.update = function () {
|
|
if (this.showSelection && defined(this.position)) {
|
|
var screenPosition = this.computeScreenSpacePosition(
|
|
this.position,
|
|
screenSpacePos
|
|
);
|
|
if (!defined(screenPosition)) {
|
|
this._screenPositionX = offScreen;
|
|
this._screenPositionY = offScreen;
|
|
} else {
|
|
var container = this._container;
|
|
var containerWidth = container.parentNode.clientWidth;
|
|
var containerHeight = container.parentNode.clientHeight;
|
|
var indicatorSize = this._selectionIndicatorElement.clientWidth;
|
|
var halfSize = indicatorSize * 0.5;
|
|
|
|
screenPosition.x =
|
|
Math.min(
|
|
Math.max(screenPosition.x, -indicatorSize),
|
|
containerWidth + indicatorSize
|
|
) - halfSize;
|
|
screenPosition.y =
|
|
Math.min(
|
|
Math.max(screenPosition.y, -indicatorSize),
|
|
containerHeight + indicatorSize
|
|
) - halfSize;
|
|
|
|
this._screenPositionX = Math.floor(screenPosition.x + 0.25) + "px";
|
|
this._screenPositionY = Math.floor(screenPosition.y + 0.25) + "px";
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Animate the indicator to draw attention to the selection.
|
|
*/
|
|
SelectionIndicatorViewModel.prototype.animateAppear = function () {
|
|
this._tweens.addProperty({
|
|
object: this,
|
|
property: "_scale",
|
|
startValue: 2,
|
|
stopValue: 1,
|
|
duration: 0.8,
|
|
easingFunction: EasingFunction.EXPONENTIAL_OUT,
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Animate the indicator to release the selection.
|
|
*/
|
|
SelectionIndicatorViewModel.prototype.animateDepart = function () {
|
|
this._tweens.addProperty({
|
|
object: this,
|
|
property: "_scale",
|
|
startValue: this._scale,
|
|
stopValue: 1.5,
|
|
duration: 0.8,
|
|
easingFunction: EasingFunction.EXPONENTIAL_OUT,
|
|
});
|
|
};
|
|
|
|
Object.defineProperties(SelectionIndicatorViewModel.prototype, {
|
|
/**
|
|
* Gets the HTML element containing the selection indicator.
|
|
* @memberof SelectionIndicatorViewModel.prototype
|
|
*
|
|
* @type {Element}
|
|
*/
|
|
container: {
|
|
get: function () {
|
|
return this._container;
|
|
},
|
|
},
|
|
|
|
/**
|
|
* Gets the HTML element that holds the selection indicator.
|
|
* @memberof SelectionIndicatorViewModel.prototype
|
|
*
|
|
* @type {Element}
|
|
*/
|
|
selectionIndicatorElement: {
|
|
get: function () {
|
|
return this._selectionIndicatorElement;
|
|
},
|
|
},
|
|
|
|
/**
|
|
* Gets the scene being used.
|
|
* @memberof SelectionIndicatorViewModel.prototype
|
|
*
|
|
* @type {Scene}
|
|
*/
|
|
scene: {
|
|
get: function () {
|
|
return this._scene;
|
|
},
|
|
},
|
|
});
|
|
|
|
/**
|
|
* A function that converts the world position of an object to a screen space position.
|
|
* @callback SelectionIndicatorViewModel.ComputeScreenSpacePosition
|
|
* @param {Cartesian3} position The position in WGS84 (world) coordinates.
|
|
* @param {Cartesian2} result An object to return the input position transformed to window coordinates.
|
|
* @returns {Cartesian2} The modified result parameter.
|
|
*/
|
|
export default SelectionIndicatorViewModel;
|