(null);
208 |
209 | return { renderViewer, maximize: _onClick, triggered, transform, loaded, onLoad: _onLoad, imgRef };
210 | }
211 |
212 | function ReactIntense(props: Props) {
213 | const {
214 | className,
215 | renderLoader = () => ,
216 | src,
217 | thumbnailSrc,
218 | vertical,
219 | caption,
220 | title,
221 | } = props;
222 | const { triggered, transform, loaded, onLoad, maximize, imgRef } = useIntenseMaximize(props);
223 |
224 | function renderViewer() {
225 | const transformStyle = {
226 | height: vertical ? '' : window.innerHeight,
227 | MozTransform: transform,
228 | transform: transform,
229 | WebkitTransform: transform,
230 | width: vertical ? window.innerWidth : '',
231 | };
232 |
233 | return triggered ? (
234 |
235 |
236 |
237 | {title}
238 | {caption}
239 |
240 |
241 | ) : null;
242 | }
243 |
244 | return (
245 |
246 |
251 | {triggered ? renderLoader() : null}
252 |
253 | {renderViewer()}
254 |
255 | );
256 | }
257 |
258 | export default ReactIntense;
259 |
--------------------------------------------------------------------------------
/lib/polyfills.js:
--------------------------------------------------------------------------------
1 | // https://gist.github.com/paulirish/1579671
2 | (function () {
3 | var lastTime = 0;
4 | var vendors = ['ms', 'moz', 'webkit', 'o'];
5 | for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
6 | window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
7 | window.cancelAnimationFrame =
8 | window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
9 | }
10 |
11 | if (!window.requestAnimationFrame)
12 | window.requestAnimationFrame = function (callback, element) {
13 | var currTime = new Date().getTime();
14 | var timeToCall = Math.max(0, 16 - (currTime - lastTime));
15 | var id = window.setTimeout(function () {
16 | callback(currTime + timeToCall);
17 | }, timeToCall);
18 | lastTime = currTime + timeToCall;
19 | return id;
20 | };
21 |
22 | if (!window.cancelAnimationFrame)
23 | window.cancelAnimationFrame = function (id) {
24 | clearTimeout(id);
25 | };
26 | })();
27 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-intense",
3 | "version": "0.2.2",
4 | "description": "A React port of the javascript full-size image viewer",
5 | "scripts": {
6 | "build": "parcel build src/index.html --dist-dir public",
7 | "build-lib": "rm -rf dist && babel --extensions .tsx lib --out-dir dist --copy-files",
8 | "start": "parcel src/index.html --dist-dir public",
9 | "lint": "npx prettier src lib --write"
10 | },
11 | "main": "dist/ReactIntense.js",
12 | "keywords": [
13 | "react",
14 | "component",
15 | "intense",
16 | "react-intense",
17 | "intense-images",
18 | "image",
19 | "images",
20 | "full-size",
21 | "full-screen"
22 | ],
23 | "repository": {
24 | "type": "git",
25 | "url": "https://github.com/brycedorn/react-intense"
26 | },
27 | "author": {
28 | "name": "Bryce Dorn",
29 | "email": "brycedorn@gmail.com",
30 | "url": "https://www.bryce.io"
31 | },
32 | "license": "MIT",
33 | "bugs": {
34 | "url": "https://github.com/brycedorn/react-intense/issues"
35 | },
36 | "homepage": "https://bryce.io/react-intense",
37 | "devDependencies": {
38 | "@babel/cli": "^7.23.0",
39 | "@babel/core": "^7.23.2",
40 | "@babel/plugin-transform-modules-commonjs": "^7.23.0",
41 | "@babel/preset-env": "^7.23.2",
42 | "@babel/preset-react": "^7.22.15",
43 | "@babel/preset-typescript": "^7.23.2",
44 | "@parcel/css": "^1.9.0",
45 | "@types/react": "^18.2.37",
46 | "@types/react-dom": "^18.2.15",
47 | "@parcel/transformer-css": "^2.10.2",
48 | "babel-preset-minify": "^0.5.2",
49 | "parcel": "^2.6.0",
50 | "prettier": "3.0.3",
51 | "process": "^0.11.10"
52 | },
53 | "optionalDependencies": {
54 | "@parcel/watcher-linux-x64-glibc": "2.2.0"
55 | },
56 | "targets": {
57 | "main": false
58 | },
59 | "dependencies": {
60 | "react": "^18.2.0",
61 | "react-dom": "^18.2.0"
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brycedorn/react-intense/a604104619b8d3eab7eb27829cfdce753052e1df/src/img/favicon.png
--------------------------------------------------------------------------------
/src/img/horse.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brycedorn/react-intense/a604104619b8d3eab7eb27829cfdce753052e1df/src/img/horse.jpg
--------------------------------------------------------------------------------
/src/img/horse_thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brycedorn/react-intense/a604104619b8d3eab7eb27829cfdce753052e1df/src/img/horse_thumb.jpg
--------------------------------------------------------------------------------
/src/img/rain.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brycedorn/react-intense/a604104619b8d3eab7eb27829cfdce753052e1df/src/img/rain.jpg
--------------------------------------------------------------------------------
/src/img/rain_thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brycedorn/react-intense/a604104619b8d3eab7eb27829cfdce753052e1df/src/img/rain_thumb.jpg
--------------------------------------------------------------------------------
/src/img/temple.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brycedorn/react-intense/a604104619b8d3eab7eb27829cfdce753052e1df/src/img/temple.jpg
--------------------------------------------------------------------------------
/src/img/temple_thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brycedorn/react-intense/a604104619b8d3eab7eb27829cfdce753052e1df/src/img/temple_thumb.jpg
--------------------------------------------------------------------------------
/src/index.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.jpg';
2 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | bryce.io - Intense Images
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
47 |
48 |
56 |
57 |
58 |
69 |
70 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createRoot } from 'react-dom/client';
3 | import ReactIntense, { useIntenseMaximize } from '../dist/ReactIntense';
4 | import '../dist/polyfills';
5 | // for local dev, use the following instead:
6 | // import ReactIntense, { useIntenseMaximize } from '../lib/ReactIntense';
7 | // import '../lib/polyfills';
8 |
9 | import horse from './img/horse.jpg';
10 | import horse_thumb from './img/horse_thumb.jpg';
11 | import rain from './img/rain.jpg';
12 | import rain_thumb from './img/rain_thumb.jpg';
13 | import temple from './img/temple.jpg';
14 | import temple_thumb from './img/temple_thumb.jpg';
15 |
16 | const images = [
17 | {
18 | caption: 'An annual month-long festival in Kyoto',
19 | className: 'demo-image first',
20 | src: horse,
21 | thumbnailSrc: horse_thumb,
22 | title: 'Gion Matsuri',
23 | },
24 | {
25 | caption: 'Umbrellas are key!',
26 | className: 'demo-image second',
27 | src: rain,
28 | thumbnailSrc: rain_thumb,
29 | title: 'Rainy rain',
30 | vertical: true,
31 | },
32 | {
33 | caption: 'Ancient Buddhist temple on a cliff',
34 | className: 'demo-image third',
35 | src: temple,
36 | thumbnailSrc: temple_thumb,
37 | title: 'Kiyomizu-dera',
38 | },
39 | ];
40 |
41 | function HookDemo() {
42 | const { maximize, renderViewer, triggered } = useIntenseMaximize(images[0]);
43 |
44 | return (
45 | <>
46 |
49 | {renderViewer()}
50 | >
51 | );
52 | }
53 |
54 | function IntenseDemos() {
55 | return (
56 | <>
57 |
58 | {images.map(({ caption, className, src, thumbnailSrc, title, vertical }) => (
59 |
68 | ))}
69 |
70 |
71 | >
72 | );
73 | }
74 |
75 | const element = document.getElementById('demos');
76 | if (element) {
77 | const root = createRoot(element);
78 | root.render();
79 | }
80 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | @import '../dist/ReactIntense.css';
2 |
3 | * {
4 | -webkit-font-smoothing: antialiased;
5 | -moz-box-sizing: border-box;
6 | box-sizing: border-box;
7 | }
8 | html,
9 | body {
10 | font-family: 'Ubuntu Mono', monospace;
11 | margin: 0px;
12 | height: 100%;
13 | width: 100%;
14 | }
15 | body {
16 | padding: 20px;
17 | text-align: center;
18 | min-width: 700px;
19 | }
20 | .logo {
21 | width: 55px;
22 | height: 55px;
23 | background: #222;
24 | color: #fff;
25 | text-align: center;
26 | line-height: 56px;
27 | border-radius: 100%;
28 | font-size: 27px;
29 | letter-spacing: -7px;
30 | text-indent: -6px;
31 | margin: auto;
32 | margin-bottom: 20px;
33 | margin-top: 20px;
34 | }
35 | header h1,
36 | footer h1 {
37 | font-weight: normal;
38 | width: 604px;
39 | background: #222;
40 | color: #fff;
41 | font-size: 18px;
42 | height: 55px;
43 | line-height: 55px;
44 | margin: auto;
45 | margin-top: 0px;
46 | margin-bottom: 20px;
47 | }
48 | #demos .gallery {
49 | display: flex;
50 | align-items: center;
51 | justify-content: center;
52 | flex-wrap: wrap;
53 | gap: 16px;
54 | }
55 | .demo-image {
56 | width: 290px;
57 | height: 290px;
58 | background-size: cover;
59 | background-position: 50% 50%;
60 | }
61 | button {
62 | margin: 16px;
63 | width: 100px;
64 | height: 32px;
65 | }
66 | footer h1 {
67 | margin-top: 16px;
68 | padding-left: 20px;
69 | background: #e9e9e9;
70 | color: #222;
71 | font-size: 16px;
72 | }
73 | footer h1 a {
74 | color: #222;
75 | }
76 | iframe {
77 | margin-bottom: -5px;
78 | margin-left: 2px;
79 | }
80 | .github-link {
81 | position: fixed;
82 | z-index: 2;
83 | top: 0;
84 | right: 0;
85 | border: 0;
86 | }
87 | .bullet {
88 | font-size: 12px;
89 | }
90 | @media (max-width: 650px) {
91 | body {
92 | padding: 10px;
93 | min-width: 350px;
94 | }
95 | header h1,
96 | footer h1 {
97 | width: 100%;
98 | font-size: 13px;
99 | height: 20px;
100 | line-height: 20px;
101 | }
102 | footer h1 {
103 | padding: 0 4px;
104 | }
105 | .demo-image {
106 | width: 200px;
107 | height: 200px;
108 | }
109 | }
110 | .github-corner:hover .octo-arm {
111 | animation: octocat-wave 560ms ease-in-out;
112 | }
113 | @keyframes octocat-wave {
114 | 0%,
115 | 100% {
116 | transform: rotate(0);
117 | }
118 | 20%,
119 | 60% {
120 | transform: rotate(-25deg);
121 | }
122 | 40%,
123 | 80% {
124 | transform: rotate(10deg);
125 | }
126 | }
127 | @media (max-width: 500px) {
128 | .github-corner:hover .octo-arm {
129 | animation: none;
130 | }
131 | .github-corner .octo-arm {
132 | animation: octocat-wave 560ms ease-in-out;
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["es6", "dom", "es2016", "es2017"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": false,
17 | "jsx": "react-jsx"
18 | },
19 | "include": ["lib/**/*.tsx", "lib/**/*.ts", "src/**/*.tsx", "src/**/*.ts"]
20 | }
21 |
--------------------------------------------------------------------------------