97 lines
2.9 KiB
JavaScript
97 lines
2.9 KiB
JavaScript
/*
|
|
Tinker Bell effect on maps.
|
|
|
|
Copyright (c) 2015 Jean-Marc VIGLINO,
|
|
released under the CeCILL-B license (French BSD license)
|
|
(http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
|
|
@link https://github.com/Viglino
|
|
*/
|
|
|
|
import {unByKey as ol_Observable_unByKey} from 'ol/Observable.js'
|
|
import ol_interaction_Pointer from 'ol/interaction/Pointer.js'
|
|
import {asString as ol_color_asString} from 'ol/color.js'
|
|
import ol_ext_getMapCanvas from '../util/getMapcanvas.js'
|
|
|
|
/**
|
|
* @constructor
|
|
* @extends {ol_interaction_Pointer}
|
|
* @param {ol_interaction_TinkerBell.options} options flashlight param
|
|
* @param {ol_color} [options.color] color of the sparkles
|
|
*/
|
|
var ol_interaction_TinkerBell = class olinteractionTinkerBell extends ol_interaction_Pointer {
|
|
constructor(options) {
|
|
options = options || {}
|
|
|
|
super({
|
|
handleDownEvent: function(e) { this.onMove(e) },
|
|
handleMoveEvent: function(e) { this.onMove(e) }
|
|
})
|
|
|
|
this.set('color', options.color ? ol_color_asString(options.color) : "#fff")
|
|
this.sparkle = [0, 0]
|
|
this.sparkles = []
|
|
this.lastSparkle = this.time = new Date()
|
|
|
|
var self = this
|
|
this.out_ = function () { self.isout_ = true }
|
|
this.isout_ = true
|
|
}
|
|
/** Set the map > start postcompose
|
|
*/
|
|
setMap(map) {
|
|
if (this._listener)
|
|
ol_Observable_unByKey(this._listener)
|
|
this._listener = null
|
|
if (this.getMap()) {
|
|
map.getViewport().removeEventListener('mouseout', this.out_, false)
|
|
this.getMap().render()
|
|
}
|
|
|
|
super.setMap(map)
|
|
|
|
if (map) {
|
|
this._listener = map.on('postcompose', this.postcompose_.bind(this))
|
|
map.getViewport().addEventListener('mouseout', this.out_, false)
|
|
}
|
|
}
|
|
onMove(e) {
|
|
this.sparkle = e.pixel
|
|
this.isout_ = false
|
|
this.getMap().render()
|
|
}
|
|
/** Postcompose function
|
|
*/
|
|
postcompose_(e) {
|
|
var delta = 15
|
|
var ctx = e.context || ol_ext_getMapCanvas(this.getMap()).getContext('2d')
|
|
var dt = e.frameState.time - this.time
|
|
this.time = e.frameState.time
|
|
if (e.frameState.time - this.lastSparkle > 30 && !this.isout_) {
|
|
this.lastSparkle = e.frameState.time
|
|
this.sparkles.push({ p: [this.sparkle[0] + Math.random() * delta - delta / 2, this.sparkle[1] + Math.random() * delta], o: 1 })
|
|
}
|
|
ctx.save()
|
|
ctx.scale(e.frameState.pixelRatio, e.frameState.pixelRatio)
|
|
ctx.fillStyle = this.get("color")
|
|
for (var i = this.sparkles.length - 1, p; p = this.sparkles[i]; i--) {
|
|
if (p.o < 0.2) {
|
|
this.sparkles.splice(0, i + 1)
|
|
break
|
|
}
|
|
ctx.globalAlpha = p.o
|
|
ctx.beginPath()
|
|
ctx.arc(p.p[0], p.p[1], 2.2, 0, 2 * Math.PI, false)
|
|
ctx.fill()
|
|
p.o *= 0.98
|
|
p.p[0] += (Math.random() - 0.5)
|
|
p.p[1] += dt * (1 + Math.random()) / 30
|
|
}
|
|
ctx.restore()
|
|
|
|
// continue postcompose animation
|
|
if (this.sparkles.length)
|
|
this.getMap().render()
|
|
}
|
|
}
|
|
|
|
export default ol_interaction_TinkerBell |