Created
August 11, 2016 11:12
-
-
Save visitek/3d90d7b27b817b698a44231a30a62354 to your computer and use it in GitHub Desktop.
Horizontal scrollbar for Angular2
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
/** | |
* MyAppIn (http://www.myappin.cz) | |
* @author Martin Lonsky (martin@lonsky.net, +420 736 645876) | |
* @link http://www.myappin.cz | |
* @copyright Copyright (c) MyAppIn s.r.o. (http://www.myappin.cz) | |
* Date: 10. 8. 2016 | |
* Time: 12:36 | |
*/ | |
import {INode} from './node.interface'; | |
import {IRenderable} from '../core/renderable.interface'; | |
import * as d3 from 'd3'; | |
import {EventEmitter} from '@angular/core'; | |
/// <reference path="/typings/index.d.ts" /> | |
export class ScrollVerticalComponent implements INode, IRenderable { | |
private _node:any; | |
private _scrollPath:any; | |
private _scroll:any; | |
private _scrollX:number = 0; | |
private _scrollWidth:number = 0; | |
private _visible:boolean = true; | |
private _scrollEmitter:EventEmitter<ScrollVerticalComponent> = new EventEmitter; | |
public node():any { | |
return this._node; | |
} | |
public constructor(private _parentNode:INode, | |
private _x:number = 0, | |
private _y:number = 0, | |
private _width:number = 0, | |
private _height:number = 0, | |
private _scrollAt:number = 0, | |
private _contentWidth:number) { | |
this._scrollX = this.x + (this.width / 100 * this.scrollAt); | |
} | |
public get scrollEmitter():EventEmitter<ScrollVerticalComponent> { | |
return this._scrollEmitter; | |
} | |
public get x():number { | |
return this._x; | |
} | |
public get y():number { | |
return this._y; | |
} | |
public get width():number { | |
return this._width; | |
} | |
public get height():number { | |
return this._height; | |
} | |
public get scrollAt():number { | |
return this._scrollAt; | |
} | |
public get scrollX():number { | |
return this._scrollX; | |
} | |
public get scrollWidth():number { | |
return this._scrollWidth; | |
} | |
public get visible():boolean { | |
return this._visible; | |
} | |
public get contentWidth() { | |
return this._contentWidth; | |
} | |
public set x(value:number) { | |
this._x = value; | |
} | |
public set y(value:number) { | |
this._y = value; | |
} | |
public set width(value:number) { | |
this._width = value; | |
} | |
public set height(value:number) { | |
this._height = value; | |
} | |
public set scrollX(value:number) { | |
this.scrollAt = value / this.contentWidth * 100; | |
} | |
public set scrollAt(value:number) { | |
if(value > 100){ | |
value = 100; | |
} | |
else if(value < 0){ | |
value = 0; | |
} | |
this._scrollAt = value; | |
this.resolve(); | |
} | |
public set contentWidth(value:number) { | |
this._contentWidth = value; | |
this.resolve(); | |
} | |
public set visible(value:boolean) { | |
if (value) { | |
this._node.classed('hidden', false); | |
} | |
else { | |
this._node.classed('hidden', true); | |
} | |
this._visible = value; | |
} | |
public render():void { | |
this._node = this._parentNode.node().append('g').classed('scroll', true); | |
let __this = this; | |
this._scrollPath = this._node.append('path').classed('bar_line', true).on('click', ()=> { | |
this.scrollAt = (d3.event.offsetX - this.x) / this.width * 100; | |
}); | |
this._scroll = this._node.append('path').classed('scroll', true).call(d3.drag() | |
.on('start', function () { | |
__this._scroll.classed("dragging", true); | |
}) | |
.on("drag", function () { | |
__this._scroll.classed("dragging", true); | |
let x = __this.scrollX + d3.event.dx; | |
if (x < __this.x) { | |
x = __this.x; | |
} | |
if (x > __this.width + __this.x - __this.scrollWidth) { | |
x = __this.width + __this.x - __this.scrollWidth; | |
} | |
__this._scrollX = x; | |
__this.scrollAt = (__this.scrollX - __this.x) / (__this.width - __this.scrollWidth) * 100; | |
__this._moveScroll(); | |
}) | |
.on('end', function () { | |
__this._scroll.classed("dragging", false); | |
})); | |
} | |
public remove():void { | |
} | |
public resolve():void { | |
if (!this._visible) { | |
return; | |
} | |
this._scrollPath.attr('d', ()=> { | |
let path = d3.path(); | |
path.rect(this.x, this.y, this.width, this.height); | |
return path.toString(); | |
}); | |
this._scrollWidth = this.width / (this.contentWidth / this.width); | |
if (this.scrollWidth < 8) { | |
this._scrollWidth = 8; | |
} | |
this._scroll.attr('d', ()=> { | |
let path = d3.path(); | |
path.rect(this.x, this.y, this.scrollWidth, this.height); | |
return path.toString(); | |
}); | |
this._moveScroll(); | |
} | |
private _moveScroll():void { | |
this._scroll.attr('transform', ()=> { | |
let x = ((this.width - this.scrollWidth) / 100 * this.scrollAt) + this.x; | |
if (x < this.x) { | |
x = this.x; | |
} | |
if (x > this.width + this.x - this.scrollWidth) { | |
x = this.width + this.x - this.scrollWidth; | |
} | |
this._scrollX = x; | |
return 'translate(' + (x - this.x) + ',0)' | |
}); | |
this.scrollEmitter.emit(this); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment