Reworked overlay itself and doctest.

This commit is contained in:
Severin Opel 2019-12-12 19:02:58 +01:00
parent 32e913c629
commit 7f2fc93fa3
2 changed files with 427 additions and 202 deletions

View File

@ -17,6 +17,8 @@
<script src="../../../dist/iwmlib.js"></script> <script src="../../../dist/iwmlib.js"></script>
<script src="../../../dist/iwmlib.pixi.js"></script> <script src="../../../dist/iwmlib.pixi.js"></script>
<link rel="shortcut icon" type="image/x-icon" href="../../../assets/icons/map.png">
<style> <style>
.inline-showcase { .inline-showcase {
@ -109,17 +111,22 @@
let exampleOverlayJSON = { let exampleOverlayJSON = {
icon: '../../../assets/icons/place.png', icon: '../../../assets/icons/place.png',
iconColor: '0x000000', iconColor: "0x35aaea",
iconAnchor: { x: 0.5, y: 1 }, iconAnchor: { x: 0.5, y: 1 },
size: 5,
scale: 0.2, scale: 0.2,
color: '0xFF00FF', disabledColor: 0x000000,
fillAlpha: 0, disabledIconColor: 0xCCCCCC,
disabledScale: 0.5,
color: '0x3FA7EE',
items: [ items: [
{ {
name: 'Abidjan', name: 'Custom Icon',
fontWeight: "bold", fontWeight: "bold",
icon: '../../../assets/icons//beenhere.png', icon: '../../../assets/icons/beenhere.png',
iconColor: 0x00ff00, iconColor: 0x00ff00,
iconAlpha: 0.5,
size: 0,
labelVerticalAlignment: "underneath", labelVerticalAlignment: "underneath",
label: 'Abidjan', label: 'Abidjan',
location: { location: {
@ -127,17 +134,19 @@
y: -4.006472 y: -4.006472
}, },
information: information:
'... der größte städtische Ballungsraum der Elfenbeinküste.' 'Here a custom icon is used. It overrides the icon setting in the global section.'
}, },
{ {
name: 'Berlin', name: 'Berlin',
label: "enabled",
disabledLabel: "disabled",
location: { location: {
x: 52.52543, x: 52.52543,
y: 13.385291 y: 13.385291
}, },
information: information:
'... ist die Bundeshauptstadt der Bundesrepublik Deutschland.' '... ist die Bundeshauptstadt der Bundesrepublik Deutschland.',
enabled: false
}, },
{ {
name: 'Canberra', name: 'Canberra',
@ -157,7 +166,7 @@
y: 18.416962 y: 18.416962
}, },
information: information:
'... ist eine Hafenstadt an der Südwestküste Südafrikas auf einer Halbinsel, die vom beeindruckenden Tafelberg dominiert wird.' `This item adjusts it's size according to the map.`
}, },
{ {
name: 'Moskau', name: 'Moskau',
@ -191,7 +200,8 @@
}, },
{ {
name: 'Tokio', name: 'Tokio',
type: "factory",
label: "factory",
location: { location: {
x: 35.696278, x: 35.696278,
y: 139.731366 y: 139.731366
@ -221,6 +231,7 @@
function texturesLoaded(textures) { function texturesLoaded(textures) {
/** When all textures are loaded .... */ /** When all textures are loaded .... */
setupMap(textures) setupMap(textures)
@ -232,6 +243,27 @@
let cleaner = null let cleaner = null
const vanishingTime = 1000 const vanishingTime = 1000
// Factories must return a geographics object.
Overlay.createFactory("factory", (item) => {
// This is applied to every item in the overlay that has
// the type factory'
let geographics = new GeoPoint(item.location)
geographics.drawHandler.add((graphics) => {
graphics.beginFill(item.color, item.fillAlpha)
graphics.drawRect(0, 0, 10, 10)
})
let text = new PIXI.Text(item.name, {fontSize: 5})
geographics.graphics.addChild(text)
return geographics
})
/** /**
* *
* The actual PIXI elements are created when the overlay.create() is called. * The actual PIXI elements are created when the overlay.create() is called.

View File

@ -1,5 +1,5 @@
import { GeoLayer } from './geolayer.js' import { GeoLayer } from './geolayer.js'
import { GeoPoint, GeoMultiShape } from './geographics.js' import { GeoPoint, GeoMultiShape, GeoGraphics } from './geographics.js'
import GeoJson from './geojson.js' import GeoJson from './geojson.js'
import Popup from '../popup.js' import Popup from '../popup.js'
@ -11,118 +11,216 @@ import Popup from '../popup.js'
* *
* It's highly configurable and adaptable to a variety of scenarios. * It's highly configurable and adaptable to a variety of scenarios.
* *
* @export
* @class Overlay
*
*
* @param {object} options
* @param {object} options.name Name of the item.
* @param {object} options.borderColor
* @param {object} options.borderThickness
* @param {object} options.enabled Determines if enabled, disabled when false.
* @param {object} options.labelScale
* @param {object} options.location
* @param {object} options.label
* @param {object} options.labelType
* @param {object} options.labelLocation
* @param {object} options.labelAlignment
* @param {object} options.labelVerticalAlignment
* @param {object} options.labelSpacing
* @param {object} options.labelTarget
* @param {object} options.geometry
* @param {object} options.information
* @param {object} options.informationPath
* @param {object} options.informationType
* @param {object} options.icon
* @param {object} options.iconAlpha
* @param {object} options.iconAnchor
* @param {object} options.iconColor
* @param {object} options.iconScale
* @param {object} options.iconOffset
* @param {object} options.items
* @param {object} options.color Color of te point.
* @param {object} options.fillAlpha FillAlpha of the point.
* @param {object} options.size Size of the point.
* @param {object} options.scale Determines the scale of the graphics.
* @param {object} options.rescale Rescales the graphics relative to the map, that they keep their original scale. Only works for the entire overlay atm. Therefore must be set in the global param eters and not inside the children.
* @param {object} options.popoverOffset
* @param {object} options.zoomVisibility
* @param {object} options.labelMultiLineAlign
* @param {object} options.labelBreakWords
* @param {object} options.labelDropShadow
* @param {object} options.labelDropShadowAlpha
* @param {object} options.labelDropShadowAngle
* @param {object} options.labelDropShadowBlur
* @param {object} options.labelDropShadowColor
* @param {object} options.labelDropShadowDistance
* @param {object} options.fontColor
* @param {object} options.fontFamily
* @param {object} options.fontSize
* @param {object} options.fontStyle
* @param {object} options.fontWeight
* @param {object} options.labelStroke
* @param {object} options.labelStrokeThickness
* @param {object} options.wordWrap
* @param {object} options.wordWrapWidth
* @param {object} options.labelFill
* @param {object} options.labelFillGradientType
* @param {object} options.labelFillGradientStops
* @param {object} options.fontVariant
* @param {object} options.labelLeading
* @param {object} options.letterSpacing
* @param {object} options.labelLineHeight
* @param {object} options.labelLineJoin
* @param {object} options.labelMiterLimit
* @param {object} options.labelPadding
* @param {object} options.labelTrim
* @param {object} options.textBaseline
* @param {object} options.labelWhiteSpace
*/ */
export default class Overlay { export default class Overlay {
/** constructor(options = {}) {
*Creates an instance of Overlay.
* @param {*} [{
* name = "unnamed", {string}
* connector = false,
* connectorType = "line",
* location = null,
* label = false,
* labelType = null,
* labelLocation = null,
* labelAlignment = "center",
* labelVerticalAlign = "underneath",
* labelTarget = null,
* shape = "geometry", {string} - Defines the shape to be used: geometry, circle, rectangle
* geometry = null,
* geometryType = "point",
* geometryFallback = "circle",
* informationPopup = "infocard",
*
* }={}]
* @memberof Overlay
*/
constructor(opts = {}) {
let defaultTextStyle = new PIXI.TextStyle() let defaultTextStyle = new PIXI.TextStyle()
Object.assign( let defaultOptions = {
this, type: 'auto',
{ name: 'unnamed',
type: 'auto',
name: 'unnamed',
borderColor: 0x000000, borderColor: 0x000000,
borderThickness: 5, borderThickness: 5,
enabled: true,
labelScale: 1,
location: null,
label: false,
labelType: null,
labelLocation: null,
labelAlignment: 'center',
labelVerticalAlignment: 'underneath',
labelSpacing: 10,
labelTarget: null,
geometry: null,
information: '',
informationPath: null,
informationType: 'popup',
icon: null,
iconAlpha: 1,
iconAnchor: { x: 0.5, y: 0.5 },
iconColor: 0xffffff,
iconScale: 1,
iconOffset: { x: 0, y: 0 },
items: [],
color: 0xff00ff,
fillAlpha: 1,
size: 50,
scale: 1,
rescale: false,
popoverOffset: { x: 0, y: 0 },
zoomVisibility: { min: 0, max: Number.MAX_VALUE },
disabledAlpha: 1, /**
disabledColor: 0xaa1111, * The following Attributes are taken from the TextStyle class
disabledBorderColor: 0x000000, * of PIXI. All can be overwritten in the overlay's JSON file.
enabled: true, */
labelScale: 1, labelMultiLineAlign: defaultTextStyle.align,
location: null, labelBreakWords: defaultTextStyle.breakWords,
label: false, labelDropShadow: defaultTextStyle.dropShadow,
labelType: null, labelDropShadowAlpha: defaultTextStyle.dropShadowAlpha,
labelLocation: null, labelDropShadowAngle: defaultTextStyle.dropShadowAngle,
labelAlignment: 'center', labelDropShadowBlur: defaultTextStyle.dropShadowBlur,
labelVerticalAlign: 'underneath', labelDropShadowColor: defaultTextStyle.dropShadowColor,
labelSpacing: 10, labelDropShadowDistance: defaultTextStyle.dropShadowDistance,
labelTarget: null, fontColor: 0x000000,
geometry: null, fontFamily: defaultTextStyle.fontFamily,
information: '', fontSize: defaultTextStyle.fontSize,
informationPath: null, fontStyle: defaultTextStyle.fontStyle,
informationType: 'popup', fontWeight: defaultTextStyle.fontWeight,
icon: null, labelStroke: defaultTextStyle.stroke,
iconAlpha: 1, labelStrokeThickness: defaultTextStyle.strokeThickness,
iconAnchor: { x: 0.5, y: 0.5 }, wordWrap: defaultTextStyle.wordWrap,
iconColor: 0xffffff, wordWrapWidth: defaultTextStyle.wordWrapWidth,
iconScale: 1, labelFill: defaultTextStyle.fill,
iconOffset: { x: 0, y: 0 }, labelFillGradientType: defaultTextStyle.fillGradientType,
items: [], labelFillGradientStops: defaultTextStyle.fillGradientStops,
color: 0xff00ff, fontVariant: defaultTextStyle.fontVariant,
fillAlpha: 1, labelLeading: defaultTextStyle.leading,
size: 50, letterSpacing: defaultTextStyle.letterSpacing,
scale: 1, labelLineHeight: defaultTextStyle.lineHeight,
rescale: false, labelLineJoin: defaultTextStyle.lineJoin,
popoverOffset: { x: 0, y: 0 }, labelMiterLimit: defaultTextStyle.miterLimit,
zoomVisibility: { min: 0, max: Number.MAX_VALUE }, labelPadding: defaultTextStyle.padding,
labelTrim: defaultTextStyle.trim,
textBaseline: defaultTextStyle.textBaseline,
labelWhiteSpace: defaultTextStyle.whiteSpace
}
/** defaultOptions = this.addDisabled(defaultOptions)
* The following Attributes are taken from the TextStyle class
* of PIXI. All can be overwritten in the overlay's JSON file. console.log('DISABLED VERTICALA.', defaultOptions.disabledLabelVerticalAlignment)
*/
labelMultiLineAlign: defaultTextStyle.align, options = this.addDisabled(options)
labelBreakWords: defaultTextStyle.breakWords,
labelDropShadow: defaultTextStyle.dropShadow, options = Object.assign({}, defaultOptions, options)
labelDropShadowAlpha: defaultTextStyle.dropShadowAlpha,
labelDropShadowAngle: defaultTextStyle.dropShadowAngle, Object.assign(this, options)
labelDropShadowBlur: defaultTextStyle.dropShadowBlur,
labelDropShadowColor: defaultTextStyle.dropShadowColor,
labelDropShadowDistance: defaultTextStyle.dropShadowDistance,
fontColor: 0x000000,
fontFamily: defaultTextStyle.fontFamily,
fontSize: defaultTextStyle.fontSize,
fontStyle: defaultTextStyle.fontStyle,
fontWeight: defaultTextStyle.fontWeight,
labelStroke: defaultTextStyle.stroke,
labelStrokeThickness: defaultTextStyle.strokeThickness,
wordWrap: defaultTextStyle.wordWrap,
wordWrapWidth: defaultTextStyle.wordWrapWidth,
labelFill: defaultTextStyle.fill,
labelFillGradientType: defaultTextStyle.fillGradientType,
labelFillGradientStops: defaultTextStyle.fillGradientStops,
fontVariant: defaultTextStyle.fontVariant,
labelLeading: defaultTextStyle.leading,
letterSpacing: defaultTextStyle.letterSpacing,
labelLineHeight: defaultTextStyle.lineHeight,
labelLineJoin: defaultTextStyle.lineJoin,
labelMiterLimit: defaultTextStyle.miterLimit,
labelPadding: defaultTextStyle.padding,
labelTrim: defaultTextStyle.trim,
textBaseline: defaultTextStyle.textBaseline,
labelWhiteSpace: defaultTextStyle.whiteSpace
},
opts
)
} }
/**
* Some parameters shall not have a disabled option.
* These are defined here.
*
* @readonly
* @memberof Overlay
*/
get excludedDisableParameters() {
return ['items', 'rescale', 'name', 'type', 'enabled']
}
/**
* Copies the normal properties to the disabled version of the property,
* while conserving already set disabled properties.
*
* @param {*} options
* @returns {object} - Returns the modified options object.
* @memberof Overlay
*/
addDisabled(options) {
for (let [key, value] of Object.entries(options)) {
if (this.excludedDisableParameters.indexOf(key) == -1) {
let disabledProperty = this.toDisabledPropertyString(key)
if (options[disabledProperty] == undefined) {
options[disabledProperty] = value
}
}
}
return options
}
/**
* Textures need to be loaded by the app. Texture parameters return all parameters that need to be evaluated for textures.
* @readonly
* @member {array}
* @memberof Overlay
*/
get textureParameters() { get textureParameters() {
return ['icon'] const textureParameters = ['icon']
textureParameters.forEach(textureParameter => {
textureParameters.push(this.toDisabledPropertyString(textureParameter))
})
return textureParameters
} }
/**
* The required textures are saved inside the single items.
* Their texture string gets replaced by a texture object
* containing the path and the texture.
*
* @param {*} parameter
* @param {*} key
* @param {*} path
* @memberof Overlay
*/
setTexture(parameter, key, path) { setTexture(parameter, key, path) {
let obj = (this[parameter] = {}) let obj = (this[parameter] = {})
obj._key = key obj._key = key
@ -150,6 +248,14 @@ export default class Overlay {
}) })
} }
/**
* Recursively calls a function on child items.
*
* @param {*} parameter
* @param {*} func
* @param {*} [obj=null]
* @memberof Overlay
*/
apply(parameter, func, obj = null) { apply(parameter, func, obj = null) {
if (obj == null) return if (obj == null) return
if (Array.isArray(obj)) { if (Array.isArray(obj)) {
@ -187,13 +293,21 @@ export default class Overlay {
adjustItems = null, adjustItems = null,
cleanupItems = null cleanupItems = null
} = {}) { } = {}) {
const name = this.name[0].toUpperCase() + this.name.slice(1).toLowerCase() + ' Overlay' console.log(this)
const name = this.name
? this.name[0].toUpperCase() + this.name.slice(1).toLowerCase() + ' Overlay'
: 'Unnamed Overlay'
let geoLayer = new GeoLayer(new PIXI.Container(), { name }) let geoLayer = new GeoLayer(new PIXI.Container(), { name })
geoLayer.visibility = this.zoomVisibility geoLayer.visibility = this.zoomVisibility
if (this.rescale) geoLayer.rescale = this.rescale if (this.rescale) geoLayer.rescale = this.rescale
this.items.forEach(item => { this.items.forEach(item => {
if (!excludeItems(item)) { if (!excludeItems(item)) {
//Copies all values to a disabled state.
item = this.addDisabled(item)
if (adjustItems) { if (adjustItems) {
adjustItems(item) adjustItems(item)
} }
@ -208,11 +322,60 @@ export default class Overlay {
}) })
return geoLayer return geoLayer
} }
/**
* Used to pick a property or disabled property using an enabled parameter.
*
* @param {*} item
* @param {*} property
* @param {boolean} [enabled=true]
* @returns {any} - Returns the picked item property.
* @memberof Overlay
*/
pickItemProperty(item, property, enabled = true) {
return enabled ? this.getItemProperty(item, property) : this.getDisabledItemProperty(item, property)
}
toDisabledPropertyString(propertyName) {
const prefix = 'disabled'
return prefix + propertyName[0].toUpperCase() + propertyName.slice(1)
}
/**
* Get's the disabled version of the property as long as it is not excluded.
*
* @param {*} item
* @param {*} property
* @returns {any} - Returns the picked item property.
* @memberof Overlay
*/
getDisabledItemProperty(item, property) {
if (this.excludedDisableParameters.indexOf(property) === -1) {
property = this.toDisabledPropertyString(property)
}
const propertyValue = this.getItemProperty(item, property)
return propertyValue
}
/**
* Tries to get the infromation from an overlay item.
* If the item does not contain the property, the overlay definition will be used.
* When the overlay definition is not set, the default value is used.
*
* @param {OverlayItem} item - Item to get the informations from.
* @param {string} property - Name of the property.
* @returns {any} - Returns the picked item property.
* @memberof Overlay
*/
getItemProperty(item, property) { getItemProperty(item, property) {
let propertyValue = null let propertyValue = null
const propertyExistsOnItem = item[property] !== undefined const propertyExistsOnItem = item[property] !== undefined
const propertyExistsOnOverlay = this[property] !== undefined const propertyExistsOnOverlay = this[property] !== undefined
if (property == 'disabledLabelVerticalAlignment') {
console.log(this)
console.log(this['disabledLabelVerticalAlignment'], propertyExistsOnItem, propertyExistsOnOverlay)
}
if (propertyExistsOnItem) propertyValue = item[property] if (propertyExistsOnItem) propertyValue = item[property]
else if (propertyExistsOnOverlay) propertyValue = this[property] else if (propertyExistsOnOverlay) propertyValue = this[property]
else { else {
@ -229,6 +392,15 @@ export default class Overlay {
else return false else return false
} }
/**
* An overlay can have a reference to another file.
* That single overlays are more easy to maintain.
*
* @param {*} item
* @param {*} property
* @returns {any} - Returns the reference as object or the property.
* @memberof Overlay
*/
_resolveReference(item, property) { _resolveReference(item, property) {
if (this._isReference(property)) { if (this._isReference(property)) {
let referencedProperty = property['@property'] let referencedProperty = property['@property']
@ -281,18 +453,30 @@ export default class Overlay {
}) })
} }
/**
* Creates a geographic for each item.
* By default it uses the regular routine but you may
* specify a factory for the defined type.
*
* @param {*} item
* @param {*} [informationCallback=null]
* @returns {GeoGraphics} - Returns the created geographics.
* @memberof Overlay
*/
createItem(item, informationCallback = null) { createItem(item, informationCallback = null) {
let geographics let geographics
let type = this.getItemProperty(item, 'type')
/** /**
* Use a factory to draw the items, if a type is specified. * Use a factory to draw the items, if a type is specified.
*/ */
if (this.type != 'auto') { if (type != 'auto') {
let geographicsFactory = Overlay.requestFactory(this.type) let geographicsFactory = Overlay.requestFactory(type)
if (!geographicsFactory) if (!geographicsFactory)
console.error( console.error(
'Invalid Overlay Mode: ' + 'Invalid Overlay Mode: ' +
this.type + type +
'. Fallback to auto mode. Overlaymodes must be registeres beforehand. Valid modes are: ' + '. Fallback to auto mode. Overlaymodes must be registeres beforehand. Valid modes are: ' +
Overlay.listFactories().join(',') + Overlay.listFactories().join(',') +
'.' '.'
@ -318,84 +502,100 @@ export default class Overlay {
this._drawRoutine(geographics, item, informationCallback) this._drawRoutine(geographics, item, informationCallback)
} }
this._drawLabel(item, geographics) let label = this._createLabel(item, geographics)
if (label != null && geographics != null) {
console.log(geographics)
geographics.graphics.addChild(label)
}
} }
return geographics return geographics
} }
_drawLabel(item, geographics) { /**
let label = this.getItemProperty(item, 'label') *
if (label) { * Draws a label that is shown next to the item on the map.
let textStyle = this._gatherFontStyle(item) *
let text = new PIXI.Text(label, textStyle) * @param {*} item
* @returns {PIXI.Text} - Returns the created label or null.
* @memberof Overlay
*/
_createLabel(item) {
let enabled = this.getItemProperty(item, 'enabled')
let labelText = this.pickItemProperty(item, 'label', enabled)
let label = null
let labelScale = this.getItemProperty(item, 'labelScale') if (labelText) {
text.scale.set(labelScale, labelScale) let textStyle = this._gatherFontStyle(item)
label = new PIXI.Text(labelText, textStyle)
let labelScale = this.pickItemProperty(item, 'labelScale', enabled)
label.scale.set(labelScale, labelScale)
let position = new PIXI.Point() let position = new PIXI.Point()
let align = this.getItemProperty(item, 'labelAlignment') let align = this.pickItemProperty(item, 'labelAlignment', enabled)
if (align == 'left'); if (align == 'left');
else if (align == 'center') position.set(text.position.x - text.width / 2, text.position.y) else if (align == 'center') position.set(label.position.x - label.width / 2, label.position.y)
else if (align == 'right') position.set(text.position.x - text.width, text.position.y) else if (align == 'right') position.set(label.position.x - label.width, label.position.y)
else this._logPropertyNotImplemented('labelAlignment', align) else this._logPropertyNotImplemented('labelAlignment', align)
let verticalAlign = this.getItemProperty(item, 'labelVerticalAlignment') let verticalAlign = this.pickItemProperty(item, 'labelVerticalAlignment', enabled)
if (verticalAlign == 'underneath') { if (verticalAlign == 'underneath') {
let size = this.getItemProperty(item, 'size') let size = this.pickItemProperty(item, 'size', enabled)
let scale = this.getItemProperty(item, 'scale') let scale = this.pickItemProperty(item, 'scale', enabled)
let labelSpacing = this.getItemProperty(item, 'labelSpacing') let labelSpacing = this.pickItemProperty(item, 'labelSpacing', enabled)
position.y += size * scale + labelSpacing position.y += size * scale + labelSpacing
} else if (verticalAlign == 'above') { } else if (verticalAlign == 'above') {
let size = this.getItemProperty(item, 'size') let size = this.pickItemProperty(item, 'size', enabled)
let scale = this.getItemProperty(item, 'scale') let scale = this.pickItemProperty(item, 'scale', enabled)
let labelSpacing = this.getItemProperty(item, 'labelSpacing') let labelSpacing = this.pickItemProperty(item, 'labelSpacing', enabled)
position.y -= size * scale + text.height + labelSpacing position.y -= size * scale + label.height + labelSpacing
} else this._logPropertyNotImplemented('labelVerticalAlignment', verticalAlign) } else this._logPropertyNotImplemented('labelVerticalAlignment', verticalAlign)
text.position.set(position.x, position.y) label.position.set(position.x, position.y)
geographics.graphics.addChild(text)
} }
return label
} }
_gatherFontStyle(item) { _gatherFontStyle(item) {
const enabled = this.getItemProperty(item, 'enabled')
return { return {
align: this.getItemProperty(item, 'labelMultiLineAlign'), align: this.pickItemProperty(item, 'labelMultiLineAlign', enabled),
breakWords: this.getItemProperty(item, 'labelBreakWords'), breakWords: this.pickItemProperty(item, 'labelBreakWords', enabled),
dropShadow: this.getItemProperty(item, 'labelDropShadow'), dropShadow: this.pickItemProperty(item, 'labelDropShadow', enabled),
dropShadowAlpha: this.getItemProperty(item, 'labelDropShadowAlpha'), dropShadowAlpha: this.pickItemProperty(item, 'labelDropShadowAlpha', enabled),
dropShadowAngle: this.getItemProperty(item, 'labelDropShadowAngle'), dropShadowAngle: this.pickItemProperty(item, 'labelDropShadowAngle', enabled),
dropShadowBlur: this.getItemProperty(item, 'labelDropShadowBlur'), dropShadowBlur: this.pickItemProperty(item, 'labelDropShadowBlur', enabled),
dropShadowColor: this.getItemProperty(item, 'labelDropShadowColor'), dropShadowColor: this.pickItemProperty(item, 'labelDropShadowColor', enabled),
dropShadowDistance: this.getItemProperty(item, 'labelDropShadowDistance'), dropShadowDistance: this.pickItemProperty(item, 'labelDropShadowDistance', enabled),
fontFamily: this.getItemProperty(item, 'fontFamily'), fontFamily: this.pickItemProperty(item, 'fontFamily', enabled),
fontSize: this.getItemProperty(item, 'fontSize'), fontSize: this.pickItemProperty(item, 'fontSize', enabled),
fontStyle: this.getItemProperty(item, 'fontStyle'), fontStyle: this.pickItemProperty(item, 'fontStyle', enabled),
fontWeight: this.getItemProperty(item, 'fontWeight'), fontWeight: this.pickItemProperty(item, 'fontWeight', enabled),
stroke: this.getItemProperty(item, 'labelStroke'), stroke: this.pickItemProperty(item, 'labelStroke', enabled),
strokeThickness: this.getItemProperty(item, 'labelStrokeThickness'), strokeThickness: this.pickItemProperty(item, 'labelStrokeThickness', enabled),
wordWrap: this.getItemProperty(item, 'wordWrap'), wordWrap: this.pickItemProperty(item, 'wordWrap', enabled),
wordWrapWidth: this.getItemProperty(item, 'wordWrapWidth'), wordWrapWidth: this.pickItemProperty(item, 'wordWrapWidth', enabled),
fill: this.pickItemProperty(item, 'labelFill', enabled),
fill: this.getItemProperty(item, 'labelFill'), fillGradientType: this.pickItemProperty(item, 'labelFillGradientType', enabled),
fillGradientType: this.getItemProperty(item, 'labelFillGradientType'), fillGradientStops: this.pickItemProperty(item, 'labelFillGradientStops', enabled),
fillGradientStops: this.getItemProperty(item, 'labelFillGradientStops'), fontVariant: this.pickItemProperty(item, 'fontVariant', enabled),
fontVariant: this.getItemProperty(item, 'fontVariant'), leading: this.pickItemProperty(item, 'labelLeading', enabled),
leading: this.getItemProperty(item, 'labelLeading'), letterSpacing: this.pickItemProperty(item, 'letterSpacing', enabled),
letterSpacing: this.getItemProperty(item, 'letterSpacing'), lineHeight: this.pickItemProperty(item, 'labelLineHeight', enabled),
lineHeight: this.getItemProperty(item, 'labelLineHeight'), lineJoin: this.pickItemProperty(item, 'labelLineJoin', enabled),
lineJoin: this.getItemProperty(item, 'labelLineJoin'), miterLimit: this.pickItemProperty(item, 'labelMiterLimit', enabled),
miterLimit: this.getItemProperty(item, 'labelMiterLimit'), padding: this.pickItemProperty(item, 'labelPadding', enabled),
padding: this.getItemProperty(item, 'labelPadding'), trim: this.pickItemProperty(item, 'labelTrim', enabled),
trim: this.getItemProperty(item, 'labelTrim'), textBaseline: this.pickItemProperty(item, 'textBaseline', enabled),
textBaseline: this.getItemProperty(item, 'textBaseline'), whiteSpace: this.pickItemProperty(item, 'labelWhiteSpace', enabled)
whiteSpace: this.getItemProperty(item, 'labelWhiteSpace')
} }
} }
@ -440,25 +640,27 @@ export default class Overlay {
} }
_createIcon(geographics, item) { _createIcon(geographics, item) {
let icon = this.getItemProperty(item, 'icon') let enabled = this.getItemProperty(item, 'enabled')
let icon = this.pickItemProperty(item, 'icon', enabled)
if (icon) { if (icon) {
if (icon.texture) { if (icon.texture) {
let sprite = new PIXI.Sprite(icon.texture) let sprite = new PIXI.Sprite(icon.texture)
const iconAnchor = this.getItemProperty(item, 'iconAnchor') const iconAnchor = this.pickItemProperty(item, 'iconAnchor', enabled)
sprite.anchor.set(iconAnchor.x, iconAnchor.y) sprite.anchor.set(iconAnchor.x, iconAnchor.y)
const iconScale = this.getItemProperty(item, 'iconScale') const iconScale = this.pickItemProperty(item, 'iconScale', enabled)
if (iconScale) sprite.scale.set(iconScale, iconScale) if (iconScale) sprite.scale.set(iconScale, iconScale)
const iconOffset = this.getItemProperty(item, 'iconOffset') const iconOffset = this.pickItemProperty(item, 'iconOffset', enabled)
if (iconOffset && iconOffset.x != null && iconOffset.y != null) if (iconOffset && iconOffset.x != null && iconOffset.y != null)
sprite.position.set(iconOffset.x, iconOffset.y) sprite.position.set(iconOffset.x, iconOffset.y)
const iconColor = this.getItemProperty(item, 'iconColor') const iconColor = this.pickItemProperty(item, 'iconColor', enabled)
if (iconColor) sprite.tint = iconColor if (iconColor) sprite.tint = iconColor
const iconAlpha = this.getItemProperty(item, 'iconAlpha') const iconAlpha = this.pickItemProperty(item, 'iconAlpha', enabled)
if (iconAlpha) sprite.alpha = iconAlpha if (iconAlpha) sprite.alpha = iconAlpha
geographics.graphics.addChild(sprite) geographics.graphics.addChild(sprite)
@ -468,28 +670,6 @@ export default class Overlay {
_createInformation(geographics, item, callback = null) { _createInformation(geographics, item, callback = null) {
if (item.information) { if (item.information) {
/**
* SO: The overlay class is quite convenient.
* But managing the information creation solely inside this
* class restricts us massively.
*
* Maybe a restructuring would be good, that we can handle
* the creation of information with a callback and can adapt
* to any occuring situation.
*
* e.g.
*
* overlay.informationHandler((geo, type, item)=>{
* switch(type){
* case "popup":
* createPopup(item.information)
* break;
*
* ....
* }
* })
*/
geographics.graphics.interactive = true geographics.graphics.interactive = true
const informationType = this.getItemProperty(item, 'informationType') const informationType = this.getItemProperty(item, 'informationType')
@ -538,17 +718,21 @@ export default class Overlay {
_fill(geographics, item) { _fill(geographics, item) {
const enabled = this.getItemProperty(item, 'enabled') const enabled = this.getItemProperty(item, 'enabled')
const color = enabled ? this.getItemProperty(item, 'color') : this.getItemProperty(item, 'disabledColor') const color = this.pickItemProperty(item, 'color', enabled)
let alpha = enabled ? this.getItemProperty(item, 'fillAlpha') : this.getItemProperty(item, 'disabledAlpha') const alpha = this.pickItemProperty(item, 'fillAlpha', enabled)
geographics.graphics.beginFill(color, alpha) geographics.graphics.beginFill(color, alpha)
} }
_drawPoint(item, informationCallback = null) { _drawPoint(item, informationCallback = null) {
const overlay = this const overlay = this
const enabled = this.getItemProperty(item, 'enabled')
let that = this
let geographic = new GeoPoint(item.location, { let geographic = new GeoPoint(item.location, {
onDraw: function() { onDraw: function() {
overlay._fill.call(overlay, this, item) overlay._fill.call(overlay, this, item)
const size = overlay.getItemProperty(item, 'size') ? overlay.getItemProperty(item, 'size') : 0 const size = that.pickItemProperty(item, 'size', enabled)
this.graphics.drawCircle(0, 0, size) this.graphics.drawCircle(0, 0, size)
overlay._drawRoutine.call(overlay, this, item, informationCallback) overlay._drawRoutine.call(overlay, this, item, informationCallback)
} }
@ -563,10 +747,19 @@ export default class Overlay {
Overlay.Modes = { auto: null } Overlay.Modes = { auto: null }
Overlay.createFactory = function(name, geographicsFactory) { /**
if (Overlay.Modes.hasOwnProperty(name)) * Creates a factory for a specific type.
console.warn(`The mode ${name} was already implemented and was overwritten!`) *
Overlay.Modes[name] = geographicsFactory * @param {string} type - Name of the factory. When overlay items match the type, the factory is applied.
* @param {function} geographicsFactory - A function that is called with every item. Can be used to draw the geographics individually.
*
* @static
* @memberof {Overlay}
*/
Overlay.createFactory = function(type, geographicsFactory) {
if (Overlay.Modes.hasOwnProperty(type))
console.warn(`The mode ${type} was already implemented and was overwritten!`)
Overlay.Modes[type] = geographicsFactory
} }
Overlay.requestFactory = function(name) { Overlay.requestFactory = function(name) {