Skip to content

Commit

Permalink
Overhaul scrollbar JS
Browse files Browse the repository at this point in the history
  • Loading branch information
rnixx committed May 22, 2024
1 parent 78582ab commit 1ae904a
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 147 deletions.
8 changes: 4 additions & 4 deletions js/src/personaltools.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ export class PersonalTools extends ts.Events {
this.scrollable.each((i, item) => {
const scrollbar = $(item).data('scrollbar');
if (!scrollbar.disabled) {
scrollbar.reset();
scrollbar.disable();
scrollbar.position = 0;
scrollbar.disabled = true;
}
});
}
Expand All @@ -70,8 +70,8 @@ export class PersonalTools extends ts.Events {
this.scrollable.each((i, item) => {
const scrollbar = $(item).data('scrollbar');
if (scrollbar.disabled) {
scrollbar.bind();
scrollbar.disabled = false;
}
});
}
}
}
137 changes: 62 additions & 75 deletions js/src/scrollbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,44 @@ export class Scrollbar extends ts.Events {

this.elem = elem;
this.elem.data('scrollbar', this);

// scrollable content
this.content = $('.scrollable-content', this.elem);

this.position = 0;
this.unit = 50;
this.disabled = null;
this.content = ts.query_elem('.scrollable-content', elem);

this.on_scroll = this.on_scroll.bind(this);
this.on_click = this.on_click.bind(this);
this.on_drag = this.on_drag.bind(this);
this.on_hover = this.on_hover.bind(this);
this.on_resize = this.on_resize.bind(this);

this.compile();
this.position = 0;
this.scroll_step = 50;
new ts.Property(this, 'disabled', false);

ts.ajax.attach(this, this.elem);
ts.clock.schedule_frame(() => this.render());
}

this.compile();
this.bind();
ts.clock.schedule_frame(() => this.update());
get position() {
return this._position || 0;
}

set position(position) {
this._position = this.safe_position(position);
this.update();
this.trigger('on_position', this._position);
}

bind() {
this.disabled = false;
this.elem.css('pointer-events', 'all');
this.elem.on('mousewheel wheel', this.on_scroll);
this.scrollbar.on('click', this.on_click);
this.thumb.on('mousedown', this.on_drag);
this.elem.on('mouseenter mouseleave', this.on_hover);
$(window).on('resize', this.on_resize);
}

