Full Code of sparanoid/lightense-images for AI

master d51a1db9baab cached
18 files
51.6 KB
14.3k tokens
39 symbols
1 requests
Download .txt
Repository: sparanoid/lightense-images
Branch: master
Commit: d51a1db9baab
Files: 18
Total size: 51.6 KB

Directory structure:
gitextract_vkyqeos0/

├── .babelrc
├── .eslintrc.json
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── .huskyrc
├── .jshintrc
├── .npmrc
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── demo.html
├── dist/
│   └── lightense.js
├── package.json
├── renovate.json
├── src/
│   └── index.js
└── webpack.config.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc
================================================
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry",
        "corejs": "3"
      }
    ]
  ]
}


================================================
FILE: .eslintrc.json
================================================
{
    "env": {
        "browser": true,
        "commonjs": true,
        "es2021": true
    },
    "extends": "eslint:recommended",
    "parserOptions": {
        "ecmaVersion": 12
    },
    "rules": {
        "accessor-pairs": "error",
        "array-bracket-newline": "error",
        "array-bracket-spacing": [
            "error",
            "never"
        ],
        "array-callback-return": "error",
        "array-element-newline": "off",
        "arrow-body-style": "error",
        "arrow-parens": "error",
        "arrow-spacing": [
            "error",
            {
                "after": true,
                "before": true
            }
        ],
        "block-scoped-var": "error",
        "block-spacing": "error",
        "brace-style": [
            "error",
            "1tbs"
        ],
        "callback-return": "error",
        "camelcase": "off",
        "capitalized-comments": "off",
        "class-methods-use-this": "error",
        "comma-dangle": "error",
        "comma-spacing": [
            "error",
            {
                "after": true,
                "before": false
            }
        ],
        "comma-style": [
            "error",
            "last"
        ],
        "complexity": "error",
        "computed-property-spacing": [
            "error",
            "never"
        ],
        "consistent-return": "off",
        "consistent-this": "error",
        "curly": "error",
        "default-case": "off",
        "dot-location": "error",
        "dot-notation": "error",
        "eol-last": "error",
        "eqeqeq": "error",
        "func-call-spacing": "error",
        "func-name-matching": "error",
        "func-names": "off",
        "func-style": [
            "error",
            "declaration",
            {
                "allowArrowFunctions": true
            }
        ],
        "function-paren-newline": "error",
        "generator-star-spacing": "error",
        "global-require": "error",
        "guard-for-in": "error",
        "handle-callback-err": "error",
        "id-blacklist": "error",
        "id-length": "off",
        "id-match": "error",
        "implicit-arrow-linebreak": [
            "error",
            "beside"
        ],
        "indent": "off",
        "indent-legacy": "off",
        "init-declarations": "off",
        "jsx-quotes": "error",
        "key-spacing": "error",
        "keyword-spacing": "off",
        "line-comment-position": "error",
        "linebreak-style": [
            "error",
            "unix"
        ],
        "lines-around-comment": "error",
        "lines-around-directive": "error",
        "lines-between-class-members": "error",
        "max-classes-per-file": "error",
        "max-depth": "error",
        "max-len": "off",
        "max-lines": "off",
        "max-lines-per-function": "off",
        "max-nested-callbacks": "error",
        "max-params": "error",
        "max-statements": "off",
        "max-statements-per-line": "error",
        "multiline-comment-style": [
            "error",
            "separate-lines"
        ],
        "new-parens": "error",
        "newline-after-var": "off",
        "newline-before-return": "off",
        "newline-per-chained-call": "error",
        "no-alert": "error",
        "no-array-constructor": "error",
        "no-async-promise-executor": "error",
        "no-await-in-loop": "error",
        "no-bitwise": "off",
        "no-buffer-constructor": "error",
        "no-caller": "error",
        "no-catch-shadow": "error",
        "no-confusing-arrow": "error",
        "no-continue": "error",
        "no-div-regex": "error",
        "no-duplicate-imports": "error",
        "no-else-return": "error",
        "no-empty-function": "error",
        "no-eq-null": "error",
        "no-eval": "error",
        "no-extend-native": "error",
        "no-extra-bind": "error",
        "no-extra-label": "error",
        "no-extra-parens": "off",
        "no-floating-decimal": "error",
        "no-implicit-coercion": "error",
        "no-implicit-globals": "error",
        "no-implied-eval": "error",
        "no-inline-comments": "error",
        "no-inner-declarations": [
            "error",
            "functions"
        ],
        "no-invalid-this": "off",
        "no-iterator": "error",
        "no-label-var": "error",
        "no-labels": "error",
        "no-lone-blocks": "error",
        "no-lonely-if": "error",
        "no-loop-func": "error",
        "no-magic-numbers": "off",
        "no-misleading-character-class": "error",
        "no-mixed-operators": "off",
        "no-mixed-requires": "error",
        "no-multi-assign": "error",
        "no-multi-spaces": "off",
        "no-multi-str": "error",
        "no-multiple-empty-lines": "error",
        "no-native-reassign": "error",
        "no-negated-condition": "error",
        "no-negated-in-lhs": "error",
        "no-nested-ternary": "error",
        "no-new": "error",
        "no-new-func": "error",
        "no-new-object": "error",
        "no-new-require": "error",
        "no-new-wrappers": "error",
        "no-octal-escape": "error",
        "no-param-reassign": "error",
        "no-path-concat": "error",
        "no-plusplus": [
            "error",
            {
                "allowForLoopAfterthoughts": true
            }
        ],
        "no-process-env": "error",
        "no-process-exit": "error",
        "no-proto": "error",
        "no-prototype-builtins": "error",
        "no-restricted-globals": "error",
        "no-restricted-imports": "error",
        "no-restricted-modules": "error",
        "no-restricted-properties": "error",
        "no-restricted-syntax": "error",
        "no-return-assign": "error",
        "no-return-await": "error",
        "no-script-url": "error",
        "no-self-compare": "error",
        "no-sequences": "error",
        "no-shadow": "off",
        "no-shadow-restricted-names": "error",
        "no-spaced-func": "error",
        "no-sync": "error",
        "no-tabs": "error",
        "no-template-curly-in-string": "error",
        "no-ternary": "off",
        "no-throw-literal": "off",
        "no-trailing-spaces": "error",
        "no-undef-init": "error",
        "no-undefined": "error",
        "no-underscore-dangle": "error",
        "no-unmodified-loop-condition": "error",
        "no-unneeded-ternary": "error",
        "no-unused-expressions": "error",
        "no-use-before-define": "off",
        "no-useless-call": "error",
        "no-useless-computed-key": "error",
        "no-useless-concat": "error",
        "no-useless-constructor": "error",
        "no-useless-rename": "error",
        "no-useless-return": "error",
        "no-var": "off",
        "no-void": "error",
        "no-warning-comments": "off",
        "no-whitespace-before-property": "error",
        "no-with": "error",
        "nonblock-statement-body-position": "error",
        "object-curly-newline": "error",
        "object-curly-spacing": [
            "error",
            "never"
        ],
        "object-shorthand": "error",
        "one-var": "off",
        "one-var-declaration-per-line": "error",
        "operator-assignment": "error",
        "operator-linebreak": "error",
        "padded-blocks": "off",
        "padding-line-between-statements": "error",
        "prefer-arrow-callback": "off",
        "prefer-const": "error",
        "prefer-destructuring": "off",
        "prefer-numeric-literals": "error",
        "prefer-object-spread": "error",
        "prefer-promise-reject-errors": "error",
        "prefer-reflect": "error",
        "prefer-rest-params": "error",
        "prefer-spread": "error",
        "prefer-template": "off",
        "quote-props": "off",
        "quotes": [
            "error",
            "single"
        ],
        "radix": "error",
        "require-atomic-updates": "error",
        "require-await": "error",
        "require-jsdoc": "off",
        "require-unicode-regexp": "off",
        "rest-spread-spacing": [
            "error",
            "never"
        ],
        "semi": "error",
        "semi-spacing": [
            "error",
            {
                "after": true,
                "before": false
            }
        ],
        "semi-style": [
            "error",
            "last"
        ],
        "sort-imports": "error",
        "sort-keys": "off",
        "sort-vars": "error",
        "space-before-blocks": "off",
        "space-before-function-paren": "off",
        "space-in-parens": [
            "error",
            "never"
        ],
        "space-infix-ops": "error",
        "space-unary-ops": "error",
        "spaced-comment": [
            "error",
            "always"
        ],
        "strict": [
            "error",
            "function"
        ],
        "switch-colon-spacing": "error",
        "symbol-description": "error",
        "template-curly-spacing": [
            "error",
            "never"
        ],
        "template-tag-spacing": "error",
        "unicode-bom": [
            "error",
            "never"
        ],
        "valid-jsdoc": "error",
        "vars-on-top": "off",
        "wrap-iife": "error",
        "wrap-regex": "off",
        "yield-star-spacing": "error",
        "yoda": [
            "error",
            "never"
        ]
    }
}


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: [sparanoid]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
custom: https://sparanoid.com/donate/


