@uibit/image-reveal 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +22 -0
- package/custom-elements.json +254 -0
- package/dist/frameworks/angular/index.ts +26 -0
- package/dist/frameworks/astro/index.d.ts +10 -0
- package/dist/frameworks/nuxt/index.ts +7 -0
- package/dist/frameworks/preact/index.d.ts +13 -0
- package/dist/frameworks/qwik/index.tsx +10 -0
- package/dist/frameworks/react/index.d.ts +18 -0
- package/dist/frameworks/solid/index.d.ts +14 -0
- package/dist/frameworks/stencil/index.d.ts +12 -0
- package/dist/frameworks/svelte/index.svelte +36 -0
- package/dist/frameworks/vue/index.ts +24 -0
- package/dist/image-reveal.d.ts +39 -0
- package/dist/image-reveal.d.ts.map +1 -0
- package/dist/image-reveal.js +142 -0
- package/dist/image-reveal.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.d.ts +2 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +82 -0
- package/dist/styles.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +91 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 UIBit Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Image X-Ray
|
|
2
|
+
|
|
3
|
+
[Interactive Demonstration](https://rawlings.github.io/uibit/image-xray)
|
|
4
|
+
|
|
5
|
+
Image X-Ray is an interactive comparative display component that reveals layers of information beneath a primary image. By rendering a cursor-following circular lens that acts as a window to a secondary, synchronized image, it offers a polished, engaging way to highlight internal craftsmanship, design layers, or material compositions.
|
|
6
|
+
|
|
7
|
+
## Value Delivery
|
|
8
|
+
|
|
9
|
+
- **Interactive Comparison** – Prompts user exploration by allowing them to visually peek underneath a primary surface in real-time.
|
|
10
|
+
- **Pixel-Perfect Alignment** – Ensures absolute structural alignment between the base and secondary layers at all viewport sizes.
|
|
11
|
+
- **Responsive Interactions** – Operates smoothly on mouse movement for desktops and supports tactile touch-based drag triggers for mobile screens.
|
|
12
|
+
- **High-Impact Visual Narrative** – Ideal for telling stories of build quality, material composition, or engineering structure without static split diagrams.
|
|
13
|
+
|
|
14
|
+
## Ideal Applications
|
|
15
|
+
|
|
16
|
+
- **Product Cutaways** – Showing internal components of consumer electronics, automotive design, or luxury accessories.
|
|
17
|
+
- **Architectural Presentations** – Revealing structural framing, insulation layers, or historical alterations beneath finished walls.
|
|
18
|
+
- **Educational Materials** – Displaying layered anatomical, geological, or historical illustrations.
|
|
19
|
+
|
|
20
|
+
## Further Information
|
|
21
|
+
|
|
22
|
+
Detailed design guidelines, customizable attributes, and integration examples are available on our documentation site.
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "1.0.0",
|
|
3
|
+
"readme": "",
|
|
4
|
+
"modules": [
|
|
5
|
+
{
|
|
6
|
+
"kind": "javascript-module",
|
|
7
|
+
"path": "src/image-reveal.ts",
|
|
8
|
+
"declarations": [
|
|
9
|
+
{
|
|
10
|
+
"kind": "class",
|
|
11
|
+
"description": "Reveals a synchronized secondary \"xray\" image through a circular lens that\nfollows the user's cursor or touch point over the primary image.\n\nPlace the primary image in the default slot and the reveal image in the\n`xray` named slot. Both images are pixel-aligned so the lens shows exactly\nwhat lies beneath the cursor on the xray layer.",
|
|
12
|
+
"name": "ImageReveal",
|
|
13
|
+
"cssProperties": [
|
|
14
|
+
{
|
|
15
|
+
"description": "Diameter of the circular lens",
|
|
16
|
+
"name": "--uibit-image-reveal-lens-size",
|
|
17
|
+
"default": "12rem"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"description": "Box shadow of the lens ring",
|
|
21
|
+
"name": "--uibit-image-reveal-lens-shadow",
|
|
22
|
+
"default": "0 0 0 0.1875rem #ffffff, 0 0.5rem 2rem rgba(0,0,0,0.35)"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"slots": [
|
|
26
|
+
{
|
|
27
|
+
"description": "Primary (outer) image",
|
|
28
|
+
"name": ""
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"description": "Secondary image revealed through the lens",
|
|
32
|
+
"name": "xray"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"members": [
|
|
36
|
+
{
|
|
37
|
+
"kind": "field",
|
|
38
|
+
"name": "size",
|
|
39
|
+
"type": {
|
|
40
|
+
"text": "string"
|
|
41
|
+
},
|
|
42
|
+
"default": "''",
|
|
43
|
+
"description": "Diameter of the lens in any CSS unit. Overrides the CSS custom property.",
|
|
44
|
+
"attribute": "size"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"kind": "field",
|
|
48
|
+
"name": "_x",
|
|
49
|
+
"type": {
|
|
50
|
+
"text": "number"
|
|
51
|
+
},
|
|
52
|
+
"privacy": "private",
|
|
53
|
+
"default": "0"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"kind": "field",
|
|
57
|
+
"name": "_y",
|
|
58
|
+
"type": {
|
|
59
|
+
"text": "number"
|
|
60
|
+
},
|
|
61
|
+
"privacy": "private",
|
|
62
|
+
"default": "0"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"kind": "field",
|
|
66
|
+
"name": "_base",
|
|
67
|
+
"type": {
|
|
68
|
+
"text": "HTMLElement"
|
|
69
|
+
},
|
|
70
|
+
"privacy": "private"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"kind": "field",
|
|
74
|
+
"name": "_lensImg",
|
|
75
|
+
"type": {
|
|
76
|
+
"text": "HTMLElement"
|
|
77
|
+
},
|
|
78
|
+
"privacy": "private"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"kind": "method",
|
|
82
|
+
"name": "_lensSize",
|
|
83
|
+
"privacy": "private",
|
|
84
|
+
"return": {
|
|
85
|
+
"type": {
|
|
86
|
+
"text": "number"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"kind": "method",
|
|
92
|
+
"name": "_updateLens",
|
|
93
|
+
"privacy": "private",
|
|
94
|
+
"parameters": [
|
|
95
|
+
{
|
|
96
|
+
"name": "clientX",
|
|
97
|
+
"type": {
|
|
98
|
+
"text": "number"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "clientY",
|
|
103
|
+
"type": {
|
|
104
|
+
"text": "number"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"kind": "field",
|
|
111
|
+
"name": "_onMouseEnter",
|
|
112
|
+
"privacy": "private"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"kind": "field",
|
|
116
|
+
"name": "_onMouseMove",
|
|
117
|
+
"privacy": "private"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"kind": "field",
|
|
121
|
+
"name": "_onMouseLeave",
|
|
122
|
+
"privacy": "private"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"kind": "field",
|
|
126
|
+
"name": "_onTouchStart",
|
|
127
|
+
"privacy": "private"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"kind": "field",
|
|
131
|
+
"name": "_onTouchMove",
|
|
132
|
+
"privacy": "private"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"kind": "field",
|
|
136
|
+
"name": "_onTouchEnd",
|
|
137
|
+
"privacy": "private"
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
"events": [
|
|
141
|
+
{
|
|
142
|
+
"type": {
|
|
143
|
+
"text": "{ x: number, y: number }"
|
|
144
|
+
},
|
|
145
|
+
"description": "Fired as the lens moves; `detail.x` and `detail.y` are percentages",
|
|
146
|
+
"name": "reveal-move"
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
"attributes": [
|
|
150
|
+
{
|
|
151
|
+
"name": "size",
|
|
152
|
+
"type": {
|
|
153
|
+
"text": "string"
|
|
154
|
+
},
|
|
155
|
+
"default": "''",
|
|
156
|
+
"description": "Diameter of the lens in any CSS unit. Overrides the CSS custom property.",
|
|
157
|
+
"fieldName": "size"
|
|
158
|
+
}
|
|
159
|
+
],
|
|
160
|
+
"superclass": {
|
|
161
|
+
"name": "UIBitElement",
|
|
162
|
+
"package": "@uibit/core"
|
|
163
|
+
},
|
|
164
|
+
"tagName": "uibit-image-reveal",
|
|
165
|
+
"customElement": true
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
"exports": [
|
|
169
|
+
{
|
|
170
|
+
"kind": "js",
|
|
171
|
+
"name": "ImageReveal",
|
|
172
|
+
"declaration": {
|
|
173
|
+
"name": "ImageReveal",
|
|
174
|
+
"module": "src/image-reveal.ts"
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"kind": "custom-element-definition",
|
|
179
|
+
"name": "uibit-image-reveal",
|
|
180
|
+
"declaration": {
|
|
181
|
+
"name": "ImageReveal",
|
|
182
|
+
"module": "src/image-reveal.ts"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"kind": "js",
|
|
187
|
+
"name": "default",
|
|
188
|
+
"declaration": {
|
|
189
|
+
"name": "ImageReveal",
|
|
190
|
+
"module": "src/image-reveal.ts"
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
]
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"kind": "javascript-module",
|
|
197
|
+
"path": "src/index.ts",
|
|
198
|
+
"declarations": [],
|
|
199
|
+
"exports": [
|
|
200
|
+
{
|
|
201
|
+
"kind": "js",
|
|
202
|
+
"name": "default",
|
|
203
|
+
"declaration": {
|
|
204
|
+
"name": "default",
|
|
205
|
+
"module": "./image-reveal"
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"kind": "js",
|
|
210
|
+
"name": "ImageReveal",
|
|
211
|
+
"declaration": {
|
|
212
|
+
"name": "ImageReveal",
|
|
213
|
+
"module": "./image-reveal"
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"kind": "js",
|
|
218
|
+
"name": "*",
|
|
219
|
+
"declaration": {
|
|
220
|
+
"name": "*",
|
|
221
|
+
"module": "src/types"
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"kind": "javascript-module",
|
|
228
|
+
"path": "src/styles.ts",
|
|
229
|
+
"declarations": [
|
|
230
|
+
{
|
|
231
|
+
"kind": "variable",
|
|
232
|
+
"name": "styles",
|
|
233
|
+
"default": "css` :host { display: block; position: relative; overflow: hidden; cursor: none; -webkit-user-select: none; user-select: none; line-height: 0; } :host([touch]) { cursor: default; } .base { display: block; width: 100%; height: 100%; position: relative; } ::slotted(img), ::slotted(picture) { display: block; width: 100%; height: auto; pointer-events: none; } .xray-slot { position: absolute; inset: 0; pointer-events: none; } .xray-slot ::slotted(img), .xray-slot ::slotted(picture) { display: block; width: 100%; height: 100%; object-fit: cover; } .lens { position: absolute; top: 0; left: 0; border-radius: 50%; overflow: hidden; pointer-events: none; box-shadow: var( --uibit-image-reveal-lens-shadow, 0 0 0 0.0625rem rgba(0, 0, 0, 0.18), 0 0 0 0.1875rem rgba(255, 255, 255, 0.92), 0 0 0 0.25rem rgba(0, 0, 0, 0.1), 0 0.75rem 2.5rem rgba(0, 0, 0, 0.45) ); transform: translate(-50%, -50%); will-change: transform; transition: opacity 0.15s ease; opacity: 0; } :host([active]) .lens { opacity: 1; } .lens-inner { width: 100%; height: 100%; position: relative; overflow: hidden; } .lens-img { position: absolute; pointer-events: none; } `"
|
|
234
|
+
}
|
|
235
|
+
],
|
|
236
|
+
"exports": [
|
|
237
|
+
{
|
|
238
|
+
"kind": "js",
|
|
239
|
+
"name": "styles",
|
|
240
|
+
"declaration": {
|
|
241
|
+
"name": "styles",
|
|
242
|
+
"module": "src/styles.ts"
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"kind": "javascript-module",
|
|
249
|
+
"path": "src/types.ts",
|
|
250
|
+
"declarations": [],
|
|
251
|
+
"exports": []
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Component, ChangeDetectionStrategy, ElementRef, input, effect, output } from '@angular/core';
|
|
2
|
+
import '@uibit/image-reveal';
|
|
3
|
+
import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
|
|
4
|
+
|
|
5
|
+
@Component({
|
|
6
|
+
selector: 'uibit-image-reveal',
|
|
7
|
+
template: '<ng-content></ng-content>',
|
|
8
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
9
|
+
standalone: true,
|
|
10
|
+
host: {
|
|
11
|
+
'(reveal-move)': 'revealMove.emit($event)'
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
export class NgxImageReveal {
|
|
15
|
+
constructor(private el: ElementRef<HTMLElementClass>) {
|
|
16
|
+
effect(() => {
|
|
17
|
+
if (this.el.nativeElement) {
|
|
18
|
+
this.el.nativeElement.size = this.size();
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
readonly size = input<string, any>('');
|
|
24
|
+
|
|
25
|
+
readonly revealMove = output<CustomEvent<{ x: number, y: number }>>();
|
|
26
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
|
|
2
|
+
import '@uibit/image-reveal';
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
namespace astroHTML.JSX {
|
|
6
|
+
interface IntrinsicElements {
|
|
7
|
+
'uibit-image-reveal': Partial<HTMLElementClass> & astroHTML.JSX.HTMLAttributes;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { JSX } from 'preact';
|
|
2
|
+
import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
|
|
3
|
+
import '@uibit/image-reveal';
|
|
4
|
+
|
|
5
|
+
declare module 'preact' {
|
|
6
|
+
namespace JSX {
|
|
7
|
+
interface IntrinsicElements {
|
|
8
|
+
'uibit-image-reveal': JSX.HTMLAttributes<HTMLElementClass> & {
|
|
9
|
+
size?: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HTMLAttributes, ClassAttributes } from 'react';
|
|
2
|
+
import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
|
|
3
|
+
import '@uibit/image-reveal';
|
|
4
|
+
|
|
5
|
+
declare global {
|
|
6
|
+
namespace React {
|
|
7
|
+
namespace JSX {
|
|
8
|
+
interface IntrinsicElements {
|
|
9
|
+
'uibit-image-reveal': ClassAttributes<HTMLElementClass> & HTMLAttributes<HTMLElementClass> & {
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
class?: string;
|
|
12
|
+
size?: string;
|
|
13
|
+
onRevealMove?: (event: any) => void;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { JSX } from 'solid-js';
|
|
2
|
+
import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
|
|
3
|
+
import '@uibit/image-reveal';
|
|
4
|
+
|
|
5
|
+
declare module 'solid-js' {
|
|
6
|
+
namespace JSX {
|
|
7
|
+
interface IntrinsicElements {
|
|
8
|
+
'uibit-image-reveal': Partial<HTMLElementClass> & JSX.HTMLAttributes<HTMLElementClass> & {
|
|
9
|
+
size?: string;
|
|
10
|
+
"on:reveal-move"?: (event: CustomEvent) => void;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
|
|
2
|
+
import '@uibit/image-reveal';
|
|
3
|
+
|
|
4
|
+
declare module '@stencil/core' {
|
|
5
|
+
export namespace JSX {
|
|
6
|
+
interface IntrinsicElements {
|
|
7
|
+
'uibit-image-reveal': HTMLElementClass & {
|
|
8
|
+
size?: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import '@uibit/image-reveal';
|
|
3
|
+
import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
size = undefined,
|
|
7
|
+
xray = undefined,
|
|
8
|
+
children
|
|
9
|
+
} = $props<{
|
|
10
|
+
children?: any;
|
|
11
|
+
size?: string;
|
|
12
|
+
xray?: import('svelte').Snippet;
|
|
13
|
+
}>();
|
|
14
|
+
|
|
15
|
+
let elementRef: HTMLElementClass | null = $state(null);
|
|
16
|
+
|
|
17
|
+
$effect(() => {
|
|
18
|
+
if (elementRef && size !== undefined) {
|
|
19
|
+
elementRef.size = size;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<uibit-image-reveal bind:this={elementRef} {...$$restProps}>
|
|
26
|
+
{#if xray}
|
|
27
|
+
<div slot="xray">
|
|
28
|
+
{@render xray()}
|
|
29
|
+
</div>
|
|
30
|
+
{/if}
|
|
31
|
+
{#if children}
|
|
32
|
+
{@render children()}
|
|
33
|
+
{:else}
|
|
34
|
+
<slot />
|
|
35
|
+
{/if}
|
|
36
|
+
</uibit-image-reveal>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defineComponent, h } from 'vue';
|
|
2
|
+
import type { ImageReveal as HTMLElementClass } from '@uibit/image-reveal';
|
|
3
|
+
import '@uibit/image-reveal';
|
|
4
|
+
|
|
5
|
+
export const ImageReveal = defineComponent({
|
|
6
|
+
name: 'ImageReveal',
|
|
7
|
+
props: {
|
|
8
|
+
size: { type: [String, Number, Boolean, Array, Object] as any }
|
|
9
|
+
},
|
|
10
|
+
emits: ['reveal-move'],
|
|
11
|
+
setup(props, { slots, emit }) {
|
|
12
|
+
return () => {
|
|
13
|
+
const eventListeners: Record<string, any> = {};
|
|
14
|
+
eventListeners['onReveal-move'] = (event: Event) => {
|
|
15
|
+
emit('reveal-move', event);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return h('uibit-image-reveal', {
|
|
19
|
+
...props,
|
|
20
|
+
...eventListeners
|
|
21
|
+
}, slots.default?.());
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { UIBitElement } from '@uibit/core';
|
|
2
|
+
/**
|
|
3
|
+
* Reveals a synchronized secondary "xray" image through a circular lens that
|
|
4
|
+
* follows the user's cursor or touch point over the primary image.
|
|
5
|
+
*
|
|
6
|
+
* Place the primary image in the default slot and the reveal image in the
|
|
7
|
+
* `xray` named slot. Both images are pixel-aligned so the lens shows exactly
|
|
8
|
+
* what lies beneath the cursor on the xray layer.
|
|
9
|
+
*
|
|
10
|
+
* @slot - Primary (outer) image
|
|
11
|
+
* @slot xray - Secondary image revealed through the lens
|
|
12
|
+
*
|
|
13
|
+
* @fires {{ x: number, y: number }} reveal-move - Fired as the lens moves; `detail.x` and `detail.y` are percentages
|
|
14
|
+
*
|
|
15
|
+
* @cssprop [--uibit-image-reveal-lens-size=12rem] - Diameter of the circular lens
|
|
16
|
+
* @cssprop [--uibit-image-reveal-lens-shadow=0 0 0 0.1875rem #ffffff, 0 0.5rem 2rem rgba(0,0,0,0.35)] - Box shadow of the lens ring
|
|
17
|
+
*/
|
|
18
|
+
export declare class ImageReveal extends UIBitElement {
|
|
19
|
+
static styles: import("lit").CSSResult;
|
|
20
|
+
/** Diameter of the lens in any CSS unit. Overrides the CSS custom property. */
|
|
21
|
+
size: string;
|
|
22
|
+
private _x;
|
|
23
|
+
private _y;
|
|
24
|
+
private _base;
|
|
25
|
+
private _lensImg;
|
|
26
|
+
connectedCallback(): void;
|
|
27
|
+
private _lensSize;
|
|
28
|
+
private _updateLens;
|
|
29
|
+
private _onMouseEnter;
|
|
30
|
+
private _onMouseMove;
|
|
31
|
+
private _onMouseLeave;
|
|
32
|
+
private _onTouchStart;
|
|
33
|
+
private _onTouchMove;
|
|
34
|
+
private _onTouchEnd;
|
|
35
|
+
firstUpdated(): void;
|
|
36
|
+
render(): import("lit").TemplateResult<1>;
|
|
37
|
+
}
|
|
38
|
+
export default ImageReveal;
|
|
39
|
+
//# sourceMappingURL=image-reveal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-reveal.d.ts","sourceRoot":"","sources":["../src/image-reveal.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,YAAY,EAAE,MAAM,aAAa,CAAC;AAK1D;;;;;;;;;;;;;;;GAeG;AACH,qBACa,WAAY,SAAQ,YAAY;IAC3C,MAAM,CAAC,MAAM,0BAAU;IAEvB,+EAA+E;IACnD,IAAI,SAAM;IAE7B,OAAO,CAAC,EAAE,CAAK;IACf,OAAO,CAAC,EAAE,CAAK;IAER,OAAO,CAAC,KAAK,CAAe;IACxB,OAAO,CAAC,QAAQ,CAAe;IAEnD,iBAAiB,SAEhB;IAED,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,WAAW;IAqBnB,OAAO,CAAC,aAAa,CAGnB;IAEF,OAAO,CAAC,YAAY,CAElB;IAEF,OAAO,CAAC,aAAa,CAEnB;IAEF,OAAO,CAAC,aAAa,CAKnB;IAEF,OAAO,CAAC,YAAY,CAIlB;IAEF,OAAO,CAAC,WAAW,CAEjB;IAEF,YAAY,SAQX;IAED,MAAM,oCAoBL;CACF;eAEc,WAAW"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html } from 'lit';
|
|
8
|
+
import { customElement, UIBitElement } from '@uibit/core';
|
|
9
|
+
import { property, state, query } from 'lit/decorators.js';
|
|
10
|
+
import { styleMap } from 'lit/directives/style-map.js';
|
|
11
|
+
import { styles } from './styles';
|
|
12
|
+
/**
|
|
13
|
+
* Reveals a synchronized secondary "xray" image through a circular lens that
|
|
14
|
+
* follows the user's cursor or touch point over the primary image.
|
|
15
|
+
*
|
|
16
|
+
* Place the primary image in the default slot and the reveal image in the
|
|
17
|
+
* `xray` named slot. Both images are pixel-aligned so the lens shows exactly
|
|
18
|
+
* what lies beneath the cursor on the xray layer.
|
|
19
|
+
*
|
|
20
|
+
* @slot - Primary (outer) image
|
|
21
|
+
* @slot xray - Secondary image revealed through the lens
|
|
22
|
+
*
|
|
23
|
+
* @fires {{ x: number, y: number }} reveal-move - Fired as the lens moves; `detail.x` and `detail.y` are percentages
|
|
24
|
+
*
|
|
25
|
+
* @cssprop [--uibit-image-reveal-lens-size=12rem] - Diameter of the circular lens
|
|
26
|
+
* @cssprop [--uibit-image-reveal-lens-shadow=0 0 0 0.1875rem #ffffff, 0 0.5rem 2rem rgba(0,0,0,0.35)] - Box shadow of the lens ring
|
|
27
|
+
*/
|
|
28
|
+
let ImageReveal = class ImageReveal extends UIBitElement {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
/** Diameter of the lens in any CSS unit. Overrides the CSS custom property. */
|
|
32
|
+
this.size = '';
|
|
33
|
+
this._x = 0;
|
|
34
|
+
this._y = 0;
|
|
35
|
+
this._onMouseEnter = (e) => {
|
|
36
|
+
this.setAttribute('active', '');
|
|
37
|
+
this._updateLens(e.clientX, e.clientY);
|
|
38
|
+
};
|
|
39
|
+
this._onMouseMove = (e) => {
|
|
40
|
+
this._updateLens(e.clientX, e.clientY);
|
|
41
|
+
};
|
|
42
|
+
this._onMouseLeave = () => {
|
|
43
|
+
this.removeAttribute('active');
|
|
44
|
+
};
|
|
45
|
+
this._onTouchStart = (e) => {
|
|
46
|
+
this.setAttribute('touch', '');
|
|
47
|
+
this.setAttribute('active', '');
|
|
48
|
+
const t = e.touches[0];
|
|
49
|
+
if (t)
|
|
50
|
+
this._updateLens(t.clientX, t.clientY);
|
|
51
|
+
};
|
|
52
|
+
this._onTouchMove = (e) => {
|
|
53
|
+
if (e.cancelable)
|
|
54
|
+
e.preventDefault();
|
|
55
|
+
const t = e.touches[0];
|
|
56
|
+
if (t)
|
|
57
|
+
this._updateLens(t.clientX, t.clientY);
|
|
58
|
+
};
|
|
59
|
+
this._onTouchEnd = () => {
|
|
60
|
+
this.removeAttribute('active');
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
static { this.styles = styles; }
|
|
64
|
+
connectedCallback() {
|
|
65
|
+
super.connectedCallback();
|
|
66
|
+
}
|
|
67
|
+
_lensSize() {
|
|
68
|
+
const prop = this.size || this.getCssPropertyValue('--uibit-image-reveal-lens-size').trim() || '12rem';
|
|
69
|
+
if (prop.endsWith('rem')) {
|
|
70
|
+
return parseFloat(prop) * parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
71
|
+
}
|
|
72
|
+
if (prop.endsWith('px'))
|
|
73
|
+
return parseFloat(prop);
|
|
74
|
+
return 192;
|
|
75
|
+
}
|
|
76
|
+
_updateLens(clientX, clientY) {
|
|
77
|
+
const rect = this._base.getBoundingClientRect();
|
|
78
|
+
const x = clientX - rect.left;
|
|
79
|
+
const y = clientY - rect.top;
|
|
80
|
+
this._x = x;
|
|
81
|
+
this._y = y;
|
|
82
|
+
const size = this._lensSize();
|
|
83
|
+
// Sync the xray img position so the pixel under the cursor aligns
|
|
84
|
+
if (this._lensImg) {
|
|
85
|
+
this._lensImg.style.width = `${rect.width}px`;
|
|
86
|
+
this._lensImg.style.height = `${rect.height}px`;
|
|
87
|
+
this._lensImg.style.left = `${-(x - size / 2)}px`;
|
|
88
|
+
this._lensImg.style.top = `${-(y - size / 2)}px`;
|
|
89
|
+
}
|
|
90
|
+
this.dispatchCustomEvent('reveal-move', { x: (x / rect.width) * 100, y: (y / rect.height) * 100 });
|
|
91
|
+
}
|
|
92
|
+
firstUpdated() {
|
|
93
|
+
this.listen(this._base, 'mouseenter', this._onMouseEnter);
|
|
94
|
+
this.listen(this._base, 'mousemove', this._onMouseMove);
|
|
95
|
+
this.listen(this._base, 'mouseleave', this._onMouseLeave);
|
|
96
|
+
this.listen(this._base, 'touchstart', this._onTouchStart, { passive: false });
|
|
97
|
+
this.listen(this._base, 'touchmove', this._onTouchMove, { passive: false });
|
|
98
|
+
this.listen(this._base, 'touchend', this._onTouchEnd);
|
|
99
|
+
this.listen(this._base, 'touchcancel', this._onTouchEnd);
|
|
100
|
+
}
|
|
101
|
+
render() {
|
|
102
|
+
const size = this.size || 'var(--uibit-image-reveal-lens-size, 12rem)';
|
|
103
|
+
const lensStyle = styleMap({
|
|
104
|
+
width: size,
|
|
105
|
+
height: size,
|
|
106
|
+
transform: `translate(calc(${this._x}px - 50%), calc(${this._y}px - 50%))`,
|
|
107
|
+
});
|
|
108
|
+
return html `
|
|
109
|
+
<div class="base" part="base">
|
|
110
|
+
<slot></slot>
|
|
111
|
+
<div class="lens" part="lens" style=${lensStyle}>
|
|
112
|
+
<div class="lens-inner" part="lens-inner">
|
|
113
|
+
<div class="lens-img" part="lens-img">
|
|
114
|
+
<slot name="reveal"></slot>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
__decorate([
|
|
123
|
+
property({ type: String })
|
|
124
|
+
], ImageReveal.prototype, "size", void 0);
|
|
125
|
+
__decorate([
|
|
126
|
+
state()
|
|
127
|
+
], ImageReveal.prototype, "_x", void 0);
|
|
128
|
+
__decorate([
|
|
129
|
+
state()
|
|
130
|
+
], ImageReveal.prototype, "_y", void 0);
|
|
131
|
+
__decorate([
|
|
132
|
+
query('.base')
|
|
133
|
+
], ImageReveal.prototype, "_base", void 0);
|
|
134
|
+
__decorate([
|
|
135
|
+
query('.lens-img')
|
|
136
|
+
], ImageReveal.prototype, "_lensImg", void 0);
|
|
137
|
+
ImageReveal = __decorate([
|
|
138
|
+
customElement('uibit-image-reveal')
|
|
139
|
+
], ImageReveal);
|
|
140
|
+
export { ImageReveal };
|
|
141
|
+
export default ImageReveal;
|
|
142
|
+
//# sourceMappingURL=image-reveal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-reveal.js","sourceRoot":"","sources":["../src/image-reveal.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACtD,cAAc,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACtD,cAAc,SAAS,CAAC"}
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM,yBA+ElB,CAAC"}
|
package/dist/styles.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const styles = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
position: relative;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
cursor: none;
|
|
8
|
+
-webkit-user-select: none;
|
|
9
|
+
user-select: none;
|
|
10
|
+
line-height: 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
:host([touch]) {
|
|
14
|
+
cursor: default;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.base {
|
|
18
|
+
display: block;
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 100%;
|
|
21
|
+
position: relative;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
::slotted(img),
|
|
25
|
+
::slotted(picture) {
|
|
26
|
+
display: block;
|
|
27
|
+
width: 100%;
|
|
28
|
+
height: auto;
|
|
29
|
+
pointer-events: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.xray-slot {
|
|
33
|
+
position: absolute;
|
|
34
|
+
inset: 0;
|
|
35
|
+
pointer-events: none;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.xray-slot ::slotted(img),
|
|
39
|
+
.xray-slot ::slotted(picture) {
|
|
40
|
+
display: block;
|
|
41
|
+
width: 100%;
|
|
42
|
+
height: 100%;
|
|
43
|
+
object-fit: cover;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.lens {
|
|
47
|
+
position: absolute;
|
|
48
|
+
top: 0;
|
|
49
|
+
left: 0;
|
|
50
|
+
border-radius: 50%;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
pointer-events: none;
|
|
53
|
+
box-shadow: var(
|
|
54
|
+
--uibit-image-reveal-lens-shadow,
|
|
55
|
+
0 0 0 0.0625rem rgba(0, 0, 0, 0.18),
|
|
56
|
+
0 0 0 0.1875rem rgba(255, 255, 255, 0.92),
|
|
57
|
+
0 0 0 0.25rem rgba(0, 0, 0, 0.1),
|
|
58
|
+
0 0.75rem 2.5rem rgba(0, 0, 0, 0.45)
|
|
59
|
+
);
|
|
60
|
+
transform: translate(-50%, -50%);
|
|
61
|
+
will-change: transform;
|
|
62
|
+
transition: opacity 0.15s ease;
|
|
63
|
+
opacity: 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
:host([active]) .lens {
|
|
67
|
+
opacity: 1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.lens-inner {
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
position: relative;
|
|
74
|
+
overflow: hidden;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.lens-img {
|
|
78
|
+
position: absolute;
|
|
79
|
+
pointer-events: none;
|
|
80
|
+
}
|
|
81
|
+
`;
|
|
82
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+ExB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,gBAAgB,CAAC;AAE9C,OAAO,CAAC,MAAM,CAAC;IACf,UAAU,qBAAqB;QAC3B,oBAAoB,EAAE,WAAW,CAAC;KACrC;CACA"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uibit/image-reveal",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A floating circular lens that follows the cursor or touch point, revealing a synchronized secondary image exactly where the user looks. Built for luxury and high-tech product storytelling.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./custom-elements.json": "./custom-elements.json",
|
|
14
|
+
"./react": "./dist/frameworks/react/index.d.ts",
|
|
15
|
+
"./vue": "./dist/frameworks/vue/index.ts",
|
|
16
|
+
"./svelte": "./dist/frameworks/svelte/index.svelte",
|
|
17
|
+
"./angular": "./dist/frameworks/angular/index.ts",
|
|
18
|
+
"./solid": "./dist/frameworks/solid/index.d.ts",
|
|
19
|
+
"./astro": "./dist/frameworks/astro/index.astro",
|
|
20
|
+
"./qwik": "./dist/frameworks/qwik/index.tsx",
|
|
21
|
+
"./nuxt": "./dist/frameworks/nuxt/index.ts",
|
|
22
|
+
"./preact": "./dist/frameworks/preact/index.d.ts",
|
|
23
|
+
"./stencil": "./dist/frameworks/stencil/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"package.json",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE",
|
|
30
|
+
"custom-elements.json"
|
|
31
|
+
],
|
|
32
|
+
"keywords": [
|
|
33
|
+
"xray",
|
|
34
|
+
"lens",
|
|
35
|
+
"loupe",
|
|
36
|
+
"image",
|
|
37
|
+
"reveal",
|
|
38
|
+
"web-component",
|
|
39
|
+
"lit"
|
|
40
|
+
],
|
|
41
|
+
"author": "Jonathan Rawlings",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/Rawlings/uibit",
|
|
46
|
+
"directory": "packages/components/image-reveal"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@uibit/core": "0.1.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^20.19.43",
|
|
53
|
+
"lit": "^3.3.3",
|
|
54
|
+
"typescript": "7.0.2",
|
|
55
|
+
"@uibit/codegen": "0.1.0"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"lit": "^3.0.0",
|
|
59
|
+
"react": ">=18",
|
|
60
|
+
"vue": ">=3",
|
|
61
|
+
"svelte": ">=4 || ^5",
|
|
62
|
+
"@angular/core": ">=14"
|
|
63
|
+
},
|
|
64
|
+
"customElements": "custom-elements.json",
|
|
65
|
+
"peerDependenciesMeta": {
|
|
66
|
+
"react": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"vue": {
|
|
70
|
+
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"svelte": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@angular/core": {
|
|
76
|
+
"optional": true
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"uibit": {
|
|
80
|
+
"id": "image-reveal",
|
|
81
|
+
"title": "Image Reveal",
|
|
82
|
+
"category": "Media",
|
|
83
|
+
"tagName": "uibit-image-reveal"
|
|
84
|
+
},
|
|
85
|
+
"scripts": {
|
|
86
|
+
"build": "cem analyze --globs 'src/**/*.ts' --litelement && uibit-codegen --package . && tsc",
|
|
87
|
+
"dev": "concurrently \"cem analyze --globs 'src/**/*.ts' --litelement --watch\" \"tsc --watch\"",
|
|
88
|
+
"analyze": "cem analyze --globs 'src/**/*.ts' --litelement",
|
|
89
|
+
"typecheck": "tsc --noEmit"
|
|
90
|
+
}
|
|
91
|
+
}
|