disable() {
this.disabled = true;
unbind() {
this.elem.css('pointer-events', 'none');
this.elem.off('mousewheel wheel', this.on_scroll);
this.scrollbar.off('click', this.on_click);
this.thumb.off('mousedown', this.on_drag);
Expand All @@ -57,7 +63,7 @@ export class Scrollbar extends ts.Events {
}

destroy() {
$(window).off('resize', this.on_resize);
this.unbind();
}

compile() {
Expand All @@ -69,46 +75,51 @@ export class Scrollbar extends ts.Events {
`, this.elem);
}

update() {
// abstract, implemented in subclass
throw 'Abstract Scrollbar does not implement update()';
}

update(attr) {
render(attr) {
this.scrollbar.css(attr, this.scrollsize);
if(this.contentsize <= this.scrollsize) {
this.thumbsize = this.scrollsize;
} else {
this.thumbsize = Math.pow(this.scrollsize, 2) / this.contentsize;
}
this.thumb.css(attr, this.thumbsize);
this.set_position();
this.update();
}

reset() {
this.position = 0;
this.set_position();
safe_position(position) {
const max_pos = this.contentsize - this.scrollsize;
if (position >= max_pos) {
position = max_pos;
} else if (position <= 0) {
position = 0;
}
return position;
}

unload() {
this.scrollbar.off('click', this.on_click);
this.elem.off('mousewheel wheel', this.on_scroll);
this.elem.off('mouseenter mouseleave', this.on_hover);
this.thumb.off('mousedown', this.on_drag);
on_disabled(value) {
if (value) {
this.unbind();
} else {
this.bind();
}
}

on_resize() {
this.render();
}

on_hover(e) {
e.preventDefault();
e.stopPropagation();

const container = this.elem.get(0);
const is_inside_container = $(container).has(e.target).length > 0 || $(container).is(e.target);

if (is_inside_container && this.contentsize > this.scrollsize) {
const elem = this.elem;
if (
(elem.has(e.target).length > 0 || elem.is(e.target)) &&
this.contentsize > this.scrollsize
) {
if (e.type === 'mouseenter') {
this.scrollbar.stop(true, true).fadeIn();
} else if (e.type === 'mouseleave') {
if (e.relatedTarget !== this.elem.get(0)) {
if (e.relatedTarget !== elem.get(0)) {
this.scrollbar.stop(true, true).fadeOut();
}
}
Expand All @@ -123,32 +134,21 @@ export class Scrollbar extends ts.Events {
if (typeof evt.deltaY === 'number') {
// down
if(evt.deltaY > 0) {
this.position += this.unit;
this.position += this.scroll_step;
}
// up
else if(evt.deltaY < 0) {
this.position -= this.unit;
this.position -= this.scroll_step;
}
}
this.set_position();
}

prevent_overflow() {
let threshold = this.contentsize - this.scrollsize;
if(this.position >= threshold) {
this.position = threshold;
} else if(this.position <= 0) {
this.position = 0;
}
}

on_click(e) {
e.preventDefault(); // prevent text selection
this.thumb.addClass('active');
let evt_data = this.get_evt_data(e),
new_thumb_pos = evt_data - this.offset - this.thumbsize / 2;
this.position = this.contentsize * new_thumb_pos / this.scrollsize;
this.set_position();
let position = this.pos_from_evt(e),
thumb_pos = position - this.offset - this.thumbsize / 2;
this.position = this.contentsize * thumb_pos / this.scrollsize;
this.thumb.removeClass('active');
}

Expand All @@ -158,10 +158,9 @@ export class Scrollbar extends ts.Events {
$(window).trigger(evt);

function on_move(e) {
let mouse_pos_on_move = this.get_evt_data(e) - this.offset,
let mouse_pos_on_move = this.pos_from_evt(e) - this.offset,
new_thumb_pos = thumb_position + mouse_pos_on_move - mouse_pos;
this.position = this.contentsize * new_thumb_pos / this.scrollsize;
this.set_position();
}

function on_up() {
Expand All @@ -176,7 +175,7 @@ export class Scrollbar extends ts.Events {

let _on_move = on_move.bind(this),
_on_up = on_up.bind(this),
mouse_pos = this.get_evt_data(e) - this.offset,
mouse_pos = this.pos_from_evt(e) - this.offset,
thumb_position = this.position / (this.contentsize / this.scrollsize);
this.thumb.addClass('active');

Expand Down Expand Up @@ -212,23 +211,17 @@ export class ScrollbarX extends Scrollbar {
this.thumb.css('width', this.thumbsize);
}

update() {
super.update('width');
}

on_resize() {
this.update();
render() {
super.render('width');
}

set_position() {
this.prevent_overflow();
update() {
let thumb_pos = this.position / (this.contentsize / this.scrollsize);
this.content.css('right', this.position + 'px');
this.thumb.css('left', thumb_pos + 'px');
this.trigger('on_position');
}

get_evt_data(e) {
pos_from_evt(e) {
return e.pageX;
}
};
Expand Down Expand Up @@ -258,23 +251,17 @@ export class ScrollbarY extends Scrollbar {
this.thumb.css('height', this.thumbsize);
}

update() {
super.update('height');
render() {
super.render('height');
}

on_resize() {
this.update();
}

set_position() {
this.prevent_overflow();
update() {
let thumb_pos = this.position / (this.contentsize / this.scrollsize);
this.content.css('bottom', this.position + 'px');
this.thumb.css('top', thumb_pos + 'px');
this.trigger('on_position');
}

get_evt_data(e) {
pos_from_evt(e) {
return e.pageY;
}
}
}
Loading

0 comments on commit 1ae904a

Please sign in to comment.