================================================
FILE: .github/workflows/test.yml
================================================
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages

name: Test

on:
  push:
    branches:
      - '**'
    tags:
      - '**'
  pull_request:
    branches:
      - '**'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
      - run: yarn --frozen-lockfile
      - run: yarn test


================================================
FILE: .gitignore
================================================
# Numerous always-ignore extensions
*.diff
*.err
*.orig
*.log
*.rej
*.swo
*.swp
*.zip
*.vi
*~

# OS or Editor folders
.DS_Store
._*
Thumbs.db
.cache
.project
.settings
.tmproj
*.esproj
nbproject
*.sublime-project
*.sublime-workspace
.idea

# Folders to ignore
node_modules


================================================
FILE: .huskyrc
================================================
{
  "hooks": {
    "pre-commit": "yarn test && git add .",
    "pre-push": "yarn build"
  }
}


================================================
FILE: .jshintrc
================================================
{
  "esnext": true
}


================================================
FILE: .npmrc
================================================
message="chore(release): %s :tada:"


================================================
FILE: .travis.yml
================================================
sudo: false
language: node_js
node_js:
  - "10"
notifications:
  email: false
  slack:
    secure: P/ngpvqinM/t9tdXZO2qHQvq2XCkcerKM+KwNJlQoVHnkl/Z/EtzB1yxiZZ6LGdHp+r3nShBhfW+gJVojU80EObt0iWHbFTkUUMFf6WI6c056937CksQI4atmDBiCJxMAnkd6DCLWfBexVtKDhkc5vX0bYhgoiXEzCYUhFd8pZ4=


================================================
FILE: CHANGELOG.md
================================================
Deprecated. See GitHub releases for latest updates.

## [1.0.10](https://github.com/sparanoid/lightense-images/compare/v1.0.9...v1.0.10) (2020-07-16)


### Features

