Skip to content

Commit

Permalink
Merge pull request #211 from nateplusplus/next-release
Browse files Browse the repository at this point in the history
Next release
  • Loading branch information
nateplusplus authored Jul 10, 2022
2 parents 52ddd65 + 4eae5d3 commit 827a9f4
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 30 deletions.
8 changes: 7 additions & 1 deletion docs/api.pug
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ block content
td string
td: code undefined
td JavaScript selector used to attach PushIn to an element on the page.
tr
th(scope="row") scrollTarget
td: code data-pushin-scroll-target
td string
td: code target | window
td JavaScript selector used to bind scroll events. If "window" is provided, scroll events will be bound to the Window object, regardless of which element is the target.
section.container-fluid.my-5
.row
.col
Expand All @@ -132,7 +138,7 @@ block content
td: code 0,768,1440,1920
td Provide a comma-separated list of numbers to configure appropriate responsive design breakpoints.
tr
th(scope="row") from
th(scope="row") inpoints
td: code data-pushin-from
td string
td: code 0
Expand Down
23 changes: 11 additions & 12 deletions docs/home.pug
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ block append head

block append styles
style.
#demo {
height: 500px;
}

.pushin-layer img {
width: 100%;
}
Expand Down Expand Up @@ -67,29 +63,29 @@ block content
.pushin
.pushin-scene
.pushin-composition
.pushin-layer(data-pushin-transitions='false' data-pushin-to="1000" data-pushin-speed="20")
.pushin-layer(data-pushin-from="350" data-pushin-to="2500" data-pushin-speed="20")
.mountain-0.no-pointer
.mountain-0-text.position-absolute.d-flex.align-items-center.justify-content-center.no-pointer
p Scroll to begin
img(src='/pushin/images/mountain-0-mask.svg')
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="2000" data-pushin-from="0" data-pushin-to="3500" data-pushin-speed="7")
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="2000" data-pushin-from="350" data-pushin-to="3500" data-pushin-speed="7")
.mountain-1.no-pointer
img(src='/pushin/images/mountain-02-hill-1.svg')
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="2000" data-pushin-from="0" data-pushin-to="5000" data-pushin-speed="8")
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="2000" data-pushin-from="350" data-pushin-to="5000" data-pushin-speed="8")
.mountain-2.no-pointer
img(src='/pushin/images/mountain-01-trees.svg')
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="1500" data-pushin-from="0" data-pushin-to="4000" data-pushin-speed="4")
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="1500" data-pushin-from="350" data-pushin-to="4000" data-pushin-speed="4")
.mountain-3.no-pointer
img(src='/pushin/images/mountain-03-hill-2.svg')
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="1500" data-pushin-from="0" data-pushin-to="4000" data-pushin-speed="1")
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="1500" data-pushin-from="350" data-pushin-to="4000" data-pushin-speed="1")
.mountain-4.no-pointer
img(src='/pushin/images/mountain-04-landscape.svg')
.pushin-layer(data-pushin-transitions='false' data-pushin-from="0" data-pushin-to="6000" data-pushin-speed='0.9')
.pushin-layer(data-pushin-transitions='false' data-pushin-from="350" data-pushin-to="6000" data-pushin-speed='0.9')
.mountain-5.no-pointer
.mountain-5-text.position-absolute.d-flex.align-items-center.justify-content-center.no-pointer
p PushIn.js
img(src='/pushin/images/mountain-05-logo.svg')
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="1000" data-pushin-from="0" data-pushin-to="5000" data-pushin-speed='0.5')
.pushin-layer(data-pushin-transition-start='-1' data-pushin-transition-end="1000" data-pushin-from="350" data-pushin-to="5000" data-pushin-speed='0.5')
.mountain-6.no-pointer
img(src='/pushin/images/mountain-06-sky.svg')
.pushin-layer
Expand Down Expand Up @@ -133,5 +129,8 @@ block content
block scripts
script( defer ).
document.addEventListener( 'DOMContentLoaded', function() {
pushInStart({ target: '#demo' });
pushInStart({
target: '#demo',
scrollTarget: 'window',
});
} );
14 changes: 10 additions & 4 deletions src/pushInScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,22 @@ export class PushInScene {
if (this.pushin.target) {
this.container.classList.add('pushin-scene--with-target');
}

if (this.pushin.scrollTarget === 'window') {
this.container.classList.add('pushin-scene--scroll-target-window');
}
}

