Skip to content

Instantly share code, notes, and snippets.

@visitek
Created August 11, 2016 11:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save visitek/3d90d7b27b817b698a44231a30a62354 to your computer and use it in GitHub Desktop.
Save visitek/3d90d7b27b817b698a44231a30a62354 to your computer and use it in GitHub Desktop.
Horizontal scrollbar for Angular2
/**
* 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