| | |
| | | |
| | | |
| | | import * as PIXI from 'pixi.js'; |
| | | |
| | | let app = null; |
| | | let mapContainer = null; |
| | | let effectTick, effectHalfCircle, effectRectangle; |
| | | |
| | | export function syncApp(param) { |
| | | app = param; |
| | |
| | | mapContainer = param; |
| | | } |
| | | |
| | | export const MapEvent = Object.freeze({ |
| | | SELECTION_BOX: Symbol.for(0), |
| | | }) |
| | | |
| | | export const getRealPosition = (x, y, mapContainer) => { |
| | | const rect = app.view.getBoundingClientRect(); |
| | | return { |
| | | mapX: (x - rect.left) / mapContainer.scale.x - mapContainer.x / mapContainer.scale.x, |
| | | mapY: (y - rect.top) / mapContainer.scale.y - mapContainer.y / mapContainer.scale.y |
| | | } |
| | | } |
| | | |
| | | export const initSprite = (sprite, type) => { |
| | | sprite.anchor.set(0.5); |
| | | sprite.cursor = 'pointer'; |
| | | sprite.eventMode = 'static'; |
| | | sprite.data = { |
| | | type: type |
| | | }; |
| | | } |
| | | |
| | | // sprite be movable from sprite click event |
| | | export const beMovable = (sprite, setDidClickSprite) => { |
| | | sprite.off('pointerup'); |
| | | sprite.off('pointermove'); |
| | | sprite.off('pointerdown'); |
| | | sprite.off('click'); |
| | | |
| | | sprite.on("pointerdown", onDragStart); |
| | | |
| | | let dragTarget; |
| | | function onDragStart(event) { |
| | | setDidClickSprite(true); |
| | | dragTarget = event.currentTarget; |
| | | mapContainer.parent.off('pointermove'); |
| | | mapContainer.parent.on('pointermove', onDragMove, dragTarget); |
| | | |
| | | mapContainer.parent.off('pointerup'); |
| | | mapContainer.parent.on('pointerup', onDragEnd.bind(mapContainer)); |
| | | } |
| | | |
| | | function onDragMove(event) { |
| | | if (this) { |
| | | this.parent.toLocal(event.global, null, this.position); |
| | | } |
| | | } |
| | | |
| | | function onDragEnd() { |
| | | if (dragTarget) { |
| | | setDidClickSprite(false); |
| | | this.parent.off('pointermove'); |
| | | this.parent.off('pointerup'); |
| | | dragTarget.alpha = 1; |
| | | dragTarget = null; |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | // sprite be beSettings from sprite click event |
| | | export const beSettings = (sprite, setSpriteBySettings, setDidClickSprite) => { |
| | | sprite.off('pointerup'); |
| | | sprite.off('pointermove'); |
| | | sprite.off('pointerdown'); |
| | | sprite.off('click'); |
| | | |
| | | sprite.on("click", onClick); |
| | | |
| | | function onClick(event) { |
| | | setSpriteBySettings(sprite); |
| | | // setDidClickSprite(true); |
| | | } |
| | | } |
| | | |
| | | // sprites be movable from select box |
| | | // the scale was dynamic |
| | | export const spriteListBeMovable = (selectedSprites, scale, resetFn) => { |
| | | if (selectedSprites && selectedSprites.length > 0) { |
| | | let batchMove = false; |
| | | let batchMoveStartPos = null; |
| | | |
| | | const batchMoving = (event) => { |
| | | if (batchMove && batchMoveStartPos) { |
| | | // offset move val |
| | | var mouseMovement = { |
| | | x: (event.global.x - batchMoveStartPos.x) / scale, |
| | | y: (event.global.y - batchMoveStartPos.y) / scale |
| | | }; |
| | | for (let sprite of selectedSprites) { |
| | | sprite.position.x = sprite.data.batchMoveStartPos.x + mouseMovement.x; |
| | | sprite.position.y = sprite.data.batchMoveStartPos.y + mouseMovement.y; |
| | | } |
| | | } |
| | | } |
| | | |
| | | const batchMoveEnd = (event) => { |
| | | batchMove = false; |
| | | batchMoveStartPos = null; |
| | | selectedSprites.forEach(child => { |
| | | unMarkSprite(child); |
| | | }) |
| | | selectedSprites = []; |
| | | mapContainer.parent.off('mousedown'); |
| | | mapContainer.parent.off('mousemove'); |
| | | mapContainer.parent.off('mouseup'); |
| | | |
| | | resetFn(); |
| | | } |
| | | |
| | | const batchMoveStart = (event) => { |
| | | batchMoveStartPos = { x: event.data.global.clone().x, y: event.data.global.clone().y }; |
| | | selectedSprites.forEach(child => { |
| | | child.data.batchMoveStartPos = { x: child.position.x, y: child.position.y }; |
| | | }) |
| | | |
| | | batchMove = true; |
| | | mapContainer.parent.off('mousemove'); |
| | | mapContainer.parent.on('mousemove', batchMoving); |
| | | |
| | | mapContainer.parent.off('mouseup'); |
| | | mapContainer.parent.on('mouseup', batchMoveEnd); |
| | | } |
| | | |
| | | mapContainer.parent.off('mousedown') |
| | | mapContainer.parent.on('mousedown', batchMoveStart); |
| | | } |
| | | } |
| | | |
| | | export const isSpriteInSelectionBox = (sprite, selectionBox) => { |
| | | const spriteBounds = sprite.getBounds(); |
| | | const boxBounds = selectionBox.getBounds(); |
| | | |
| | | return spriteBounds.x + spriteBounds.width > boxBounds.x |
| | | && spriteBounds.x < boxBounds.x + boxBounds.width |
| | | && spriteBounds.y + spriteBounds.height > boxBounds.y |
| | | && spriteBounds.y < boxBounds.y + boxBounds.height; |
| | | } |
| | | |
| | | export const showSelectedEffect = (sprite) => { |
| | | const { width, height } = sprite; |
| | | const scale = sprite.scale.x; |
| | | const sideLen = (Math.max(width, height) + 10) * scale; |
| | | const color = 0x273c75; |
| | | |
| | | effectHalfCircle = new PIXI.Graphics(); |
| | | effectHalfCircle.beginFill(color); |
| | | effectHalfCircle.lineStyle(2 * scale, color); |
| | | effectHalfCircle.arc(0, 0, sideLen, 0, Math.PI); |
| | | effectHalfCircle.endFill(); |
| | | effectHalfCircle.position.set(sprite.x, sprite.y); |
| | | effectHalfCircle.scale.set(1 / scale); |
| | | |
| | | effectRectangle = new PIXI.Graphics(); |
| | | effectRectangle.lineStyle(2 * scale, color, 1); |
| | | effectRectangle.drawRoundedRect(0, 0, sideLen, sideLen, 16 * scale); |
| | | effectRectangle.endFill(); |
| | | effectRectangle.mask = effectHalfCircle; |
| | | |
| | | const scaledWidth = sideLen * (1 / scale); |
| | | const scaledHeight = sideLen * (1 / scale); |
| | | |
| | | effectRectangle.scale.set(1 / scale); |
| | | effectRectangle.position.set(sprite.x - scaledWidth / 2, sprite.y - scaledHeight / 2); |
| | | |
| | | mapContainer.addChild(effectRectangle); |
| | | mapContainer.addChild(effectHalfCircle); |
| | | |
| | | let phase = 0; |
| | | effectTick = (delta) => { |
| | | phase += delta / 10; |
| | | phase %= (Math.PI * 2); |
| | | effectHalfCircle.rotation = phase; |
| | | }; |
| | | |
| | | app.ticker.add(effectTick); |
| | | } |
| | | |
| | | export const removeSelectedEffect = () => { |
| | | if (effectTick) { |
| | | app.ticker.remove(effectTick); |
| | | } |
| | | if (effectHalfCircle) { |
| | | mapContainer.removeChild(effectHalfCircle); |
| | | effectHalfCircle = null; |
| | | } |
| | | if (effectRectangle) { |
| | | mapContainer.removeChild(effectRectangle); |
| | | effectRectangle = null; |
| | | } |
| | | } |
| | | |
| | | export const markSprite = (sprite) => { |
| | | sprite.alpha = 0.5; |
| | | } |
| | | |
| | | export const unMarkSprite = (sprite) => { |
| | | sprite.alpha = 1; |
| | | } |