/**
* Resize the PushIn container if using a target container.
*/
public resize() {
const sizes = this.pushin.target?.getBoundingClientRect();
if (sizes) {
this.container.style.height = `${sizes.height}px`;
this.container.style.width = `${sizes.width}px`;
if (this.pushin.scrollTarget !== 'window') {
const sizes = this.pushin.target?.getBoundingClientRect();
if (sizes) {
this.container.style.height = `${sizes.height}px`;
this.container.style.width = `${sizes.width}px`;
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/pushin.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
position: sticky;
}

.pushin-scene--scroll-target-window {
height: 100vh;
}

.pushin-composition {
flex: 0 0 100%;
padding-top: 201%;
Expand Down
69 changes: 56 additions & 13 deletions src/pushin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export class PushIn {
private lastAnimationFrameId = -1;
public cleanupFns: VoidFunction[] = [];
public options: PushInOptions;
public scrollTarget?: HTMLElement | string;

/* istanbul ignore next */
constructor(public container: HTMLElement, options?: PushInOptions) {
Expand All @@ -25,6 +26,7 @@ export class PushIn {
debug: options?.debug ?? false,
scene: options?.scene ?? { breakpoints: [], inpoints: [] },
target: options?.target ?? undefined,
scrollTarget: options?.scrollTarget,
};

this.options.scene!.composition = options?.composition ?? undefined;
Expand All @@ -38,15 +40,16 @@ export class PushIn {
*/
/* istanbul ignore next */
start(): void {
this.setTarget();
if (this.container) {
this.setTarget();
this.setScrollTarget();

this.scrollY = this.getScrollY();
this.scrollY = this.getScrollY();

if (this.options.debug) {
this.showDebugger();
}
if (this.options.debug) {
this.showDebugger();
}

if (this.container) {
this.scene = new PushInScene(this);

this.setScrollLength();
Expand All @@ -67,6 +70,39 @@ export class PushIn {
}
}

/**
* Get scrollTarget option from data attribute
* or JavaScript API.
*/
setScrollTarget(): void {
let scrollTarget;

let value;
if (this.container.hasAttribute('data-pushin-scroll-target')) {
value = <string>this.container!.dataset!.pushinScrollTarget;
} else if (this.options.scrollTarget) {
value = this.options!.scrollTarget;
}

if (value) {
if (value === 'window') {
scrollTarget = value;
} else {
scrollTarget = document.querySelector(<string>value);
}
}

if (!scrollTarget) {
if (this.target) {
scrollTarget = this.target;
} else {
scrollTarget = 'window';
}
}

this.scrollTarget = <HTMLElement | string>scrollTarget;
}

/**
* Set the target parameter and make sure
* pushin is always a child of that target.
Expand Down Expand Up @@ -108,10 +144,14 @@ export class PushIn {
*/
private getScrollY(): number {
let scrollY = 0;
if (this.target) {
scrollY = this.target.scrollTop;
} else if (typeof window !== 'undefined') {

if (this.scrollTarget === 'window' && typeof window !== 'undefined') {
scrollY = window.scrollY;
} else {
const target = <HTMLElement>this.scrollTarget;
if (target) {
scrollY = target.scrollTop;
}
}

return scrollY;
Expand All @@ -122,7 +162,7 @@ export class PushIn {
* on the provided target element.
*/
private setTargetOverflow(): void {
if (this.target) {
if (this.target && this.scrollTarget !== 'window') {
this.target.style.overflowY = 'scroll';
this.target.style.scrollBehavior = 'smooth';
}
Expand All @@ -133,7 +173,8 @@ export class PushIn {
*/
/* istanbul ignore next */
bindEvents(): void {
const scrollTarget = this.target ? this.target : window;
const scrollTarget =
this.scrollTarget === 'window' ? window : <HTMLElement>this.scrollTarget;

const onScroll = () => {
this.scrollY = this.getScrollY();
Expand All @@ -150,6 +191,7 @@ export class PushIn {
}
}
};

scrollTarget.addEventListener('scroll', onScroll);
this.cleanupFns.push(() =>
scrollTarget.removeEventListener('scroll', onScroll)
Expand Down Expand Up @@ -184,10 +226,11 @@ export class PushIn {
if (layer) {
const scrollTo = layer.params.inpoint + layer.params.transitionStart;

if (!this.target) {
if (this.scrollTarget === 'window') {
window.scrollTo(0, scrollTo);
} else {
this.target.scrollTop = scrollTo;
const container = <HTMLElement>scrollTarget;
container.scrollTop = scrollTo;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface PushInOptions {
scene?: SceneOptions;
selector?: string;
target?: string;
scrollTarget?: string;
}

export interface PushInLayer {
Expand Down
4 changes: 4 additions & 0 deletions test/pushIn/getScrollY.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,22 @@ describe('getScrollY', () => {
});

it('Should return 0 by default', () => {
// @ts-ignore: test requires breaking expected type
global.window = undefined;
const result = mockPushIn['getScrollY']();
expect(result).toEqual(0);
});

it('Should return scrollTop of target', () => {
mockPushIn['target'] = <HTMLElement>{ scrollTop: 15 };
mockPushIn['scrollTarget'] = mockPushIn['target'];
const result = mockPushIn['getScrollY']();
expect(result).toEqual(15);
});

it('Should return scrollY property of window', () => {
mockPushIn['scrollTarget'] = 'window';

window.scrollY = 20;
const result = mockPushIn['getScrollY']();
expect(result).toEqual(20);
Expand Down
54 changes: 54 additions & 0 deletions test/pushIn/setScrollTarget.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { setupJSDOM } from '../setup';
import { PushIn } from '../../src/pushin';

describe('setScrollTarget', () => {
let mockPushIn: PushIn;

beforeEach(() => {
setupJSDOM(`
<!DOCTYPE html>
<body>
<div id="target">
<div class="pushin">
</div>
</div>
</body>
</html>`);

mockPushIn = Object.create(PushIn.prototype);
Object.assign(
mockPushIn,
{
container: document.querySelector('.pushin'),
options: {},
}
);
});

it('Should return "window" by default', () => {
mockPushIn['setScrollTarget']();
expect(mockPushIn['scrollTarget']).toEqual('window');
});

it('Should return scrollTarget from HTML Attribute', () => {
document.querySelector('.pushin')?.setAttribute('data-pushin-scroll-target', '#target');
// mockPushIn.options.scrollTarget = '#target';
mockPushIn['setScrollTarget']();
const expected = document.querySelector('#target');
expect(mockPushIn['scrollTarget']).toEqual(expected);
});

it('Should return scrollTarget from JavasScript API', () => {
mockPushIn.options.scrollTarget = '#target';
mockPushIn['setScrollTarget']();
const expected = document.querySelector('#target');
expect(mockPushIn['scrollTarget']).toEqual(expected);
});

it('Should fall back to target element', () => {
const expected = document.querySelector('#target');
mockPushIn['target'] = <HTMLElement>expected;
mockPushIn['setScrollTarget']();
expect(mockPushIn['scrollTarget']).toEqual(expected);
});
});
Loading

0 comments on commit 827a9f4

Please sign in to comment.