* **js:** native dark theme support via root-variables ([bfdd5c6](https://github.com/sparanoid/lightense-images/commit/bfdd5c605a8468e71cfc94818041e6938cdafdbd))



## [1.0.9](https://github.com/sparanoid/lightense-images/compare/v1.0.8...v1.0.9) (2019-09-01)


### Bug Fixes

* **css:** blur effect not supported corrently for chrome ([640acc9](https://github.com/sparanoid/lightense-images/commit/640acc968371092e990cae2662f7533df1615156))
* **js:** z-index too high, ref https://github.com/sparanoid/lightense-images/issues/41 ([a60342a](https://github.com/sparanoid/lightense-images/commit/a60342a4ea49b9c20fc0375ca939f9450630d617))


### Features

* update demo page ([5af3700](https://github.com/sparanoid/lightense-images/commit/5af3700caa047974a478d0eacae8563604ea7e88))



## [1.0.8](https://github.com/sparanoid/lightense-images/compare/v1.0.7...v1.0.8) (2019-02-20)


### Features

* **js:** use native css variables ([ea3fcc5](https://github.com/sparanoid/lightense-images/commit/ea3fcc51a1d2516c9910cc5be37dbdfb467927b8))



## [1.0.7](https://github.com/sparanoid/lightense-images/compare/v1.0.6...v1.0.7) (2019-02-19)



## [1.0.6](https://github.com/sparanoid/lightense-images/compare/v1.0.5...v1.0.6) (2018-12-09)


### Bug Fixes

* **js:** blurry images with transform, should fixes https://github.com/sparanoid/lightense-images/issues/31 ([1e318d9](https://github.com/sparanoid/lightense-images/commit/1e318d93f42270f89fcd429720292366f774a7a4))


### Features

* basic linting ([d7e0595](https://github.com/sparanoid/lightense-images/commit/d7e05954cfe17ca85834b52748e71c2b28bdce09))
* **js:** check if elements already inited, fixes https://github.com/sparanoid/lightense-images/issues/34 ([f2f0d84](https://github.com/sparanoid/lightense-images/commit/f2f0d841ccf59d4d47777e36d74099af17f30a2b))



## [1.0.5](https://github.com/sparanoid/lightense-images/compare/v1.0.4...v1.0.5) (2018-03-28)


### Bug Fixes

* missing fallback for deprecated  attribute ([0285b80](https://github.com/sparanoid/lightense-images/commit/0285b80c00174ae7dc751df7b918e8f72da870c7))


### Features

* better config inheritance, should fix https://github.com/sparanoid/lightense-images/issues/32 ([0d57306](https://github.com/sparanoid/lightense-images/commit/0d57306e0cc62a79a54147039a0301791f3c973a))
* generate Safari specific background color, automatically ([ae48d3b](https://github.com/sparanoid/lightense-images/commit/ae48d3bb888e7ff3227f3aad302e8f6d9c3ae610))



## [1.0.4](https://github.com/sparanoid/lightense-images/compare/v1.0.3...v1.0.4) (2017-03-13)


### Features

* smaller output ([143773d](https://github.com/sparanoid/lightense-images/commit/143773d69a377669530bd2d3e0e2ffa26c269ff0))



## [1.0.3](https://github.com/sparanoid/lightense-images/compare/v1.0.2...v1.0.3) (2017-01-17)


### Features

* allow passing string as target ([6608acc](https://github.com/sparanoid/lightense-images/commit/6608acc82397ff19201ed1763ec24ab90b9847dd))
* **demo:** add lazy load example ([1a16d81](https://github.com/sparanoid/lightense-images/commit/1a16d81b2da0bf0f653810ccd6a43fc0f7b891fc))
* **js:** allow select images, user should have the rights to select them ([7d24343](https://github.com/sparanoid/lightense-images/commit/7d243436fce23171a1393875b473dad322e4294a))



## [1.0.2](https://github.com/sparanoid/lightense-images/compare/v1.0.1...v1.0.2) (2016-12-21)


### Bug Fixes

* **js:** selectable `.lightense-wrap` causes zoom out not working in some area ([860d632](https://github.com/sparanoid/lightense-images/commit/860d632b73497ed37d33adf7894dea600557d17f))


### Features

* **js:** ability to override image padding ([bac3c4f](https://github.com/sparanoid/lightense-images/commit/bac3c4f664fb3daad30d3671e8f4e7c765a79654))
* **js:** avoid select images ([adf3a7e](https://github.com/sparanoid/lightense-images/commit/adf3a7ecdb8c572eed1a8f39b6e185653e4c152d))



## [1.0.1](https://github.com/sparanoid/lightense-images/compare/v1.0.0...v1.0.1) (2016-10-28)


### Bug Fixes

* missing timeout for Firefox to work ([b7ffebc](https://github.com/sparanoid/lightense-images/commit/b7ffebca240b2bc52291a5098357d3e3cef69ead))
* **docs:** wrong demo link ([91d663b](https://github.com/sparanoid/lightense-images/commit/91d663bacd0d6a28e21342d11d436c3a5823b148))
* **docs:** wrong dep check link [ci skip] ([c256f30](https://github.com/sparanoid/lightense-images/commit/c256f30c02c17ee6dda37fa8588d0f2c2587411c))
* **travis:** remove `0.12` support ([dcd3124](https://github.com/sparanoid/lightense-images/commit/dcd3124124ea2235c936213e5dff5da1ce859922))


### Features

* ability to toggle keyboard feature ([c1b9800](https://github.com/sparanoid/lightense-images/commit/c1b98002d5c0f401a67cba58f680e4909c9d1082))
* add `config.offset` support ([515fba7](https://github.com/sparanoid/lightense-images/commit/515fba73fdd0eb4d7b6682705bf0d99d075e412d))
* add demo page ([3924ac5](https://github.com/sparanoid/lightense-images/commit/3924ac51cb2d07a104d93a937b28bf8a70a0f1e9))
* add modifier keys support ([8a82ade](https://github.com/sparanoid/lightense-images/commit/8a82ade305f6af7e1daddbd8573b3f7cd418066a))
* add more options ([e0f994e](https://github.com/sparanoid/lightense-images/commit/e0f994e15c02b48171b643661efe3e1a1d70eb69))
* brand new effect as seen on Medium.com ([2323092](https://github.com/sparanoid/lightense-images/commit/23230929e50cba666c2e034064448890677a76e4))
* enable Travis CI ([644495f](https://github.com/sparanoid/lightense-images/commit/644495fe6f1413cff597f1b5480b647b4c113de3))
* handle user options ([9f5956d](https://github.com/sparanoid/lightense-images/commit/9f5956d88f0798b83e50465e402fabc41b5fe3c9))
* **docs:** add badges ([3e41f1b](https://github.com/sparanoid/lightense-images/commit/3e41f1b31059b891ffc8cdcb5e8b3dfc6c314d08))
* **docs:** add license ([6e960f6](https://github.com/sparanoid/lightense-images/commit/6e960f63b67f439d8d86c201f89158715cf6f379))



# [1.0.0](https://github.com/sparanoid/lightense-images/compare/1ade8c2f4c0afc745d37ec388234fab6397223b0...v1.0.0) (2016-03-11)


### Features

* init release ([1ade8c2](https://github.com/sparanoid/lightense-images/commit/1ade8c2f4c0afc745d37ec388234fab6397223b0))


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2021 Tunghsiao Liu

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# Lightense Images

[![Build Status](https://travis-ci.org/sparanoid/lightense-images.svg?branch=master)](https://travis-ci.org/sparanoid/lightense-images)
[![devDependency Status](https://david-dm.org/sparanoid/lightense-images/dev-status.svg?theme=shields.io)](https://david-dm.org/sparanoid/lightense-images?type=dev)

A dependency-free pure JavaScript image zooming library less than 2 KB (gzipped). Inspired by [tholman/intense-images](https://github.com/tholman/intense-images). You can play with the code [live on CodePen](http://codepen.io/sparanoid/pen/yOJyjV).

This library is mainly used by [Almace Scaffolding](https://github.com/sparanoid/almace-scaffolding).

-----

## [Getting Started](http://sparanoid.com/work/lightense-images/)

## Donate

Wanna buy me a cup of coffee? [Great](http://sparanoid.com/donate/).

## Author

**Tunghsiao Liu**

- Twitter: @[tunghsiao](http://twitter.com/tunghsiao)
- GitHub: @[sparanoid](http://github.com/sparanoid)

## License

MIT


================================================
FILE: demo.html
================================================
<!DOCTYPE html>

<link rel="stylesheet" href="https://unpkg.com/root-variables">

<style>
  @media (prefers-color-scheme: dark) {
    :root {
      --text-color-h: 213;
      --text-color-s: 32%;
      --text-color-l: 70%;

      --link-color-h: 202;
      --link-color-s: 100%;
      --link-color-l: 60%;

      --bg-color-h: 220;
      --bg-color-s: 10%;
      --bg-color-l: 12%;
    }
  }

  /* Basic styles */
  body {
    color: var(--text-color);
    background: var(--bg-color);
    padding: 1vw 2vw;
    font-family: "Helvetica Neue", Arial, sans-serif;
    text-align: center;
  }

  img {
    width: 300px;
  }

  a {
    color: var(--link-color);
    font-weight: 600;
  }

  h2 {
    margin-top: 2em;
  }

  .gallery {
    display: flex;
    flex-wrap: wrap;
  }

  .gallery > div {
    flex-grow: 1;
    margin: 0 .25rem .5rem;
    width: 30%;
  }

  /* Example: Lazy Lightense */
  .lightense-lazy {
    filter: blur(16px);
    transform: scale(1.2);
  }

  .lightense-lazy-wrap {
    position: relative;
    width: 300px;
    height: 115px;
    margin: 0 auto;
  }

  .lightense-lazy-thumb {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    opacity: 1;
    transition: opacity 1s ease;
  }

  .lightense-lazy-large {
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0;
    transition: opacity 1s ease;
  }

  .lightense-lazy-wrap.on .lightense-lazy-thumb {
    opacity: 0;
  }

  .lightense-lazy-wrap.on .lightense-lazy-large {
    opacity: 1;
  }
</style>

<h1>
  <a href="https://sparanoid.com/work/lightense-images/" target="_blank"
    >Lightense Images</a
  >
  by <a href="https://sparanoid.com/" target="_blank">Tunghsiao Liu</a>
</h1>

<h2>General Usage</h2>

<p>
  <img
    src="https://d349cztnlupsuf.cloudfront.net/girls_dead_monster_logo.png"
  />
</p>

<h2>Custom Background</h2>

<p>
  <img
    src="https://d349cztnlupsuf.cloudfront.net/railgun-logo.png"
    data-lightense-background="rgba(23, 29, 54, .8)"
  />
</p>

<h2>Disable Lightense Images with Specific Class</h2>

<p>
  <img
    src="https://d349cztnlupsuf.cloudfront.net/imouto-logo-large.png"
    class="no-lightense"
  />
</p>

<h2>Custom Padding</h2>

<p>
  <img
    src="https://d349cztnlupsuf.cloudfront.net/delicious.com-logo.png"
    data-lightense-padding="0"
  />
</p>

<h2>Custom Background</h2>

<p>
  <img
    src="https://d349cztnlupsuf.cloudfront.net/almace-scaffolding-text-vertical.svg"
    data-lightense-background="rgba(255, 1, 180, .2)"
  />
</p>

<h2>Custom Thumbnail Preview</h2>

<p>
  <img
    src="https://d349cztnlupsuf.cloudfront.net/tianjin-impression-brochure-03-thumb.jpg?test"
    data-original="https://d349cztnlupsuf.cloudfront.net/tianjin-impression-brochure-03.jpg"
    class="lightense-lazy"
  />
</p>

<h2>Flexbox Gallery</h2>

<div class="gallery">
  <div><img src="https://d349cztnlupsuf.cloudfront.net/girls_dead_monster_logo.png" /></div>
  <div><img src="https://d349cztnlupsuf.cloudfront.net/girls_dead_monster_logo.png" /></div>
  <div><img src="https://d349cztnlupsuf.cloudfront.net/girls_dead_monster_logo.png" /></div>
</div>

<h2>Event Hooks</h2>

<p>
  <img
    src="https://d349cztnlupsuf.cloudfront.net/girls_dead_monster_logo.png"
    before-show-alert="Showing!"
    after-show-alert="Showed!"
    before-hide-alert="Hiding!"
    after-hide-alert="Hidden!"
  />
</p>

<script src="dist/lightense.js"></script>

<script>
  // Init Lightense
  window.addEventListener("load", function() {
    Lightense("img:not(.no-lightense),.lightense", {

      // Example: Event Hooks
      beforeShow(config) {
        var beforeShowAttr = config.target.getAttribute("before-show-alert");
        beforeShowAttr && alert(beforeShowAttr);
      },
      afterShow(config) {
        var afterShowAttr = config.target.getAttribute("after-show-alert");
        afterShowAttr && alert(afterShowAttr);
      },
      beforeHide(config) {
        var beforeHideMessage = config.target.getAttribute("before-hide-alert");
        beforeHideMessage && alert(beforeHideMessage);
      },
      afterHide(config) {
        var afterHideMessage = config.target.getAttribute("after-hide-alert");
        afterHideMessage && alert(afterHideMessage);
      }
    });
  }, false);

  // Example: Lazy Lightense
  document.addEventListener("DOMContentLoaded", function(e) {
    function createDom(type, cssClass) {
      var div = document.createElement(type);
      div.className = cssClass;
      return div;
    }

    var thumb = document.querySelector(".lightense-lazy");
    var original = new Image();

    // Init wrapper
    var wrap = createDom("div", "lightense-lazy-wrap");
    thumb.parentNode.insertBefore(wrap, thumb);
    wrap.appendChild(thumb);

    // Wrap thumbnail
    var thumbWrap = createDom("div", "lightense-lazy-thumb");
    thumbWrap.appendChild(thumb);
    wrap.appendChild(thumbWrap);

    // Wrap original
    var originalWrap = createDom("div", "lightense-lazy-large");
    original.src = thumb.dataset.original;
    originalWrap.appendChild(original);
    wrap.appendChild(originalWrap);

    // Load original image
    original.addEventListener(
      "load",
      function() {
        wrap.classList.add("on");
      },
      false
    );
  });
</script>


================================================
FILE: dist/lightense.js
================================================
/*! lightense-images v1.0.17 | © Tunghsiao Liu | MIT */
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else if(typeof exports === 'object')
		exports["Lightense"] = factory();
	else
		root["Lightense"] = factory();
})(this, function() {
return /******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ 352:
/***/ ((module) => {

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

var Lightense = function Lightense() {
  'use strict'; // default options

  var defaults = {
    time: 300,
    padding: 40,
    offset: 40,
    keyboard: true,
    cubicBezier: 'cubic-bezier(.2, 0, .1, 1)',
    background: 'var(--bg-color-80, rgba(255, 255, 255, .98))',
    backgroundFilter: 'blur(30px)',
    zIndex: 1000000,

    /* eslint-disable no-undefined */
    beforeShow: undefined,
    afterShow: undefined,
    beforeHide: undefined,
    afterHide: undefined
    /* eslint-enable no-undefined  */

  }; // Init user options

  var config = {};

  function invokeCustomHook(methodName) {
    var method = config[methodName];

    if (!method) {
      return;
    }

    if (typeof method !== 'function') {
      throw "config.".concat(methodName, " must be a function!");
    }

    Reflect.apply(method, config, [config]);
  } // Init target elements


  var elements;

  function getElements(elements) {
    switch (_typeof(elements)) {
      case 'undefined':
        throw 'You need to pass an element!';

      case 'string':
        return document.querySelectorAll(elements);

      case 'object':
        return elements;
    }
  }

  function startTracking(passedElements) {
    // If passed an array of elements, assign tracking to all
    var len = passedElements.length;

    if (len) {
      // Loop and assign
      for (var i = 0; i < len; i++) {
        track(passedElements[i]);
      }
    } else {
      track(passedElements);
    }
  }

  function track(element) {
    if (element.src && !element.classList.contains('lightense-target')) {
      element.classList.add('lightense-target');
      element.addEventListener('click', function (event) {
        if (config.keyboard) {
          // If Command (macOS) or Ctrl (Windows) key pressed, stop processing
          // and open the image in a new tab
          if (event.metaKey || event.ctrlKey) {
            return window.open(element.src, '_blank');
          }
        } // Init instance


        init(this);
      }, false);
    }
  }

  function insertCss(styleId, styleContent) {
    var head = document.head || document.getElementsByTagName('head')[0]; // Remove existing instance

    if (document.getElementById(styleId)) {
      document.getElementById(styleId).remove();
    } // Create new instance


    var styleEl = document.createElement('style');
    styleEl.id = styleId; // Check if content exists

    if (styleEl.styleSheet) {
      styleEl.styleSheet.cssText = styleContent;
    } else {
      styleEl.appendChild(document.createTextNode(styleContent));
    }

    head.appendChild(styleEl);
  }

  function createDefaultCss() {
    var css = "\n:root {\n  --lightense-z-index: ".concat(config.zIndex - 1, ";\n  --lightense-backdrop: ").concat(config.background, ";\n  --lightense-backdrop-filter: ").concat(config.backgroundFilter, ";\n  --lightense-duration: ").concat(config.time, "ms;\n  --lightense-timing-func: ").concat(config.cubicBezier, ";\n}\n\n.lightense-backdrop {\n  box-sizing: border-box;\n  width: 100%;\n  height: 100%;\n  position: fixed;\n  top: 0;\n  left: 0;\n  overflow: hidden;\n  z-index: calc(var(--lightense-z-index) - 1);\n  padding: 0;\n  margin: 0;\n  transition: opacity var(--lightense-duration) ease;\n  cursor: zoom-out;\n  opacity: 0;\n  background-color: var(--lightense-backdrop);\n  visibility: hidden;\n}\n\n@supports (-webkit-backdrop-filter: blur(30px)) {\n  .lightense-backdrop {\n    background-color: var(--lightense-backdrop);\n    -webkit-backdrop-filter: var(--lightense-backdrop-filter);\n  }\n}\n\n@supports (backdrop-filter: blur(30px)) {\n  .lightense-backdrop {\n    background-color: var(--lightense-backdrop);\n    backdrop-filter: var(--lightense-backdrop-filter);\n  }\n}\n\n.lightense-wrap {\n  position: relative;\n  transition: transform var(--lightense-duration) var(--lightense-timing-func);\n  z-index: var(--lightense-z-index);\n  pointer-events: none;\n}\n\n.lightense-target {\n  cursor: zoom-in;\n  transition: transform var(--lightense-duration) var(--lightense-timing-func);\n  pointer-events: auto;\n}\n\n.lightense-open {\n  cursor: zoom-out;\n}\n\n.lightense-transitioning {\n  pointer-events: none;\n}");
    insertCss('lightense-images-css', css);
  }

  function createBackdrop() {
    if (document.querySelector('.lightense-backdrop') === null) {
      config.container = document.createElement('div');
      config.container.className = 'lightense-backdrop';
      document.body.appendChild(config.container);
    } else {
      config.container = document.querySelector('.lightense-backdrop');
    }
  }

  function createTransform(img) {
    // Get original image size
    var naturalWidth = img.width;
    var naturalHeight = img.height; // Calc zoom ratio

    var scrollTop = window.pageYOffset || document.documentElement.scrollTop || 0;
    var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || 0;
    var targetImage = config.target.getBoundingClientRect();
    var maxScaleFactor = naturalWidth / targetImage.width;
    var viewportWidth = window.innerWidth || document.documentElement.clientWidth || 0;
    var viewportHeight = window.innerHeight || document.documentElement.clientHeight || 0;
    var viewportPadding = config.target.getAttribute('data-lightense-padding') || config.target.getAttribute('data-padding') || config.padding;
    var viewportWidthOffset = viewportWidth > viewportPadding ? viewportWidth - viewportPadding : viewportWidth - defaults.padding;
    var viewportHeightOffset = viewportHeight > viewportPadding ? viewportHeight - viewportPadding : viewportHeight - defaults.padding;
    var imageRatio = naturalWidth / naturalHeight;
    var viewportRatio = viewportWidthOffset / viewportHeightOffset;

    if (naturalWidth < viewportWidthOffset && naturalHeight < viewportHeightOffset) {
      config.scaleFactor = maxScaleFactor;
    } else if (imageRatio < viewportRatio) {
      config.scaleFactor = viewportHeightOffset / naturalHeight * maxScaleFactor;
    } else {
      config.scaleFactor = viewportWidthOffset / naturalWidth * maxScaleFactor;
    } // Calc animation


    var viewportX = viewportWidth / 2;
    var viewportY = scrollTop + viewportHeight / 2;
    var imageCenterX = targetImage.left + scrollLeft + targetImage.width / 2;
    var imageCenterY = targetImage.top + scrollTop + targetImage.height / 2;
    config.translateX = Math.round(viewportX - imageCenterX);
    config.translateY = Math.round(viewportY - imageCenterY);
  }

  function createViewer() {
    config.target.classList.add('lightense-open'); // Create wrapper element

    config.wrap = document.createElement('div');
    config.wrap.className = 'lightense-wrap'; // Apply zoom ratio to target image

    setTimeout(function () {
      config.target.style.transform = 'scale(' + config.scaleFactor + ')';
    }, 20); // Apply animation to outer wrapper

    config.target.parentNode.insertBefore(config.wrap, config.target);
    config.wrap.appendChild(config.target);
    setTimeout(function () {
      config.wrap.style.transform = 'translate3d(' + config.translateX + 'px, ' + config.translateY + 'px, 0)';
    }, 20); // Show backdrop

    var item_options = {
      cubicBezier: config.target.getAttribute('data-lightense-cubic-bezier') || config.cubicBezier,
      background: config.target.getAttribute('data-lightense-background') || config.target.getAttribute('data-background') || config.background,
      zIndex: config.target.getAttribute('data-lightense-z-index') || config.zIndex
    }; // Create new config for item-specified styles

    var config_computed = _objectSpread(_objectSpread({}, config), item_options);

    var css = "\n    :root {\n      --lightense-z-index: ".concat(config_computed.zIndex - 1, ";\n      --lightense-backdrop: ").concat(config_computed.background, ";\n      --lightense-duration: ").concat(config_computed.time, "ms;\n      --lightense-timing-func: ").concat(config_computed.cubicBezier, ";\n    }");
    insertCss('lightense-images-css-computed', css);
    config.container.style.visibility = 'visible';
    setTimeout(function () {
      config.container.style.opacity = '1';
    }, 20);
  }

  function removeViewer() {
    invokeCustomHook('beforeHide');
    unbindEvents();
    config.target.classList.remove('lightense-open'); // Remove transform styles

    config.wrap.style.transform = '';
    config.target.style.transform = '';
    config.target.classList.add('lightense-transitioning'); // Fadeout backdrop

    config.container.style.opacity = ''; // Hide backdrop and remove target element wrapper

    setTimeout(function () {
      invokeCustomHook('afterHide');
      config.container.style.visibility = '';
      config.container.style.backgroundColor = '';
      config.wrap.parentNode.replaceChild(config.target, config.wrap);
      config.target.classList.remove('lightense-transitioning');
    }, config.time);
  }

  function checkViewer() {
    var scrollOffset = Math.abs(config.scrollY - window.scrollY);

    if (scrollOffset >= config.offset) {
      removeViewer();
    }
  }

  function once(target, event, handler) {
    target.addEventListener(event, function fn(args) {
      Reflect.apply(handler, this, args);
      target.removeEventListener(event, fn);
    });
  }

  function init(element) {
    config.target = element; // TODO: need refine
    // If element already openned, close it

    if (config.target.classList.contains('lightense-open')) {
      return removeViewer();
    }

    invokeCustomHook('beforeShow'); // Save current window scroll position for later use

    config.scrollY = window.scrollY;
    once(config.target, 'transitionend', function () {
      invokeCustomHook('afterShow');
    });
    var img = new Image();

    img.onload = function () {
      createTransform(this);
      createViewer();
      bindEvents();
    };

    img.src = config.target.src;
  }

  function bindEvents() {
    window.addEventListener('keyup', onKeyUp, false);
    window.addEventListener('scroll', checkViewer, false);
    config.container.addEventListener('click', removeViewer, false);
  }

  function unbindEvents() {
    window.removeEventListener('keyup', onKeyUp, false);
    window.removeEventListener('scroll', checkViewer, false);
    config.container.removeEventListener('click', removeViewer, false);
  } // Exit on excape (esc) key pressed


  function onKeyUp(event) {
    event.preventDefault();

    if (event.keyCode === 27) {
      removeViewer();
    }
  }

  function main(target) {
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    // Parse elements
    elements = getElements(target); // Parse user options

    config = _objectSpread(_objectSpread({}, defaults), options); // Prepare stylesheets

    createDefaultCss(); // Prepare backdrop element

    createBackdrop(); // Pass and prepare elements

    startTracking(elements);
  }

  return main;
};

var singleton = Lightense();
module.exports = singleton;

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	// This entry module is referenced by other modules so it can't be inlined
/******/ 	var __webpack_exports__ = __webpack_require__(352);
/******/ 	
/******/ 	return __webpack_exports__;
/******/ })()
;
});

================================================
FILE: package.json
================================================
{
  "name": "lightense-images",
  "version": "1.0.17",
  "description": "A dependency-free pure JavaScript image zooming library less than 2 KB (gzipped)",
  "main": "dist/lightense.js",
  "scripts": {
    "build": "webpack --progress --mode=production",
    "test": "yarn eslint src/index.js",
    "watch": "webpack --progress --watch --mode=development",
    "release": "release-it"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/sparanoid/lightense-images.git"
  },
  "publishConfig": {
    "registry": "https://registry.npmjs.org/"
  },
  "keywords": [
    "css",
    "image",
    "javascript",
    "webpack"
  ],
  "author": "Tunghsiao Liu",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/sparanoid/lightense-images/issues"
  },
  "homepage": "http://sparanoid.com/work/lightense-images/",
  "devDependencies": {
    "@babel/core": "^7.10.5",
    "@babel/preset-env": "^7.10.4",
    "babel-loader": "^8.1.0",
    "core-js": "^3.15.2",
    "eslint": "^8.0.0",
    "eslint-webpack-plugin": "^3.0.0",
    "husky": "^8.0.0",
    "release-it": "^15.0.0",
    "terser-webpack-plugin": "^5.1.4",
    "webpack": "^5.41.1",
    "webpack-cli": "^4.7.2"
  },
  "release-it": {
    "hooks": {
      "before:bump": [
        "yarn test"
      ],
      "after:bump": [
        "yarn build"
      ]
    },
    "github": {
      "release": true
    }
  }
}


================================================
FILE: renovate.json
================================================
{
  "extends": [
    "config:base",
    ":preserveSemverRanges"
  ]
}


================================================
FILE: src/index.js
================================================
const Lightense = () => {
  'use strict';

  // default options
  const defaults = {
    time: 300,
    padding: 40,
    offset: 40,
    keyboard: true,
    cubicBezier: 'cubic-bezier(.2, 0, .1, 1)',
    background: 'var(--bg-color-80, rgba(255, 255, 255, .98))',
    backgroundFilter: 'blur(30px)',
    zIndex: 1000000,
    /* eslint-disable no-undefined */
    beforeShow: undefined,
    afterShow: undefined,
    beforeHide: undefined,
    afterHide: undefined
    /* eslint-enable no-undefined  */
  };
  // Init user options
  var config = {};

  function invokeCustomHook(methodName) {
    const method = config[methodName];

    if (!method) {
      return;
    }

    if (typeof method !== 'function') {
      throw `config.${methodName} must be a function!`;
    }

    Reflect.apply(method, config, [config]);
  }

  // Init target elements
  var elements;

  function getElements(elements) {
    switch (typeof elements) {
      case 'undefined':
        throw 'You need to pass an element!';

      case 'string':
        return document.querySelectorAll(elements);

      case 'object':
        return elements;
    }
  }

  function startTracking(passedElements) {
    // If passed an array of elements, assign tracking to all
    var len = passedElements.length;
    if (len) {
      // Loop and assign
      for (var i = 0; i < len; i++) {
        track(passedElements[i]);
      }
    } else {
      track(passedElements);
    }
  }

  function track(element) {
    if (element.src && !element.classList.contains('lightense-target')) {
      element.classList.add('lightense-target');
      element.addEventListener(
        'click',
        function(event) {
          if (config.keyboard) {
            // If Command (macOS) or Ctrl (Windows) key pressed, stop processing
            // and open the image in a new tab
            if (event.metaKey || event.ctrlKey) {
              return window.open(element.src, '_blank');
            }
          }

          // Init instance
          init(this);
        },
        false
      );
    }
  }

  function insertCss(styleId, styleContent) {
    var head = document.head || document.getElementsByTagName('head')[0];

    // Remove existing instance
    if (document.getElementById(styleId)) {
      document.getElementById(styleId).remove();
    }

    // Create new instance
    var styleEl = document.createElement('style');
    styleEl.id = styleId;

    // Check if content exists
    if (styleEl.styleSheet) {
      styleEl.styleSheet.cssText = styleContent;
    } else {
      styleEl.appendChild(document.createTextNode(styleContent));
    }
    head.appendChild(styleEl);
  }

  function createDefaultCss() {
    var css = `
:root {
  --lightense-z-index: ${config.zIndex - 1};
  --lightense-backdrop: ${config.background};
  --lightense-backdrop-filter: ${config.backgroundFilter};
  --lightense-duration: ${config.time}ms;
  --lightense-timing-func: ${config.cubicBezier};
}

.lightense-backdrop {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  overflow: hidden;
  z-index: calc(var(--lightense-z-index) - 1);
  padding: 0;
  margin: 0;
  transition: opacity var(--lightense-duration) ease;
  cursor: zoom-out;
  opacity: 0;
  background-color: var(--lightense-backdrop);
  visibility: hidden;
}

@supports (-webkit-backdrop-filter: blur(30px)) {
  .lightense-backdrop {
    background-color: var(--lightense-backdrop);
    -webkit-backdrop-filter: var(--lightense-backdrop-filter);
  }
}

@supports (backdrop-filter: blur(30px)) {
  .lightense-backdrop {
    background-color: var(--lightense-backdrop);
    backdrop-filter: var(--lightense-backdrop-filter);
  }
}

.lightense-wrap {
  position: relative;
  transition: transform var(--lightense-duration) var(--lightense-timing-func);
  z-index: var(--lightense-z-index);
  pointer-events: none;
}

.lightense-target {
  cursor: zoom-in;
  transition: transform var(--lightense-duration) var(--lightense-timing-func);
  pointer-events: auto;
}

.lightense-open {
  cursor: zoom-out;
}

.lightense-transitioning {
  pointer-events: none;
}`;
    insertCss('lightense-images-css', css);
  }

  function createBackdrop() {
    if (document.querySelector('.lightense-backdrop') === null) {
      config.container = document.createElement('div');
      config.container.className = 'lightense-backdrop';
      document.body.appendChild(config.container);
    } else {
      config.container = document.querySelector('.lightense-backdrop');
    }
  }

  function createTransform(img) {
    // Get original image size
    var naturalWidth = img.width;
    var naturalHeight = img.height;

    // Calc zoom ratio
    var scrollTop = window.pageYOffset || document.documentElement.scrollTop || 0;
    var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || 0;
    var targetImage = config.target.getBoundingClientRect();
    var maxScaleFactor = naturalWidth / targetImage.width;
    var viewportWidth = window.innerWidth || document.documentElement.clientWidth || 0;
    var viewportHeight = window.innerHeight || document.documentElement.clientHeight || 0;
    var viewportPadding =
      config.target.getAttribute('data-lightense-padding') ||
      config.target.getAttribute('data-padding') ||
      config.padding;
    var viewportWidthOffset =
      viewportWidth > viewportPadding
        ? viewportWidth - viewportPadding
        : viewportWidth - defaults.padding;
    var viewportHeightOffset =
      viewportHeight > viewportPadding
        ? viewportHeight - viewportPadding
        : viewportHeight - defaults.padding;
    var imageRatio = naturalWidth / naturalHeight;
    var viewportRatio = viewportWidthOffset / viewportHeightOffset;

    if (
      naturalWidth < viewportWidthOffset &&
      naturalHeight < viewportHeightOffset
    ) {
      config.scaleFactor = maxScaleFactor;
    } else if (imageRatio < viewportRatio) {
      config.scaleFactor =
        (viewportHeightOffset / naturalHeight) * maxScaleFactor;
    } else {
      config.scaleFactor =
        (viewportWidthOffset / naturalWidth) * maxScaleFactor;
    }

    // Calc animation
    var viewportX = viewportWidth / 2;
    var viewportY = scrollTop + viewportHeight / 2;
    var imageCenterX = targetImage.left + scrollLeft + targetImage.width / 2;
    var imageCenterY = targetImage.top + scrollTop + targetImage.height / 2;

    config.translateX = Math.round(viewportX - imageCenterX);
    config.translateY = Math.round(viewportY - imageCenterY);
  }

  function createViewer() {
    config.target.classList.add('lightense-open');

    // Create wrapper element
    config.wrap = document.createElement('div');
    config.wrap.className = 'lightense-wrap';

    // Apply zoom ratio to target image
    setTimeout(function() {
      config.target.style.transform = 'scale(' + config.scaleFactor + ')';
    }, 20);

    // Apply animation to outer wrapper
    config.target.parentNode.insertBefore(config.wrap, config.target);
    config.wrap.appendChild(config.target);
    setTimeout(function() {
      config.wrap.style.transform =
        'translate3d(' +
        config.translateX +
        'px, ' +
        config.translateY +
        'px, 0)';
    }, 20);

    // Show backdrop
    var item_options = {
      cubicBezier:
        config.target.getAttribute('data-lightense-cubic-bezier') ||
        config.cubicBezier,
      background:
        config.target.getAttribute('data-lightense-background') ||
        config.target.getAttribute('data-background') ||
        config.background,
      zIndex:
        config.target.getAttribute('data-lightense-z-index') || config.zIndex
    };

    // Create new config for item-specified styles
    var config_computed = {...config, ...item_options};

    var css = `
    :root {
      --lightense-z-index: ${config_computed.zIndex - 1};
      --lightense-backdrop: ${config_computed.background};
      --lightense-duration: ${config_computed.time}ms;
      --lightense-timing-func: ${config_computed.cubicBezier};
    }`;
    insertCss('lightense-images-css-computed', css);

    config.container.style.visibility = 'visible';
    setTimeout(function() {
      config.container.style.opacity = '1';
    }, 20);
  }

  function removeViewer() {
    invokeCustomHook('beforeHide');
    unbindEvents();

    config.target.classList.remove('lightense-open');

    // Remove transform styles
    config.wrap.style.transform = '';
    config.target.style.transform = '';
    config.target.classList.add('lightense-transitioning');

    // Fadeout backdrop
    config.container.style.opacity = '';

    // Hide backdrop and remove target element wrapper
    setTimeout(function() {
      invokeCustomHook('afterHide');
      config.container.style.visibility = '';
      config.container.style.backgroundColor = '';
      config.wrap.parentNode.replaceChild(config.target, config.wrap);
      config.target.classList.remove('lightense-transitioning');
    }, config.time);
  }

  function checkViewer() {
    var scrollOffset = Math.abs(config.scrollY - window.scrollY);
    if (scrollOffset >= config.offset) {
      removeViewer();
    }
  }

  function once(target, event, handler) {
    target.addEventListener(event, function fn(args) {
      Reflect.apply(handler, this, args);

      target.removeEventListener(event, fn);
    });
  }

  function init(element) {
    config.target = element;

    // TODO: need refine
    // If element already openned, close it
    if (config.target.classList.contains('lightense-open')) {
      return removeViewer();
    }

    invokeCustomHook('beforeShow');

    // Save current window scroll position for later use
    config.scrollY = window.scrollY;

    once(config.target, 'transitionend', function() {
      invokeCustomHook('afterShow');
    });

    var img = new Image();
    img.onload = function() {
      createTransform(this);
      createViewer();
      bindEvents();
    };

    img.src = config.target.src;
  }

  function bindEvents() {
    window.addEventListener('keyup', onKeyUp, false);
    window.addEventListener('scroll', checkViewer, false);
    config.container.addEventListener('click', removeViewer, false);
  }

  function unbindEvents() {
    window.removeEventListener('keyup', onKeyUp, false);
    window.removeEventListener('scroll', checkViewer, false);
    config.container.removeEventListener('click', removeViewer, false);
  }

  // Exit on excape (esc) key pressed
  function onKeyUp(event) {
    event.preventDefault();
    if (event.keyCode === 27) {
      removeViewer();
    }
  }

  function main(target, options = {}) {
    // Parse elements
    elements = getElements(target);

    // Parse user options
    config = {...defaults, ...options};

    // Prepare stylesheets
    createDefaultCss();

    // Prepare backdrop element
    createBackdrop();

    // Pass and prepare elements
    startTracking(elements);
  }

  return main;
};

const singleton = Lightense();

module.exports = singleton;


================================================
FILE: webpack.config.js
================================================
const webpack = require('webpack');
const path = require('path');
const pkg = require('./package.json');
const banner = `/*! ${ pkg.name } v${ pkg.version } | © ${ pkg.author } | ${ pkg.license } */`;
const ESLintPlugin = require('eslint-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");

module.exports = {
  entry: {
    './dist/lightense': './src/index.js',
    './dist/lightense.min': './src/index.js',
  },
  output: {
    path: path.resolve(__dirname, './'),
    filename: '[name].js',
    libraryTarget: 'umd',
    library: 'Lightense',
    globalObject: 'this',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        enforce: 'pre',
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          },
        },
      }
    ]
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        include: /\.min\.js$/,
        parallel: true,
        extractComments: false,
      })
    ]
  },
  plugins: [
    new webpack.BannerPlugin({
      banner: banner,
      raw: true,
      entryOnly: true
    }),
    new ESLintPlugin({
      extensions: 'js'
    })
  ]
};
Download .txt
gitextract_vkyqeos0/

├── .babelrc
├── .eslintrc.json
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── .huskyrc
├── .jshintrc
├── .npmrc
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── demo.html
├── dist/
│   └── lightense.js
├── package.json
├── renovate.json
├── src/
│   └── index.js
└── webpack.config.js
Download .txt
SYMBOL INDEX (39 symbols across 2 files)

FILE: dist/lightense.js
  function ownKeys (line 18) | function ownKeys(object, enumerableOnly) { var keys = Object.keys(object...
  function _objectSpread (line 20) | function _objectSpread(target) { for (var i = 1; i < arguments.length; i...
  function _defineProperty (line 22) | function _defineProperty(obj, key, value) { if (key in obj) { Object.def...
  function _typeof (line 24) | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol ===...
  function invokeCustomHook (line 50) | function invokeCustomHook(methodName) {
  function getElements (line 67) | function getElements(elements) {
  function startTracking (line 80) | function startTracking(passedElements) {
  function track (line 94) | function track(element) {
  function insertCss (line 112) | function insertCss(styleId, styleContent) {
  function createDefaultCss (line 132) | function createDefaultCss() {
  function createBackdrop (line 137) | function createBackdrop() {
  function createTransform (line 147) | function createTransform(img) {
  function createViewer (line 181) | function createViewer() {
  function removeViewer (line 213) | function removeViewer() {
  function checkViewer (line 233) | function checkViewer() {
  function once (line 241) | function once(target, event, handler) {
  function init (line 248) | function init(element) {
  function bindEvents (line 273) | function bindEvents() {
  function unbindEvents (line 279) | function unbindEvents() {
  function onKeyUp (line 286) | function onKeyUp(event) {
  function main (line 294) | function main(target) {
  function __webpack_require__ (line 322) | function __webpack_require__(moduleId) {

FILE: src/index.js
  function invokeCustomHook (line 24) | function invokeCustomHook(methodName) {
  function getElements (line 41) | function getElements(elements) {
  function startTracking (line 54) | function startTracking(passedElements) {
  function track (line 67) | function track(element) {
  function insertCss (line 89) | function insertCss(styleId, styleContent) {
  function createDefaultCss (line 110) | function createDefaultCss() {
  function createBackdrop (line 175) | function createBackdrop() {
  function createTransform (line 185) | function createTransform(img) {
  function createViewer (line 235) | function createViewer() {
  function removeViewer (line 290) | function removeViewer() {
  function checkViewer (line 314) | function checkViewer() {
  function once (line 321) | function once(target, event, handler) {
  function init (line 329) | function init(element) {
  function bindEvents (line 357) | function bindEvents() {
  function unbindEvents (line 363) | function unbindEvents() {
  function onKeyUp (line 370) | function onKeyUp(event) {
  function main (line 377) | function main(target, options = {}) {
Condensed preview — 18 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (57K chars).
[
  {
    "path": ".babelrc",
    "chars": 132,
    "preview": "{\n  \"presets\": [\n    [\n      \"@babel/preset-env\",\n      {\n        \"useBuiltIns\": \"entry\",\n        \"corejs\": \"3\"\n      }\n"
  },
  {
    "path": ".eslintrc.json",
    "chars": 9328,
    "preview": "{\n    \"env\": {\n        \"browser\": true,\n        \"commonjs\": true,\n        \"es2021\": true\n    },\n    \"extends\": \"eslint:r"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 353,
    "preview": "# These are supported funding model platforms\n\ngithub: [sparanoid]\npatreon: # Replace with a single Patreon username\nope"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 573,
    "preview": "# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created\n# For "
  },
  {
    "path": ".gitignore",
    "chars": 273,
    "preview": "# Numerous always-ignore extensions\n*.diff\n*.err\n*.orig\n*.log\n*.rej\n*.swo\n*.swp\n*.zip\n*.vi\n*~\n\n# OS or Editor folders\n.D"
  },
  {
    "path": ".huskyrc",
    "chars": 94,
    "preview": "{\n  \"hooks\": {\n    \"pre-commit\": \"yarn test && git add .\",\n    \"pre-push\": \"yarn build\"\n  }\n}\n"
  },
  {
    "path": ".jshintrc",
    "chars": 21,
    "preview": "{\n  \"esnext\": true\n}\n"
  },
  {
    "path": ".npmrc",
    "chars": 36,
    "preview": "message=\"chore(release): %s :tada:\"\n"
  },
  {
    "path": ".travis.yml",
    "chars": 272,
    "preview": "sudo: false\nlanguage: node_js\nnode_js:\n  - \"10\"\nnotifications:\n  email: false\n  slack:\n    secure: P/ngpvqinM/t9tdXZO2qH"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 6356,
    "preview": "Deprecated. See GitHub releases for latest updates.\n\n## [1.0.10](https://github.com/sparanoid/lightense-images/compare/v"
  },
  {
    "path": "LICENSE",
    "chars": 1080,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2021 Tunghsiao Liu\n\nPermission is hereby granted, free of charge, to any person obt"
  },
  {
    "path": "README.md",
    "chars": 983,
    "preview": "# Lightense Images\n\n[![Build Status](https://travis-ci.org/sparanoid/lightense-images.svg?branch=master)](https://travis"
  },
  {
    "path": "demo.html",
    "chars": 5253,
    "preview": "<!DOCTYPE html>\n\n<link rel=\"stylesheet\" href=\"https://unpkg.com/root-variables\">\n\n<style>\n  @media (prefers-color-scheme"
  },
  {
    "path": "dist/lightense.js",
    "chars": 14359,
    "preview": "/*! lightense-images v1.0.17 | © Tunghsiao Liu | MIT */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif("
  },
  {
    "path": "package.json",
    "chars": 1392,
    "preview": "{\n  \"name\": \"lightense-images\",\n  \"version\": \"1.0.17\",\n  \"description\": \"A dependency-free pure JavaScript image zooming"
  },
  {
    "path": "renovate.json",
    "chars": 70,
    "preview": "{\n  \"extends\": [\n    \"config:base\",\n    \":preserveSemverRanges\"\n  ]\n}\n"
  },
  {
    "path": "src/index.js",
    "chars": 11021,
    "preview": "const Lightense = () => {\n  'use strict';\n\n  // default options\n  const defaults = {\n    time: 300,\n    padding: 40,\n   "
  },
  {
    "path": "webpack.config.js",
    "chars": 1227,
    "preview": "const webpack = require('webpack');\nconst path = require('path');\nconst pkg = require('./package.json');\nconst banner = "
  }
]

About this extraction

This page contains the full source code of the sparanoid/lightense-images GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 18 files (51.6 KB), approximately 14.3k tokens, and a symbol index with 39 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!