-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fb73285
commit 2d80860
Showing
8 changed files
with
271 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import 'leaflet' | ||
import * as PIXI from 'pixi.js' | ||
|
||
declare module 'leaflet' { | ||
interface PixiOverlayOptions extends L.LayerOptions { | ||
padding: number | ||
forceCanvas: boolean | ||
doubleBuffering: boolean | ||
resolution: number | ||
projectionZoom: (map: L.Map) => number | ||
destroyInteractionManager: boolean | ||
autoPreventDefault: boolean | ||
preserveDrawingBuffer: boolean | ||
clearBeforeRender: boolean | ||
shouldRedrawOnMove: () => boolean | ||
} | ||
|
||
type LatLngToLayerPointFn = (latLng: L.LatLng, zoom?: number) => L.Point | ||
type LayerPointToLatLngFn = (point: L.Point, zoom?: number) => L.LatLng | ||
|
||
interface PixiOverlayUtils { | ||
latLngToLayerPoint: LatLngToLayerPointFn | ||
layerPointToLatLng: LayerPointToLatLngFn | ||
getScale: (zoom?: number) => number | undefined | ||
getRenderer: () => PIXI.IRenderer | ||
getContainer: () => PIXI.Container | ||
getMap: () => L.Map | ||
} | ||
|
||
type DrawCallbackFn = (utils: PixiOverlayUtils, container: PIXI.Container) => void | ||
|
||
interface LeafletPixiOverlayDefnition extends Omit<L.Layer, 'onAdd' | 'onRemove'> { | ||
utils: PixiOverlayUtils | ||
options: PixiOverlayOptions | ||
_container?: HTMLElement | ||
_pixiContainer: PIXI.Container | ||
_rendererOptions: Partial<PIXI.IRendererOptionsAuto> | ||
_doubleBuffering: boolean | ||
_map?: L.Map | ||
_renderer: PIXI.IRenderer | ||
_auxRenderer: PIXI.IRenderer | ||
_initialZoom?: number | ||
_wgsOrigin?: L.LatLng | ||
_wgsInitialShift?: L.Point | ||
_mapInitialZoom?: number | ||
_drawCallback: (utils: PixiOverlayUtils, event: L.LeafletEvent) => void | ||
_setMap: (map: L.Map) => void | ||
_setContainerStyle: () => void | ||
_addContainer: () => void | ||
_setEvents: () => void | ||
_onZoom: () => void | ||
_onAnimZoom: (event: L.ZoomAnimEvent) => void | ||
_onMove: (event: L.LeafletEvent) => void | ||
_updateTransform: (center: Pick<L.ZoomAnimEvent, 'center'>, zoom: Pick<L.ZoomAnimEvent, 'zoom'>) => void | ||
_redraw: (offset: number, container: PIXI.Container) => void | ||
_update: (event: Partial<L.LeafletEvent>) => void | ||
_disableLeafletRounding: () => void | ||
_enableLeafletRounding: () => void | ||
initialize: ( | ||
drawCallback: DrawCallbackFn, | ||
pixiContainer: PIXI.Container, | ||
options?: Partial<PixiOverlayOptions> | ||
) => void | ||
redraw: (data: PIXI.Container) => this | ||
onAdd: (map: L.Map) => void | ||
onRemove: () => void | ||
} | ||
|
||
function pixiOverlay( | ||
drawCallback: DrawCallbackFn, | ||
pixiContainer: PIXI.Container, | ||
options?: Partial<PixiOverlayOptions> | ||
): LeafletPixiOverlayDefnition | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import * as PIXI from 'pixi.js' | ||
import L from 'leaflet' | ||
import { useMap } from 'react-leaflet' | ||
import 'leaflet-pixi-overlay' | ||
|
||
const markerTexture = await PIXI.Assets.load('assets/marker.png') | ||
const markerLatLng = [56.15674, 10.21076] | ||
|
||
interface ICusMarker { | ||
sprite: PIXI.Sprite | ||
popup: L.Popup | ||
currentScale?: number | ||
targetScale?: number | ||
} | ||
|
||
export default function PixiOverlay() { | ||
const mapRef = useMap() | ||
|
||
let frame: number | null = null | ||
let firstDraw = true | ||
let prevZoom: number | null = null | ||
|
||
const sprite = new PIXI.Sprite(markerTexture) | ||
sprite.interactive = true | ||
sprite.cursor = 'pointer' | ||
|
||
const popup = L.popup({ className: 'pixi-popup' }) | ||
.setLatLng(markerLatLng as L.LatLngExpression) | ||
.setContent('<b>Hello world!</b><br>I am a popup.') | ||
.openOn(mapRef) | ||
|
||
const cusMarker: ICusMarker = { sprite, popup } | ||
|
||
const pixiContainer = new PIXI.Container() | ||
pixiContainer.addChild(cusMarker.sprite) | ||
|
||
L.pixiOverlay( | ||
(utils) => { | ||
if (frame) { | ||
cancelAnimationFrame(frame) | ||
frame = null | ||
} | ||
const zoom = utils.getMap().getZoom() | ||
const container = utils.getContainer() | ||
const renderer = utils.getRenderer() | ||
const project = utils.latLngToLayerPoint | ||
const scale = utils.getScale() | ||
|
||
if (firstDraw) { | ||
const boundary = new PIXI.EventBoundary(container) | ||
utils.getMap().on('click', (e) => { | ||
const interaction = utils.getRenderer().events | ||
const pointerEvent = e.originalEvent | ||
const pixiPoint = new PIXI.Point() | ||
// get global click position in pixiPoint: | ||
interaction.mapPositionToPoint(pixiPoint, pointerEvent.clientX, pointerEvent.clientY) | ||
// get what is below the click if any: | ||
const target = boundary.hitTest(pixiPoint.x, pixiPoint.y) | ||
if (target && target.uid === cusMarker.sprite.uid) { | ||
cusMarker.popup.openOn(mapRef) | ||
} | ||
}) | ||
|
||
const markerCoords = project(new L.LatLng(markerLatLng[0], markerLatLng[1])) | ||
cusMarker.sprite.x = markerCoords.x | ||
cusMarker.sprite.y = markerCoords.y | ||
cusMarker.sprite.anchor.set(0.5, 1) | ||
cusMarker.sprite.scale.set(1 / scale!) | ||
cusMarker.currentScale = 1 / scale! | ||
} | ||
if (firstDraw || prevZoom !== zoom) { | ||
cusMarker.currentScale = cusMarker.sprite.scale.x | ||
cusMarker.targetScale = 1 / scale! | ||
|
||
// We can draw anything PIXI here. For example, a polygon: | ||
} | ||
|
||
const duration = 100 | ||
let start: number | null = null | ||
|
||
const animate = (timestamp: number) => { | ||
if (start === null) start = timestamp | ||
const progress = timestamp - start | ||
let lambda = progress / duration | ||
if (lambda > 1) lambda = 1 | ||
lambda = lambda * (0.4 + lambda * (2.2 + lambda * -1.6)) | ||
cusMarker.sprite.scale.set( | ||
cusMarker.currentScale! + lambda * (cusMarker.targetScale! - cusMarker.currentScale!) | ||
) | ||
renderer.render(container) | ||
if (progress < duration) { | ||
frame = requestAnimationFrame(animate) | ||
} | ||
} | ||
|
||
if (!firstDraw && prevZoom !== zoom) { | ||
start = null | ||
frame = requestAnimationFrame(animate) | ||
} | ||
|
||
firstDraw = false | ||
prevZoom = zoom | ||
renderer.render(container) | ||
}, | ||
pixiContainer, | ||
{ | ||
doubleBuffering: true, | ||
autoPreventDefault: false, | ||
} | ||
).addTo(mapRef) | ||
|
||
return null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.