mirror of
https://github.com/jlfwong/speedscope.git
synced 2024-11-30 03:15:25 +03:00
Basic mouse interactions for the minimap
This commit is contained in:
parent
e59299cfc5
commit
1870bb9c6b
@ -13,6 +13,7 @@ const DEVICE_PIXEL_RATIO = window.devicePixelRatio
|
|||||||
interface FlamechartMinimapViewProps {
|
interface FlamechartMinimapViewProps {
|
||||||
flamechart: Flamechart
|
flamechart: Flamechart
|
||||||
configSpaceViewportRect: Rect
|
configSpaceViewportRect: Rect
|
||||||
|
setConfigSpaceViewportRect: (rect: Rect) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps, {}> {
|
export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps, {}> {
|
||||||
@ -128,6 +129,92 @@ export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private minConfigSpaceViewportRectWidth() { return 3 * this.props.flamechart.getMinFrameWidth(); }
|
||||||
|
|
||||||
|
private transformViewport(transform: AffineTransform) {
|
||||||
|
const viewportRect = transform.transformRect(this.props.configSpaceViewportRect)
|
||||||
|
this.setConfigSpaceViewportRect(viewportRect)
|
||||||
|
}
|
||||||
|
|
||||||
|
private setConfigSpaceViewportRect(viewportRect: Rect) {
|
||||||
|
const configSpaceOriginBounds = new Rect(
|
||||||
|
new Vec2(0, 0),
|
||||||
|
Vec2.max(new Vec2(0, 0), this.configSpaceSize().minus(viewportRect.size))
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO(jlfwong): De-dup this with FlamechartPanZoomView
|
||||||
|
const configSpaceSizeBounds = new Rect(
|
||||||
|
new Vec2(this.minConfigSpaceViewportRectWidth(), viewportRect.height()),
|
||||||
|
new Vec2(this.configSpaceSize().x, viewportRect.height())
|
||||||
|
)
|
||||||
|
|
||||||
|
this.props.setConfigSpaceViewportRect(new Rect(
|
||||||
|
configSpaceOriginBounds.closestPointTo(viewportRect.origin),
|
||||||
|
configSpaceSizeBounds.closestPointTo(viewportRect.size)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
private logicalToPhysicalViewSpace() {
|
||||||
|
return AffineTransform.withScale(new Vec2(DEVICE_PIXEL_RATIO, DEVICE_PIXEL_RATIO))
|
||||||
|
}
|
||||||
|
|
||||||
|
private pan(logicalViewSpaceDelta: Vec2) {
|
||||||
|
const physicalDelta = this.logicalToPhysicalViewSpace().transformVector(logicalViewSpaceDelta)
|
||||||
|
const configDelta = this.configSpaceToPhysicalViewSpace().inverseTransformVector(physicalDelta)
|
||||||
|
|
||||||
|
if (!configDelta) return
|
||||||
|
this.transformViewport(AffineTransform.withTranslation(configDelta))
|
||||||
|
}
|
||||||
|
|
||||||
|
private onWheel = (ev: WheelEvent) => {
|
||||||
|
ev.preventDefault()
|
||||||
|
this.pan(new Vec2(ev.deltaX, ev.deltaY))
|
||||||
|
this.renderCanvas()
|
||||||
|
}
|
||||||
|
|
||||||
|
private dragStartPos: Vec2 | null = null
|
||||||
|
private onMouseDown = (ev: MouseEvent) => {
|
||||||
|
this.dragStartPos = new Vec2(ev.offsetX, ev.offsetY)
|
||||||
|
}
|
||||||
|
|
||||||
|
private onMouseDrag = (ev: MouseEvent) => {
|
||||||
|
if (!this.dragStartPos) return
|
||||||
|
|
||||||
|
const logicalStart = this.dragStartPos
|
||||||
|
const physicalStart = this.logicalToPhysicalViewSpace().transformPosition(logicalStart)
|
||||||
|
const configStart = this.configSpaceToPhysicalViewSpace().inverseTransformPosition(physicalStart)
|
||||||
|
|
||||||
|
const logicalEnd = new Vec2(ev.offsetX, ev.offsetY)
|
||||||
|
const physicalEnd = this.logicalToPhysicalViewSpace().transformPosition(logicalEnd)
|
||||||
|
const configEnd = this.configSpaceToPhysicalViewSpace().inverseTransformPosition(physicalEnd)
|
||||||
|
|
||||||
|
if (!configStart || !configEnd) return
|
||||||
|
|
||||||
|
const left = Math.min(configStart.x, configEnd.x)
|
||||||
|
const right = Math.max(configStart.x, configEnd.x)
|
||||||
|
|
||||||
|
const width = right - left
|
||||||
|
const height = this.props.configSpaceViewportRect.height()
|
||||||
|
|
||||||
|
this.setConfigSpaceViewportRect(new Rect(
|
||||||
|
new Vec2(left, configEnd.y - height / 2),
|
||||||
|
new Vec2(width, height)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
private onMouseMove = (ev: MouseEvent) => {
|
||||||
|
if (this.dragStartPos) {
|
||||||
|
ev.preventDefault()
|
||||||
|
this.onMouseDrag(ev)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onWindowMouseUp = (ev: MouseEvent) => {
|
||||||
|
document.body.style.cursor = 'default'
|
||||||
|
this.dragStartPos = null
|
||||||
|
}
|
||||||
|
|
||||||
private preprocess(flamechart: Flamechart) {
|
private preprocess(flamechart: Flamechart) {
|
||||||
if (!this.canvas || !this.regl) return
|
if (!this.canvas || !this.regl) return
|
||||||
const configSpaceRects: Rect[] = []
|
const configSpaceRects: Rect[] = []
|
||||||
@ -152,9 +239,20 @@ export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps,
|
|||||||
this.overlayRenderer = overlayRectangleRenderer(this.regl);
|
this.overlayRenderer = overlayRectangleRenderer(this.regl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.addEventListener('mouseup', this.onWindowMouseUp)
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener('mouseup', this.onWindowMouseUp)
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
onWheel={this.onWheel}
|
||||||
|
onMouseDown={this.onMouseDown}
|
||||||
|
onMouseMove={this.onMouseMove}
|
||||||
className={css(style.minimap, style.vbox)} >
|
className={css(style.minimap, style.vbox)} >
|
||||||
<canvas
|
<canvas
|
||||||
width={1} height={1}
|
width={1} height={1}
|
||||||
|
@ -430,7 +430,6 @@ export class FlamechartPanZoomView extends ReloadableComponent<FlamechartPanZoom
|
|||||||
}
|
}
|
||||||
|
|
||||||
private lastDragPos: Vec2 | null = null
|
private lastDragPos: Vec2 | null = null
|
||||||
|
|
||||||
private onMouseDown = (ev: MouseEvent) => {
|
private onMouseDown = (ev: MouseEvent) => {
|
||||||
document.body.style.cursor = 'grabbing'
|
document.body.style.cursor = 'grabbing'
|
||||||
document.body.style.cursor = '-webkit-grabbing'
|
document.body.style.cursor = '-webkit-grabbing'
|
||||||
@ -450,6 +449,11 @@ export class FlamechartPanZoomView extends ReloadableComponent<FlamechartPanZoom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onWindowMouseUp = (ev: MouseEvent) => {
|
||||||
|
document.body.style.cursor = 'default'
|
||||||
|
this.lastDragPos = null
|
||||||
|
}
|
||||||
|
|
||||||
private onMouseMove = (ev: MouseEvent) => {
|
private onMouseMove = (ev: MouseEvent) => {
|
||||||
if (this.lastDragPos) {
|
if (this.lastDragPos) {
|
||||||
ev.preventDefault()
|
ev.preventDefault()
|
||||||
@ -508,11 +512,6 @@ export class FlamechartPanZoomView extends ReloadableComponent<FlamechartPanZoom
|
|||||||
this.renderCanvas()
|
this.renderCanvas()
|
||||||
}
|
}
|
||||||
|
|
||||||
private onWindowMouseUp = (ev: MouseEvent) => {
|
|
||||||
document.body.style.cursor = 'default'
|
|
||||||
this.lastDragPos = null
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate() { return false }
|
shouldComponentUpdate() { return false }
|
||||||
componentWillReceiveProps(nextProps: FlamechartPanZoomViewProps) {
|
componentWillReceiveProps(nextProps: FlamechartPanZoomViewProps) {
|
||||||
if (this.props.flamechart !== nextProps.flamechart) {
|
if (this.props.flamechart !== nextProps.flamechart) {
|
||||||
@ -645,6 +644,7 @@ export class FlamechartView extends ReloadableComponent<FlamechartViewProps, Fla
|
|||||||
<div className={css(style.fill, style.clip, style.vbox)} ref={this.containerRef}>
|
<div className={css(style.fill, style.clip, style.vbox)} ref={this.containerRef}>
|
||||||
<FlamechartMinimapView
|
<FlamechartMinimapView
|
||||||
configSpaceViewportRect={this.state.configSpaceViewportRect}
|
configSpaceViewportRect={this.state.configSpaceViewportRect}
|
||||||
|
setConfigSpaceViewportRect={this.setConfigSpaceViewportRect}
|
||||||
flamechart={this.props.flamechart} />
|
flamechart={this.props.flamechart} />
|
||||||
<FlamechartPanZoomView
|
<FlamechartPanZoomView
|
||||||
ref={this.panZoomRef}
|
ref={this.panZoomRef}
|
||||||
|
Loading…
Reference in New Issue
Block a user