Add existing to tracked
This commit is contained in:
+23
@@ -0,0 +1,23 @@
|
||||
.cesium-selection-wrapper {
|
||||
position: absolute;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition:
|
||||
visibility 0s 0.2s,
|
||||
opacity 0.2s ease-in;
|
||||
}
|
||||
|
||||
.cesium-selection-wrapper-visible {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition: opacity 0.2s ease-out;
|
||||
}
|
||||
|
||||
.cesium-selection-wrapper svg {
|
||||
fill: #2e2;
|
||||
stroke: #000;
|
||||
stroke-width: 1.1px;
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
import {
|
||||
defined,
|
||||
destroyObject,
|
||||
DeveloperError,
|
||||
getElement,
|
||||
} from "@cesium/engine";
|
||||
import knockout from "../ThirdParty/knockout.js";
|
||||
import SelectionIndicatorViewModel from "./SelectionIndicatorViewModel.js";
|
||||
|
||||
/**
|
||||
* A widget for displaying an indicator on a selected object.
|
||||
*
|
||||
* @alias SelectionIndicator
|
||||
* @constructor
|
||||
*
|
||||
* @param {Element|string} container The DOM element or ID that will contain the widget.
|
||||
* @param {Scene} scene The Scene instance to use.
|
||||
*
|
||||
* @exception {DeveloperError} Element with id "container" does not exist in the document.
|
||||
*/
|
||||
function SelectionIndicator(container, scene) {
|
||||
//>>includeStart('debug', pragmas.debug);
|
||||
if (!defined(container)) {
|
||||
throw new DeveloperError("container is required.");
|
||||
}
|
||||
//>>includeEnd('debug');
|
||||
|
||||
container = getElement(container);
|
||||
|
||||
this._container = container;
|
||||
|
||||
const el = document.createElement("div");
|
||||
el.className = "cesium-selection-wrapper";
|
||||
el.setAttribute(
|
||||
"data-bind",
|
||||
'\
|
||||
style: { "top" : _screenPositionY, "left" : _screenPositionX },\
|
||||
css: { "cesium-selection-wrapper-visible" : isVisible }',
|
||||
);
|
||||
container.appendChild(el);
|
||||
this._element = el;
|
||||
|
||||
const svgNS = "http://www.w3.org/2000/svg";
|
||||
const path =
|
||||
"M -34 -34 L -34 -11.25 L -30 -15.25 L -30 -30 L -15.25 -30 L -11.25 -34 L -34 -34 z M 11.25 -34 L 15.25 -30 L 30 -30 L 30 -15.25 L 34 -11.25 L 34 -34 L 11.25 -34 z M -34 11.25 L -34 34 L -11.25 34 L -15.25 30 L -30 30 L -30 15.25 L -34 11.25 z M 34 11.25 L 30 15.25 L 30 30 L 15.25 30 L 11.25 34 L 34 34 L 34 11.25 z";
|
||||
|
||||
const svg = document.createElementNS(svgNS, "svg:svg");
|
||||
svg.setAttribute("width", 160);
|
||||
svg.setAttribute("height", 160);
|
||||
svg.setAttribute("viewBox", "0 0 160 160");
|
||||
|
||||
const group = document.createElementNS(svgNS, "g");
|
||||
group.setAttribute("transform", "translate(80,80)");
|
||||
svg.appendChild(group);
|
||||
|
||||
const pathElement = document.createElementNS(svgNS, "path");
|
||||
pathElement.setAttribute("data-bind", "attr: { transform: _transform }");
|
||||
pathElement.setAttribute("d", path);
|
||||
group.appendChild(pathElement);
|
||||
|
||||
el.appendChild(svg);
|
||||
|
||||
const viewModel = new SelectionIndicatorViewModel(
|
||||
scene,
|
||||
this._element,
|
||||
this._container,
|
||||
);
|
||||
this._viewModel = viewModel;
|
||||
|
||||
knockout.applyBindings(this._viewModel, this._element);
|
||||
}
|
||||
|
||||
Object.defineProperties(SelectionIndicator.prototype, {
|
||||
/**
|
||||
* Gets the parent container.
|
||||
* @memberof SelectionIndicator.prototype
|
||||
*
|
||||
* @type {Element}
|
||||
*/
|
||||
container: {
|
||||
get: function () {
|
||||
return this._container;
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the view model.
|
||||
* @memberof SelectionIndicator.prototype
|
||||
*
|
||||
* @type {SelectionIndicatorViewModel}
|
||||
*/
|
||||
viewModel: {
|
||||
get: function () {
|
||||
return this._viewModel;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @returns {boolean} true if the object has been destroyed, false otherwise.
|
||||
*/
|
||||
SelectionIndicator.prototype.isDestroyed = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys the widget. Should be called if permanently
|
||||
* removing the widget from layout.
|
||||
*/
|
||||
SelectionIndicator.prototype.destroy = function () {
|
||||
const container = this._container;
|
||||
knockout.cleanNode(this._element);
|
||||
container.removeChild(this._element);
|
||||
return destroyObject(this);
|
||||
};
|
||||
export default SelectionIndicator;
|
||||
Generated
Vendored
+214
@@ -0,0 +1,214 @@
|
||||
import {
|
||||
Cartesian2,
|
||||
defined,
|
||||
DeveloperError,
|
||||
EasingFunction,
|
||||
SceneTransforms,
|
||||
} from "@cesium/engine";
|
||||
import knockout from "../ThirdParty/knockout.js";
|
||||
|
||||
const screenSpacePos = new Cartesian2();
|
||||
const 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 = 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.worldToWindowCoordinates
|
||||
*
|
||||
* @example
|
||||
* selectionIndicatorViewModel.computeScreenSpacePosition = function(position, result) {
|
||||
* return Cesium.SceneTransforms.worldToWindowCoordinates(scene, position, result);
|
||||
* };
|
||||
*/
|
||||
this.computeScreenSpacePosition = function (position, result) {
|
||||
return SceneTransforms.worldToWindowCoordinates(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)) {
|
||||
const screenPosition = this.computeScreenSpacePosition(
|
||||
this.position,
|
||||
screenSpacePos,
|
||||
);
|
||||
if (!defined(screenPosition)) {
|
||||
this._screenPositionX = offScreen;
|
||||
this._screenPositionY = offScreen;
|
||||
} else {
|
||||
const container = this._container;
|
||||
const containerWidth = container.parentNode.clientWidth;
|
||||
const containerHeight = container.parentNode.clientHeight;
|
||||
const indicatorSize = this._selectionIndicatorElement.clientWidth;
|
||||
const 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;
|
||||
Reference in New Issue
Block a user