// import { Viewport } from 'pixi-viewport' // use with modern build toolchain
import { stars } from './stars'
import * as target from './target'
const WORLD_WIDTH = 2000
const WORLD_HEIGHT = 2000
const STAR_SIZE = 30
const BORDER = 10
// INSTRUCTIONS
// see https://davidfig.github.io/pixi-viewport/jsdoc/ for full API documentation
// uncomment out the plugins or change options to experiment with how the viewport works
let viewport
export function create(renderer) {
// create the viewport
// viewport = new Viewport({ // use with modern build toolchain
viewport = new pixi_viewport.Viewport({
// screenWidth: window.innerWidth, // screen width used by viewport (eg, size of canvas)
// screenHeight: window.innerHeight, // screen height used by viewport (eg, size of canvas)
worldWidth: WORLD_WIDTH, // world width used by viewport (automatically calculated based on container width)
worldHeight: WORLD_HEIGHT, // world height used by viewport (automatically calculated based on container height)
// threshold: 5, // number of pixels to move to trigger an input event (e.g., drag, pinch) or disable a clicked event
passiveWheel: false, // whether the 'wheel' event is set to passive (note: if false, e.preventDefault() will be called when wheel is used over the viewport)
// stopPropagation: false, // whether to stopPropagation of events that impact the viewport (except wheel events, see options.passiveWheel)
// forceHitArea: null, // change the default hitArea from world size to a new value
// noTicker: false, // set this if you want to manually call update() function on each frame
// ticker: PIXI.Ticker.shared, // use this PIXI.ticker for updates
interaction: renderer.plugins.interaction, // InteractionManager, available from instantiated WebGLRenderer/CanvasRenderer.plugins.interaction - used to calculate pointer position relative to canvas location on screen
// divWheel: null, // div to attach the wheel event (uses document.body as default)
// disableOnContextMenu: false, // remove oncontextmenu=() => {} from the divWheel element
})
viewport
.drag({
direction: 'x', // (x, y, or all) direction to drag
// pressDrag: true, // whether click to drag is active
// wheel: true, // use wheel to scroll in direction (unless wheel plugin is active)
// wheelScroll: 1, // number of pixels to scroll with each wheel spin
// reverse: false, // reverse the direction of the wheel scroll
// clampWheel: false, // clamp wheel (to avoid weird bounce with mouse wheel)
// underflow: 'center', // (top-left, top-center, etc.) where to place world if too small for screen
// factor: 1, // factor to multiply drag to increase the speed of movement
// mouseButtons: 'all', // changes which mouse buttons trigger drag, use: 'all', 'left', right' 'middle', or some combination, like, 'middle-right'; you may want to set viewport.options.disableOnContextMenu if you want to use right-click dragging
// keyToPress: null, // array containing https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code codes of keys that can be pressed for the drag to be triggered, e.g.: ['ShiftLeft', 'ShiftRight'}
// ignoreKeyToPressOnTouch: false, // ignore keyToPress for touch events
// lineHeight: 20, // scaling factor for non-DOM_DELTA_PIXEL scrolling events (used for firefox mouse scrolling)
})
.decelerate({
// friction: 0.95, // percent to decelerate after movement
// bounce: 0.8, // percent to decelerate when past boundaries (only applicable when viewport.bounce() is active)
// minSpeed: 0.01, // minimum velocity before stopping/reversing acceleration
})
.pinch({
// noDrag: false, // disable two-finger dragging
// percent: 1, // percent to modify pinch speed
// factor: 1, // factor to multiply two-finger drag to increase the speed of movement
// center: null, // place this point at center during zoom instead of center of two fingers
// axis: 'all', // axis to zoom
})
.wheel({
// percent: 0.1, // smooth the zooming by providing the number of frames to zoom between wheel spins
// interrupt: true, // stop smoothing with any user input on the viewport
// reverse: false, // reverse the direction of the scroll
// center: null, // place this point at center during zoom instead of current mouse position
// lineHeight: 20, // scaling factor for non-DOM_DELTA_PIXEL scrolling events
axis: 'x', // axis to zoom
})
// viewport.bounce({
// sides: 'all', // all, horizontal, vertical, or combination of top, bottom, right, left(e.g., 'top-bottom-right')
// friction: 0.5, // friction to apply to decelerate if active
// time: 150, // time in ms to finish bounce
// bounceBox: null, // use this bounceBox instead of { x: 0, y: 0, width: viewport.worldWidth, height: viewport.worldHeight }
// ease: 'easeInOutSine', // ease function or name (see http://easings.net/ for supported names)
// underflow: 'center', // (top/bottom/center and left/right/center, or center) where to place world if too small for screen
// })
// viewport.animate({
// time: 1000, // time to animate
// position: null, // position to move viewport
// width: null, // desired viewport width in world pixels (use instead of scale; aspect ratio is maintained if height is not provided)
// height: null, // desired viewport height in world pixels(use instead of scale; aspect ratio is maintained if width is not provided)
// scale: null, // scale to change zoom(scale.x = scale.y)
// scaleX: null, // independently change zoom in x - direction
// scaleY: null, // independently change zoom in y - direction
// ease: 'linear', // easing function to use
// callbackOnComplete: null, // callback when animate is complete
// removeOnInterrupt: false, // removes this plugin if interrupted by any user input
// })
// viewport.clamp({
// left: 10, // whether to clamp to the left and at what value
// right: false, // whether to clamp to the right and at what value
// top: false, // whether to clamp to the top and at what value
// bottom: false, // whether to clamp to the bottom and at what value
// direction: 'x', // (all, x, or y) using clamps of [0, viewport.worldWidth / viewport.worldHeight]; replaces left / right / top / bottom if set
// underflow: 'center', // where to place world if too small for screen (e.g., top - right, center, none, bottomleft)
// })
viewport.clampZoom({
minWidth: WORLD_WIDTH, // minimum width
minHeight: WORLD_HEIGHT, // minimum height
maxWidth: WORLD_WIDTH, // maximum width
maxHeight: WORLD_HEIGHT, // maximum height
minScale: null, // minimum scale
maxScale: null, // minimum scale
})
// target.start() // starts the target moving
// viewport.follow(target.get(), {
// speed: 0, // speed to follow in pixels/frame (0=teleport to location)
// acceleration: null, // set acceleration to accelerate and decelerate at this rate; speed cannot be 0 to use acceleration
// radius: null, // radius (in world coordinates) of center circle where movement is allowed without moving the viewport
// })
// viewport.mouseEdges({
// radius: null, // distance from center of screen in screen pixels
// distance: 20, // distance from all sides in screen pixels
// top: null, // alternatively, set top distance (leave unset for no top scroll)
// bottom: null, // alternatively, set bottom distance (leave unset for no top scroll)
// left: null, // alternatively, set left distance (leave unset for no top scroll)
// right: null, // alternatively, set right distance (leave unset for no top scroll)
// speed: 8, // speed in pixels/frame to scroll viewport
// reverse: false, // reverse direction of scroll
// noDecelerate: false, // don't use decelerate plugin even if it's installed
// linear: false, // if using radius, use linear movement (+/- 1, +/- 1) instead of angled movement (Math.cos(angle from center), Math.sin(angle from center))
// allowButtons: false, // allows plugin to continue working even when there's a mousedown event
// })
// viewport.snap({
// topLeft: false, // snap to the top-left of viewport instead of center
// friction: 0.8, // friction/frame to apply if decelerate is active
// time: 1000, // time for snapping in ms
// ease: 'easeInOutSine', // ease function or name (see http://easings.net/ for supported names)
// interrupt: true, // pause snapping with any user input on the viewport
// removeOnComplete: false, // removes this plugin after snapping is complete
// removeOnInterrupt: false, // removes this plugin if interrupted by any user input
// forceStart: false, // starts the snap immediately regardless of whether the viewport is at the desired location
// })
// viewport.snapZoom({
// width: 0, // the desired width to snap (to maintain aspect ratio, choose only width or height)
// height: 0, // the desired height to snap(to maintain aspect ratio, choose only width or height)
// time: 1000, // time for snapping in ms
// ease: 'easeInOutSine', // ease function or name(see http://easings.net/ for supported names)
// center: null, // place this point at center during zoom instead of center of the viewport
// interrupt: true, // pause snapping with any user input on the viewport
// removeOnComplete: false, // removes this plugin after snapping is complete
// removeOnInterrupt: false, // removes this plugin if interrupted by any user input
// forceStart: false, // starts the snap immediately regardless of whether the viewport is at the desired zoom
// noMove: false, // zoom but do not move
// })
// create elements
stars(viewport, STAR_SIZE, BORDER)
target.setup(viewport)
border(viewport, BORDER)
// fit and center the world into the panel
viewport.fit()
viewport.moveCenter(WORLD_WIDTH / 2, WORLD_HEIGHT / 2)
}
function border(viewport) {
const line = viewport.addChild(new PIXI.Graphics())
line.lineStyle(10, 0xff0000).drawRect(0, 0, viewport.worldWidth, viewport.worldHeight)
}
export function get() {
return viewport
}
https://davidfig.github.io/pixi-viewport/ demo code: