{"id":16295138,"url":"https://github.com/wadackel/sweet-scroll","last_synced_at":"2025-04-09T05:13:19.057Z","repository":{"id":40307193,"uuid":"45517962","full_name":"wadackel/sweet-scroll","owner":"wadackel","description":":lollipop: ECMAScript2015+ \u0026 TypeScript Friendly, dependency-free smooth scroll library.","archived":false,"fork":false,"pushed_at":"2024-09-27T08:24:14.000Z","size":6240,"stargazers_count":382,"open_issues_count":23,"forks_count":44,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-10-11T20:17:54.933Z","etag":null,"topics":["animation","es2015","scrolling","smooth-scrolling","typescript","you-dont-need-jquery"],"latest_commit_sha":null,"homepage":"http://wadackel.github.io/sweet-scroll/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wadackel.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-11-04T05:45:48.000Z","updated_at":"2024-08-20T04:46:39.000Z","dependencies_parsed_at":"2023-01-22T11:45:14.515Z","dependency_job_id":"d2d85d81-f206-4f49-bb27-4ffd22957ee8","html_url":"https://github.com/wadackel/sweet-scroll","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wadackel%2Fsweet-scroll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wadackel%2Fsweet-scroll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wadackel%2Fsweet-scroll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wadackel%2Fsweet-scroll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wadackel","download_url":"https://codeload.github.com/wadackel/sweet-scroll/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247980843,"owners_count":21027808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","es2015","scrolling","smooth-scrolling","typescript","you-dont-need-jquery"],"created_at":"2024-10-10T20:17:45.277Z","updated_at":"2025-04-09T05:13:19.033Z","avatar_url":"https://github.com/wadackel.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![sweet-scroll](https://raw.githubusercontent.com/tsuyoshiwada/sweet-scroll/artwork/repo-banner.png)\n\n[![CircleCI Status](https://img.shields.io/circleci/project/github/tsuyoshiwada/sweet-scroll/master.svg?style=flat-square)](https://circleci.com/gh/tsuyoshiwada/sweet-scroll/)\n[![npm version](https://img.shields.io/npm/v/sweet-scroll.svg?style=flat-square)](https://www.npmjs.com/package/sweet-scroll)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/tsuyoshiwada/sweet-scroll/master/LICENSE)\n\n\u003e ECMAScript2015+ \u0026 TypeScript Friendly, dependency-free smooth scroll library.\n\n:lollipop: [See Demo](http://tsuyoshiwada.github.io/sweet-scroll/)\n\n## Features\n\n- Dependecy-free!!\n- ECMAScript2015+ \u0026 TypeScript friendly\n- Use `requestAnimationFrame` API\n- Supports vertical and horizontal scroll\n- Supports dynamic trigger (event delegation)\n- Supports container for the scroll\n- Supports many easing types\n- Supports server-side rendering (Can load without putting out errors.)\n\n## Migration Guide\n\nSee the [Migration Guide](./MIGRATION.md)\n\n## Table of Contents\n\n- [Usage](#usage)\n  - [1. Install](#1-install)\n  - [2. Setup of HTML](#2-setup-of-html)\n  - [3. Initialize SweetScroll](#3-initialize-sweetscroll)\n- [Options](#options)\n- [Easings](#easings)\n  - [Built-in (22)](#built-in-22)\n  - [Advanced (9)](#advanced-9)\n- [Customizing Tips](#customizing-tips)\n  - [Specifying container elements](#specifying-container-elements)\n  - [Specify fixed header](#specify-fixed-header)\n  - [Override of options for each element](#override-of-options-for-each-element)\n  - [If you want to use in non anchor element](#if-you-want-to-use-in-non-anchor-element)\n  - [Do you feel scrolling is slow?](#do-you-feel-scrolling-is-slow)\n  - [Scrolling animation in another page](#scrolling-animation-in-another-page)\n- [API](#api)\n  - [new SweetScroll(options?: PartialOptions, container?: string | Element)](#new-sweetscrolloptions-partialoptions-container-string--element--window)\n  - [SweetScroll.create(options?: PartialOptions, container?: string | Element)](#sweetscrollcreateoptions-partialoptions-container-string--element--window)\n  - [to(distance: any, options?: PartialOptions)](#todistance-any-options-partialoptions)\n  - [toTop(distance: any, options?: PartialOptions)](#totopdistance-any-options-partialoptions)\n  - [toLeft(distance: any, options?: PartialOptions)](#toleftdistance-any-options-partialoptions)\n  - [toElement(\\$el: Element, options?: PartialOptions)](#toelementel-element-options-partialoptions)\n  - [update(options: PartialOptions)](#updateoptions-partialoptions)\n  - [stop(gotoEnd: boolean = true)](#stopgotoend-boolean--true)\n  - [destroy()](#destroy)\n  - [Callbacks](#callbacks)\n- [Browser Support](#browser-support)\n  - [Scrolling with IE9](#scrolling-with-ie9)\n- [CHANGELOG](#changelog)\n- [Contibute](#contibute)\n  - [Development](#development)\n- [License](#license)\n\n## Usage\n\n### 1. Install\n\n#### via NPM\n\n```bash\n$ npm install sweet-scroll\n```\n\n##### use\n\n```typescript\nimport SweetScroll from 'sweet-scroll';\n```\n\n#### via MANUAL\n\n1. Download the [sweet-scroll.min.js](https://raw.githubusercontent.com/tsuyoshiwada/sweet-scroll/master/sweet-scroll.min.js)\n1. Load it in the script tag.\n\n```html\n\u003cscript src=\"sweet-scroll.min.js\"\u003e\u003c/script\u003e\n```\n\n#### via CDN (UNPKG)\n\n```html\n\u003cscript src=\"https://unpkg.com/sweet-scroll/sweet-scroll.min.js\"\u003e\u003c/script\u003e\n```\n\n### 2. Setup of HTML\n\n```html\n\u003ca href=\"#intro\" data-scroll\u003eGo to Introduction\u003c/a\u003e\n...\n\u003cdiv id=\"intro\"\u003eIntroduction\u003c/div\u003e\n```\n\n### 3. Initialize SweetScroll\n\nYou need to initialize an instance after `DOMContentLoaded`.\n\n```typescript\ndocument.addEventListener(\n  'DOMContentLoaded',\n  () =\u003e {\n    const scroller = new SweetScroll({\n      /* some options */\n    });\n  },\n  false,\n);\n```\n\n## Options\n\nThe following options are applied by default. It can be customized as needed.\n\n```typescript\n{\n  trigger: '[data-scroll]',       // Selector for trigger (must be a valid css selector)\n  header: '[data-scroll-header]', // Selector or Element for fixed header (Selector of must be a valid css selector)\n  duration: 1000,                 // Specifies animation duration in integer\n  easing: 'easeOutQuint',         // Specifies the pattern of easing\n  offset: 0,                      // Specifies the value to offset the scroll position in pixels\n  vertical: true,                 // Enable the vertical scroll\n  horizontal: false,              // Enable the horizontal scroll\n  cancellable: true,              // When fired wheel or touchstart events to stop scrolling\n  updateURL: false,               // Update the URL hash on after scroll (true | false | 'push' | 'replace')\n  preventDefault: true,           // Cancels the container element click event\n  stopPropagation: true,          // Prevents further propagation of the container element click event in the bubbling phase\n\n  // Callbacks\n  before: null,\n  after: null,\n  cancel: null,\n  complete: null,\n  step: null,\n}\n```\n\n## Easings\n\nSupports the following easing.\n\n### Built-in (22)\n\n- **Normal**\n  - `linear`\n- **Quad**\n  - `easeInQuad`\n  - `easeOutQuad`\n  - `easeInOutQuad`\n- **Cubic**\n  - `easeInCubic`\n  - `easeOutCubic`\n  - `easeInOutCubic`\n- **Quart**\n  - `easeInQuart`\n  - `easeOutQuart`\n  - `easeInOutQuart`\n- **Quint**\n  - `easeInQuint`\n  - `easeOutQuint` **(default)**\n  - `easeInOutQuint`\n- **Sine**\n  - `easeInSine`\n  - `easeOutSine`\n  - `easeInOutSine`\n- **Expo**\n  - `easeInExpo`\n  - `easeOutExpo`\n  - `easeInOutExpo`\n- **Circ**\n  - `easeInCirc`\n  - `easeOutCirc`\n  - `easeInOutCirc`\n\n### Advanced (9)\n\nEasing functions that are not built in can pass functions directly.\n\n```typescript\nconst scroller = new SweetScroll({\n  easing: advancedEasingFunction,\n});\n```\n\n#### Elastic\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eeaseInElastic\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nconst easeInElastic = (_, t, b, c, d) =\u003e {\n  let s = 1.70158;\n  let p = 0;\n  let a = c;\n  if (t === 0) return b;\n  if ((t /= d) === 1) return b + c;\n  if (!p) p = d * 0.3;\n  if (a \u003c Math.abs(c)) {\n    a = c;\n    s = p / 4;\n  } else {\n    s = (p / (2 * Math.PI)) * asin(c / a);\n  }\n  return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin(((t * d - s) * (2 * Math.PI)) / p)) + b;\n};\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eeaseOutElastic\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nconst easeOutElastic = (_, t, b, c, d) =\u003e {\n  let s = 1.70158;\n  let p = 0;\n  let a = c;\n  if (t === 0) return b;\n  if ((t /= d) === 1) return b + c;\n  if (!p) p = d * 0.3;\n  if (a \u003c Math.abs(c)) {\n    a = c;\n    s = p / 4;\n  } else {\n    s = (p / (2 * Math.PI)) * asin(c / a);\n  }\n  return a * Math.pow(2, -10 * t) * Math.sin(((t * d - s) * (2 * Math.PI)) / p) + c + b;\n};\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eeaseInOutElastic\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nconst easeInOutElastic = (_, t, b, c, d) =\u003e {\n  let s = 1.70158;\n  let p = 0;\n  let a = c;\n  if (t === 0) return b;\n  if ((t /= d / 2) === 2) return b + c;\n  if (!p) p = d * (0.3 * 1.5);\n  if (a \u003c Math.abs(c)) {\n    a = c;\n    s = p / 4;\n  } else {\n    s = (p / (2 * Math.PI)) * Math.asin(c / a);\n  }\n  if (t \u003c 1) {\n    return (\n      -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin(((t * d - s) * (2 * Math.PI)) / p)) + b\n    );\n  }\n  return (\n    a * Math.pow(2, -10 * (t -= 1)) * Math.sin(((t * d - s) * (2 * Math.PI)) / p) * 0.5 + c + b\n  );\n};\n```\n\n\u003c/details\u003e\n\n#### Back\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eeaseInBack\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nconst easeInBack = (_, t, b, c, d, s = 1.70158) =\u003e c * (t /= d) * t * ((s + 1) * t - s) + b;\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eeaseOutBack\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nconst easeOutBack = (_, t, b, c, d, s = 1.70158) =\u003e\n  c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eeaseInOutBack\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nconst easeInOutBack = (_, t, b, c, d, s = 1.70158) =\u003e\n  (t /= d / 2) \u003c 1\n    ? (c / 2) * (t * t * (((s *= 1.525) + 1) * t - s)) + b\n    : (c / 2) * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;\n```\n\n\u003c/details\u003e\n\n#### Bounce\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eeaseOutBounce\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nconst easeOutBounce = (_, t, b, c, d) =\u003e {\n  if ((t /= d) \u003c 1 / 2.75) {\n    return c * (7.5625 * t * t) + b;\n  } else if (t \u003c 2 / 2.75) {\n    return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b;\n  } else if (t \u003c 2.5 / 2.75) {\n    return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b;\n  }\n  return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b;\n};\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eeaseInBounce\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nconst easeOutBounce = (_, t, b, c, d) =\u003e {\n  if ((t /= d) \u003c 1 / 2.75) {\n    return c * (7.5625 * t * t) + b;\n  } else if (t \u003c 2 / 2.75) {\n    return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b;\n  } else if (t \u003c 2.5 / 2.75) {\n    return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b;\n  }\n  return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b;\n};\n\nconst easeInBounce = (x, t, b, c, d) =\u003e c - easeOutBounce(x, d - t, 0, c, d) + b;\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003ccode\u003eeaseInOutBounce\u003c/code\u003e\u003c/summary\u003e\n\n```typescript\nconst easeOutBounce = (_, t, b, c, d) =\u003e {\n  if ((t /= d) \u003c 1 / 2.75) {\n    return c * (7.5625 * t * t) + b;\n  } else if (t \u003c 2 / 2.75) {\n    return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b;\n  } else if (t \u003c 2.5 / 2.75) {\n    return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b;\n  }\n  return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b;\n};\n\nconst easeInBounce = (x, t, b, c, d) =\u003e c - easeOutBounce(x, d - t, 0, c, d) + b;\n\nconst easeInOutBounce = (x, t, b, c, d) =\u003e\n  t \u003c d / 2\n    ? easeInBounce(x, t * 2, 0, c, d) * 0.5 + b\n    : easeOutBounce(x, t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n```\n\n\u003c/details\u003e\n\n---\n\n[Live demo](http://tsuyoshiwada.github.io/sweet-scroll/easings.html)\n\n## Customizing Tips\n\n### Specifying container elements\n\nIn the following example we have specified in the container for scrolling the `#container`.\n\n```html\n\u003cdiv id=\"container\"\u003e\n  \u003ca href=\"#heading2\" data-scroll\u003eGo to Heading2\u003c/a\u003e\n  ...\n  \u003ch2 id=\"heading2\"\u003eHeading2\u003c/h2\u003e\n\u003c/div\u003e\n```\n\n```typescript\n// Specified in the CSS Selector\nconst scroller = new SweetScroll(\n  {\n    /* some options */\n  },\n  '#container',\n);\n\n// Specified in the Element\nconst scroller = new SweetScroll(\n  {\n    /* some options */\n  },\n  document.getElementById('container'),\n);\n```\n\n### Specify fixed header\n\nAdd the `data-scroll-header` attribute in order to offset the height of the fixed header.\n\n```html\n\u003cheader data-scroll-header\u003e\u003c/header\u003e\n```\n\nSpecify the CSS Selector in `header` option instead of the `data-scroll-header` attribute.\n\n```typescript\nconst scroller = new SweetScroll({\n  header: '#header',\n});\n```\n\n### Override of options for each element\n\nYou can override the default options by passing the option in `JSON` format to the `data-scroll-options`.\n\n```html\n\u003ca href=\"#target\" data-scroll data-scroll-options='{\"easing\": \"easeOutExpo\"}'\u003eGo to Target\u003c/a\u003e\n```\n\n### If you want to use in non anchor element\n\nWill use the data-scroll attribute instead of href.\n\n```html\n\u003cbutton type=\"button\" data-scroll=\"+=500\"\u003eScroll under 500px\u003c/button\u003e\n```\n\n### Scrolling animation in another page\n\nThe following, Introduce one of the mounting method.\n\n```typescript\ndocument.addEventListener(\n  'DOMContentLoaded',\n  () =\u003e {\n    const scroller = new SweetScroll();\n    const hash = window.location.hash;\n    const needsInitialScroll = document.getElementById(hash.substr(1)) != null;\n\n    if (needsInitialScroll) {\n      window.location.hash = '';\n    }\n\n    window.addEventListener(\n      'load',\n      () =\u003e {\n        if (needsInitialScroll) {\n          scroller.to(hash, { updateURL: 'replace' });\n        }\n      },\n      false,\n    );\n  },\n  false,\n);\n```\n\n[Live demo](http://tsuyoshiwada.github.io/sweet-scroll/initial-scroll.html#footer)\n\nYou can also achieve the same thing in other ways by using the provided API.\n\n## API\n\n### new SweetScroll(options?: PartialOptions, container?: string | Element | Window)\n\nWill generate a SweetScroll instance.\n\n**Example:**\n\n```typescript\nconst scroller = new SweetScroll(\n  {\n    duration: 1200,\n    easing: 'easeOutExpo',\n  },\n  '#container',\n);\n```\n\n### SweetScroll.create(options?: PartialOptions, container?: string | Element | Window)\n\nWill generate a SweetScroll instance. (factory method)\n\n**Example:**\n\n```typescript\nconst scroller = SweetScroll.create(\n  {\n    duration: 1200,\n    easing: 'easeOutExpo',\n  },\n  '#container',\n);\n```\n\n### to(distance: any, options?: PartialOptions)\n\nScroll animation to the specified `distance`.\n`distance` to can specify the CSS Selector or scroll position.\n\n**Example:**\n\n```typescript\nconst scroller = new SweetScroll();\n\n// CSS Selector of target element\nscroller.to('#footer');\n\n// Object\nscroller.to({ top: 1000, left: 20 });\n\n// Array (top:0, left:1000)\nscroller.to([0, 1000]);\n\n// Number (Priority to vertical scroll position. by default.)\nscroller.to(500);\n\n// String (Relative position)\nscroller.to('+=500');\nscroller.to('-=200');\n```\n\n### toTop(distance: any, options?: PartialOptions)\n\nVertical scroll animation to the specified `distance`.\n\n**Example:**\n\n```typescript\nscroller.toTop(0);\n```\n\n### toLeft(distance: any, options?: PartialOptions)\n\nHorizontal scroll animation to the specified `distance`.\n\n**Example:**\n\n```typescript\nscroller.toLeft(1500);\n```\n\n### toElement(\\$el: Element, options?: PartialOptions)\n\nScroll animation to the specified `Element`.\n\n**Example:**\n\n```typescript\nscroller.toElement(document.getElementById('content'));\n```\n\n### update(options: PartialOptions)\n\nWill update the SweetScroll instance.\nPrimarily used in the case of option update.\n\n**Example:**\n\n```typescript\nscroller.update({\n  trigger: 'a[href^=\"#\"]',\n  duration: 3000,\n});\n```\n\n### stop(gotoEnd: boolean = true)\n\n**gotoEnd: {Boolean}**\n\nWill stop the current scroll animation.\n\n**Example:**\n\n```typescript\nscroller.stop(true);\n```\n\n### destroy()\n\nWill destroy the SweetScroll instance.\nDisable of the method and event handler.\n\n**Example:**\n\n```typescript\nscroller.destroy();\n```\n\n### Callbacks\n\nIn `before` and `after`, you will pass the coordinates and the triggering element in the argument.\nIn addition, you can stop the scrolling by return a `before` in `false`.\n\n**Example:**\n\n```typescript\nconst scroller = new SweetScroll({\n  // Stop scrolling case of trigger element that contains the `is-disabled` class.\n  before: (offset: Offset, $trigger: Element | null, scroller: SweetScroll): boolean | void =\u003e {\n    console.log('Before!!', offset, scroller);\n    if ($trigger \u0026\u0026 $trigger.classList.contains('is-disabled')) {\n      return false;\n    }\n  },\n\n  // If the `wheel` or `touchstart` event is called\n  cancel: (scroller: SweetScroll): void =\u003e {\n    console.log('Cancel!!', scroller);\n  },\n\n  // Scroll animation is complete\n  after: (offset: Offset, $trigger: Element | null, scroller: SweetScroll): void =\u003e {\n    console.log('After!!', offset, $trigger, scroller);\n  },\n\n  // Scroll animation is complete (`after` or `cancel`)\n  complete: (isCancel: boolean, scroller: SweetScroll): void =\u003e {\n    console.log('Complete!!', isCancel, scroller);\n  },\n\n  // Each animation frame\n  step: (time: number, scroller: SweetScroll): void =\u003e {\n    console.log('step', time, scroller);\n  },\n});\n```\n\n**Extends Class:**\n\nThe following is a pattern to override a method in the inheritance destination class.\n\n```typescript\nimport SweetScroll, { Offset } from 'sweet-scroll';\n\nclass MyScroll extends SweetScroll {\n  protected onBefore(offset: Offset, $trigger: Element | null): boolean | void {\n    // Stop scrolling case of trigger element that contains the `is-disabled` class.\n    console.log('Before!!', offset);\n    if ($trigger \u0026\u0026 $trigger.classList.contains('is-disabled')) {\n      return false;\n    }\n  }\n\n  protected onCancel(): void {\n    console.log('Canell!!');\n  }\n\n  protected onAfter(offset: Offset, $trigger: Element | null): void {\n    console.log('After!!', offset, $trigger);\n  }\n\n  protected onComplete(isCancel: boolean): void {\n    console.log('Complete!!', isCancel);\n  }\n\n  protected onStep(time: number): void {\n    console.log('step', time);\n  }\n}\n```\n\n## Browser Support\n\nWorks in `IE10+`, and all modern browsers.\n\n### Scrolling with IE9\n\nIt is necessary to use [polyfill](https://gist.github.com/paulirish/1579671) or ponyfill of `requestAnimationFrame`.\n\n\u003cdetails\u003e\n  \u003csummary\u003eExample ponyfill\u003c/summary\u003e\n\nUsing [raf](https://github.com/chrisdickinson/raf) module.\n\n```typescript\nimport raf from 'raf';\nimport SweetScroll from 'sweet-scroll';\n\nSweetScroll.raf = raf;\nSweetScroll.caf = raf.cancel;\n```\n\n\u003c/details\u003e\n\n## CHANGELOG\n\nSee the [CHANGELOG.md](./CHANGELOG.md)\n\n## Contibute\n\n1. Fork it!\n1. Create your feature branch: `git checkout -b my-new-feature`\n1. Commit your changes: `git commit -am 'Add some feature'`\n1. Push to the branch: `git push origin my-new-feature`\n1. Submit a pull request :muscle:\n\nBugs, feature requests and comments are more than welcome in the [issues](https://github.com/tsuyoshiwada/sweet-scroll/issues).\n\n### Development\n\nWe will develop using the following npm scripts.\n\n#### `yarn start`\n\nLaunch the local server and let the demo run. Opening http://localhost:3000 in your browser.\n\n#### `yarn build`\n\nCompile TypeScript and create type definitions.\n\n#### `yarn test`\n\nRun unit testing with Jest.\n\n## License\n\n[MIT © tsuyoshiwada](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwadackel%2Fsweet-scroll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwadackel%2Fsweet-scroll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwadackel%2Fsweet-scroll/lists"}