super-impose
Web Component that super imposes one child over another to the same scroll position
npm i super-impose
|
pnpm add super-impose
|
yarn add super-impose
|
Examples
# complex
# view source
example/complex.ts
import { SuperImposeElement } from 'super-impose'
customElements.define('super-impose', SuperImposeElement)
class WrapElement extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
this.shadowRoot!.innerHTML = /*html*/ `
<style>
:host {
display: flex;
position: relative;
resize: both;
white-space: pre;
overflow: scroll;
}
[part="box"] {
}
</style>
<super-impose part="box">
<textarea slot="leader" part="leader" wrap="off">
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
some content wide enough to scroll<br />
</textarea>
<div slot="follower">
other content<br />
other content<br />
other content<br />
other content<br />
other content<br />
other content<br />
</div>
</super-impose>
`
}
}
customElements.define('wrap-element', WrapElement)
document.body.innerHTML = /*html*/ `
<style>
* {
background: transparent;
color: #bbb;
}
wrap-element {
width: 100px;
height: 100px;
}
</style>
<pre>
one
two
three
</pre>
<div style="padding: 20px; border: 1px solid #000; width: 100px; height: 100px; overflow: hidden; resize: both">
<super-impose onscroll="console.log(this.scrollTop, this.scrollLeft)">
<textarea slot="leader" wrap="off">
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
some content wide enough to scroll
</textarea>
<pre slot="follower" style="white-space: pre">
other content
other content
other content
other content
other content
other content
other content
</pre>
</super-impose>
</div>
<wrap-element></wrap-element>
`
const el = document.body.querySelector('super-impose')!
setTimeout(() => {
el.remove()
setTimeout(() => {
document.body.appendChild(el)
}, 500)
}, 2500)
# web
Try it live
# view source
example/web.ts
import { SuperImposeElement } from 'super-impose'
customElements.define('super-impose', SuperImposeElement)
document.body.innerHTML = /*html*/ `
<super-impose
id="demo"
style="width: 120px; height: 120px; overflow: hidden; resize: both">
<pre slot="leader" style="color: #fa4; font-size: 25px;">
🎈🎈🎈🎈🎈🎈🎈🎈🎈
🎈🎈🎈🎈🎈🎈🎈🎈🎈
🎈🎈🎈🎈🎈🎈🎈🎈🎈
🎈🎈🎈🎈🎈🎈🎈🎈🎈
🎈🎈🎈🎈🎈🎈🎈🎈🎈
🎈🎈🎈🎈🎈🎈🎈🎈🎈
🎈🎈🎈🎈🎈🎈🎈🎈🎈
🎈🎈🎈🎈🎈🎈🎈🎈🎈
🎈🎈🎈🎈🎈🎈🎈🎈🎈
</pre>
<pre slot="follower" style="white-space: pre; color:#1ff; font-size: 15px;">
🌀🌀🌀🌀🌀🌀🌀
🌀🌀🌀🌀🌀🌀🌀
🌀🌀🌀🌀🌀🌀🌀
🌀🌀🌀🌀🌀🌀🌀
🌀🌀🌀🌀🌀🌀🌀
🌀🌀🌀🌀🌀🌀🌀
</pre>
</super-impose>
</div>
`
const leader = document.querySelector('[slot=leader]')!
const mag = 20
let i = 0
const render = () => {
requestAnimationFrame(render)
const x = (i * (1 / 1000)) * Math.PI * 2
Object.assign(leader, {
scrollLeft: mag + Math.sin(x) * mag,
scrollTop: mag + Math.cos(x) * mag,
})
i += 1000 / 60
}
requestAnimationFrame(render)
API
--#
src/index.ts#L70 SuperImposeElement
– Super imposes one child (follower
) contents over another
at the same scroll position determined by the leader
.
import { SuperImposeElement } from 'super-impose'
customElements.define('super-impose', SuperImposeElement)
<super-impose>
<div slot="leader"></div>
<div slot="follower"></div>
</super-impose>
Context<SuperImposeElement & JsxContext<SuperImposeElement> & Omit<{ <T>(ctor) => #
src/work/stagas/sigl/dist/types/sigl.d.ts#L25 $
CleanClass<T>
<T>(ctx) =>
-
Wrapper<T>
},
"transition"
>> # context
src/work/stagas/sigl/dist/types/sigl.d.ts#L26 ContextClass<SuperImposeElement & JsxContext<SuperImposeElement> & Omit<{
<T>(ctor) =>
-
CleanClass<T>
<T>(ctx) =>
-
Wrapper<T>
},
"transition"
>> # onmounted
EventHandler<SuperImposeElement, CustomEvent<any>>
# onunmounted
EventHandler<SuperImposeElement, CustomEvent<any>>
# created
(ctx)
Context<SuperImposeElement & JsxContext<SuperImposeElement> & Omit<{ <T>(ctor) => #
ctx
CleanClass<T>
<T>(ctx) =>
-
Wrapper<T>
},
"transition"
>> created(ctx) =>
- void
# mounted
($)
src/index.ts#L101 Context<SuperImposeElement & JsxContext<SuperImposeElement> & Omit<{ <T>(ctor) => #
$
CleanClass<T>
<T>(ctx) =>
-
Wrapper<T>
},
"transition"
>> mounted($) =>
- void
# on
(name)
on<K>(name) =>
-
On<Fn<[ EventHandler<SuperImposeElement, LifecycleEvents & object [K]> ], Off>>
# toJSON
()
toJSON() =>
-
Pick<SuperImposeElement, keyof SuperImposeElement>
Credits
Contributing
All contributions are welcome!