Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
williamwoldum committed Oct 27, 2024
1 parent fb73285 commit 2d80860
Show file tree
Hide file tree
Showing 8 changed files with 271 additions and 14 deletions.
74 changes: 74 additions & 0 deletions @types/leaflet-pixi-overlay/index.d.ts
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
}
Binary file added assets/marker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 75 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"bootstrap-icons": "^1.11.3",
"concurrently": "^9.0.1",
"leaflet": "^1.9.4",
"leaflet-pixi-overlay": "^1.9.4",
"pixi.js": "^8.5.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-leaflet": "^4.2.1",
Expand Down
13 changes: 3 additions & 10 deletions src/components/map.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { MapContainer, TileLayer, useMap } from 'react-leaflet'

import L from 'leaflet'
import PixiOverlay from '../implementations/MapOverlay'

const ComponentResize = () => {
const map = useMap()
Expand All @@ -12,12 +11,7 @@ const ComponentResize = () => {
return null
}

interface IMap {
children: React.ReactNode
setMapRef: React.Dispatch<React.SetStateAction<L.Map | null>>
}

const LMap = ({ setMapRef, children }: IMap) => {
const LMap = () => {
return (
<MapContainer
style={{
Expand All @@ -30,14 +24,13 @@ const LMap = ({ setMapRef, children }: IMap) => {
zoom={8}
minZoom={3}
scrollWheelZoom={true}
ref={setMapRef}
>
<ComponentResize />
<TileLayer
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{children}
<PixiOverlay />
</MapContainer>
)
}
Expand Down
113 changes: 113 additions & 0 deletions src/implementations/MapOverlay.ts
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
}
4 changes: 1 addition & 3 deletions src/pages/vesselMapPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ export default function VesselMapPage() {
</div>

<div className="h-screen w-screen absolute top-0 left-0 z-0">
<LMap setMapRef={setMap}>
{allVessels && allVessels.length > 0 ? <VesselMap vessels={allVessels} /> : <></>}
</LMap>
<LMap />
</div>
{/* <div id="timeline-container" className="absolute end-0 left-0 z-10">
<TimeLine timestamps={[new Date(123456), new Date(54123), new Date(871263)]}></TimeLine>
Expand Down
Loading

0 comments on commit 2d80860

Please sign in to comment.