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
[](https://travis-ci.org/sparanoid/lightense-images)
[](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
================================================
General Usage
Custom Background
Disable Lightense Images with Specific Class
Custom Padding
Custom Background
Custom Thumbnail Preview
Flexbox Gallery
Event Hooks
================================================
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'
})
]
};