@ -1,19 +0,0 @@
|
||||
<script>
|
||||
import AnchorButton from "./elements/AnchorButton.svelte";
|
||||
</script>
|
||||
|
||||
<section class="text-white bg-cover bg-center" style="background-image: url('/images/footer/bbc.png')">
|
||||
<div class="bg-black bg-opacity-30 p-10 flex flex-col justify-between items-center">
|
||||
<h3 class="text-9xl font-extrabold">BIG</h3>
|
||||
<h5 class="text-3xl tracking-widest lowercase font-mono font-bold">Boys Club</h5>
|
||||
<hr class="w-1/2 my-5" />
|
||||
<p class="w-1/3 text-center text-xl italic">
|
||||
Big Boys Club a place focused on the Macro/Micro Size community.
|
||||
It is inclusive to all kinds and types be that giantess, destruction, vore, toyplay, mmd or anything else.
|
||||
</p>
|
||||
<hr class="w-1/2 my-5" />
|
||||
<AnchorButton href="https://discord.gg/rSq87ug" target="_blank">
|
||||
Join the Discord
|
||||
</AnchorButton>
|
||||
</div>
|
||||
</section>
|
@ -1,20 +0,0 @@
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import * as THREE from 'three';
|
||||
import * as Mid from '$lib/mid';
|
||||
</script>
|
||||
|
||||
<main class="-m-10 py-10 bg-zinc-800 bg-cover bg-center" style="background-image: url('/grow.png')">
|
||||
<section class="flex justify-between gap-5 w-2/3 mx-auto">
|
||||
<div class="flex flex-col w-full">
|
||||
<h2 class="text-4xl font-mono font-bold">Subject name: {Mid['name']}</h2>
|
||||
<h2 class="text-2xl">Vitals <span class="text-green-400 text-3xl font-bold font-mono uppercase">OK</span></h2>
|
||||
<h3>{Mid['heightcm']} cm tall</h3>
|
||||
<h3>Weighs {Mid['weightkg']} kg</h3>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
@ -1,12 +1,10 @@
|
||||
<script>
|
||||
export let href;
|
||||
export let target;
|
||||
</script>
|
||||
|
||||
<a
|
||||
target={target}
|
||||
href={href}
|
||||
class="py-3 px-10 text-lg font-bold font-mono bg-opacity-20 hover:bg-opacity-100 bg-black text-white rounded-full border-white hover:bg-white hover:text-black border-2 hover:shadow-inner duration-300"
|
||||
{href}
|
||||
class="py-2 px-5 bg-white dark:bg-black bg-opacity-70 dark:bg-opacity-50 rounded-lg hover:bg-opacity-100 dark:hover:bg-opacity-100 duration-150 text-gray-800 hover:text-black dark:text-gray-200 dark:hover:text-white"
|
||||
>
|
||||
<slot />
|
||||
</a>
|
||||
|
@ -1,24 +1,29 @@
|
||||
<script>
|
||||
import BigBoysClub from "$lib/BigBoysClub.svelte";
|
||||
|
||||
import Socials from "$lib/Socials.svelte";
|
||||
import ThemeSwitcher from "$lib/ThemeSwitcher.svelte";
|
||||
import Social from "./Social.svelte";
|
||||
</script>
|
||||
|
||||
<main class="flex flex-col">
|
||||
<BigBoysClub/>
|
||||
|
||||
<main
|
||||
class="py-10 px-2 lg:px-10 bg-white dark:bg-black dark:bg-opacity-50 text-black dark:text-white shadow"
|
||||
>
|
||||
<section
|
||||
class="p-10 flex flex-col-reverse lg:flex-row justify-between gap-10 bg-gradient-to-bl from-zinc-100 to-orange-100 text-black"
|
||||
class="container flex flex-col-reverse lg:flex-row justify-between gap-10"
|
||||
>
|
||||
<div class="flex flex-col gap-3">
|
||||
<h4 class="font-sm font-bold font-mono">Midblep // hugegrowingcat</h4>
|
||||
<h4 class="font-sm font-bold">Bart Industries</h4>
|
||||
<hr />
|
||||
<p class="text-xs">Copyright 2022 Mid</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-5 lg:items-end">
|
||||
<Socials />
|
||||
<div class="text-amber-500 flex gap-2 items-center font-bold">
|
||||
<span class="text-xs">Theme:</span>
|
||||
<span class="bg-gray-100 dark:bg-gray-800"
|
||||
><ThemeSwitcher /></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
@ -1,15 +1,37 @@
|
||||
<script>
|
||||
// @ts-nocheck
|
||||
import ThemeSwitcher from "$lib/ThemeSwitcher.svelte";
|
||||
|
||||
import Button from "./Button.svelte";
|
||||
import Dropdown from "./Dropdown.svelte";
|
||||
import DropdownButton from "./DropdownButton.svelte";
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col justify-center gap-2 items-center">
|
||||
<a class="flex text-6xl items-center font-mono font-bold" href="/">
|
||||
Mid's Domain
|
||||
<div class="flex justify-between items-center">
|
||||
<a class="flex h-14" href="/">
|
||||
<!-- <Button url="/" text="<img src='/bart.png' />" type="title" /> -->
|
||||
<img src="/bart.png" alt="Logo" class="h-full px-5 py-2 bg-amber-500" />
|
||||
</a>
|
||||
<div class="flex lg:flex-row flex-col gap-5 items-center font-mono">
|
||||
<Button url="/" text="About" />
|
||||
<Button url="/macromarch" text="Macro March" />
|
||||
<Button url="/characters" text="Characters" />
|
||||
<div class="hidden lg:flex h-14">
|
||||
<Button url="/" text="🏠 Home" />
|
||||
<Button disabled="true" url="/esu" text="📒 ESU" />
|
||||
<Button disabled="true" url="/portfolio" text="🧰 works" />
|
||||
<Button disabled="true" url="/furry" text="🐈⬛ Furry" />
|
||||
<Button disabled="true" url="http://ad.localhost" text="🔞 AD Site" />
|
||||
<span><ThemeSwitcher /></span>
|
||||
</div>
|
||||
<div class="flex lg:hidden h-14">
|
||||
<Dropdown text="🍔">
|
||||
<Button url="/" text="🏠 Home" />
|
||||
<Button disabled="true" url="/esu" text="📒 ESU" />
|
||||
<Button disabled="true" url="/portfolio" text="🧰 works" />
|
||||
<Button disabled="true" url="/furry" text="🐈⬛ Furry" />
|
||||
<Button
|
||||
disabled="true"
|
||||
url="http://ad.localhost"
|
||||
text="🔞 AD Site"
|
||||
/>
|
||||
<ThemeSwitcher />
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "Midnight",
|
||||
"heightcm": "200",
|
||||
"weightkg": "600"
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<main>
|
||||
<h1>Error</h1>
|
||||
</main>
|
@ -1,245 +0,0 @@
|
||||
<script>
|
||||
import Button from "$lib/header/Button.svelte";
|
||||
import { Splide, SplideSlide } from '@splidejs/svelte-splide';
|
||||
import '@splidejs/splide/dist/css/splide.min.css';
|
||||
import { AutoScroll } from '@splidejs/splide-extension-auto-scroll';
|
||||
import Dash from "$lib/Dash.svelte";
|
||||
|
||||
function shuffle(array) {
|
||||
let currentIndex = array.length, randomIndex;
|
||||
|
||||
// While there remain elements to shuffle...
|
||||
while (currentIndex != 0) {
|
||||
|
||||
// Pick a remaining element...
|
||||
randomIndex = Math.floor(Math.random() * currentIndex);
|
||||
currentIndex--;
|
||||
|
||||
// And swap it with the current element.
|
||||
[array[currentIndex], array[randomIndex]] = [
|
||||
array[randomIndex], array[currentIndex]];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
let options = {
|
||||
rewind: true,
|
||||
gap: '2em',
|
||||
perPage: 1,
|
||||
fixedHeight: "100vh",
|
||||
cover: true,
|
||||
type: 'fade',
|
||||
speed: 3000,
|
||||
pagination: false,
|
||||
arrows: false,
|
||||
autoplay: true,
|
||||
interval: 5000,
|
||||
focus: 'center'
|
||||
};
|
||||
let images = [
|
||||
"images/mid/image1.png",
|
||||
"images/mid/image2.jpg",
|
||||
"images/mid/image3.png",
|
||||
"images/mid/image4.jpg",
|
||||
"images/mid/image5.png",
|
||||
"images/mid/image6.png",
|
||||
"images/mid/image7.png",
|
||||
"images/mid/image8.png",
|
||||
"images/mid/image9.gif",
|
||||
"images/mid/image10.jpg",
|
||||
"images/mid/image11.png",
|
||||
"images/mid/image12.jpg",
|
||||
"images/mid/image13.jpeg",
|
||||
"images/mid/image14.png",
|
||||
"images/mid/image15.PNG",
|
||||
"images/mid/image16.PNG",
|
||||
"images/mid/image21.jpg",
|
||||
"images/mid/image22.png",
|
||||
"images/mid/image23.png",
|
||||
"images/mid/image24.png",
|
||||
"images/mid/image25.png",
|
||||
"images/mid/image27.png",
|
||||
"images/mid/image28.jpg",
|
||||
"images/mid/image29.png",
|
||||
"images/mid/image31.jpg",
|
||||
"images/mid/image33.png",
|
||||
"images/mid/image35.jpg",
|
||||
"images/mid/image36.png",
|
||||
"images/mid/image37.png"
|
||||
];
|
||||
|
||||
shuffle(images);
|
||||
</script>
|
||||
|
||||
<main class="flex flex-col -m-10">
|
||||
|
||||
<section class="flex lg:flex-row flex-col gap-5 items-center justify-center py-3 font-mono">
|
||||
<h3 class="font-bold text-xl">Characters</h3>
|
||||
<hr class="rotate-90 w-10 border"/>
|
||||
<Button id="mid" text="Midnight" />
|
||||
<Button id="koffie" text="Koffie" />
|
||||
<Button id="martin" text="Martin" />
|
||||
<Button id="seffy" text="Seffy" />
|
||||
<Button id="sprocket" text="Sprocket" />
|
||||
<Button id="others" text="Others" />
|
||||
</section>
|
||||
|
||||
<div id="mid" class="bg-center bg-cover relative h-screen overflow-hidden">
|
||||
<section class="flex justify-end h-full absolute inset-0">
|
||||
<div class="w-1/2">
|
||||
<Splide
|
||||
options={options}
|
||||
>
|
||||
{#each images as image}
|
||||
<SplideSlide>
|
||||
<img src={image} alt="Mid" />
|
||||
</SplideSlide>
|
||||
{/each}
|
||||
</Splide>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="from-black via-black bg-gradient-to-r to-transparent absolute inset-0 p-10 pl-0">
|
||||
<section class="flex gap-10 flex-col w-1/2 border-l-8 border-blue-500 pb-10 pl-10">
|
||||
<h2 class="text-6xl font-bold">
|
||||
Midnight
|
||||
<span class="text-xs text-gray-400">//</span>
|
||||
<span class="text-base font-normal">Mid</span>
|
||||
<span class="text-xs text-gray-400">//</span>
|
||||
<span class="text-base font-normal">Midblep</span>
|
||||
</h2>
|
||||
<p class="text-lg italic leading-relaxed">
|
||||
Mid is a tall black cat. He is quite the gentleman but can get rough and dirty if need be. He is part of the Thallium military, working as an Engineer on the newest technologies.
|
||||
He has created his companion Truxton, which helps him through life.
|
||||
</p>
|
||||
<p class="text-lg italic leading-relaxed">
|
||||
In actuality however, Mid is a universal entity that transcends into the 4th dimension of time.
|
||||
His embodiment is a supermassive black hole that encompasses all of livable reality, its multiverses and alternate timelines and everything else.
|
||||
All of creation is a part of him, and so he often manifests inside of the infinite worlds inside of him as this black cat.
|
||||
However, it varies massively from reality to reality as he likes to artificially limit his own capabilities to enact some fun scenarios to cure his boredom with.
|
||||
These adventures often lead to growth, worship or other indulgences.
|
||||
</p>
|
||||
<p class="text-lg italic leading-relaxed">
|
||||
The God does have a weak spot though. Provoke him enough in places where it hurts most, like size, and another being may force its way out of him.
|
||||
That being is Shenrock, an utterly evil and destructive dark version of the cat. It will seek to permanently destroy and kill, corrupting everything in its path until it has gotten its revenge.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="koffie" class="bg-cover bg-right-bottom p-10 pl-0 h-screen" style="background-image: url('/koffie.png')">
|
||||
<section class="pl-10 pb-10 border-l-8 border-red-600 flex gap-10 flex-col">
|
||||
<h2 class="text-6xl font-bold">
|
||||
Koffie
|
||||
<span class="text-xs text-gray-400">//</span>
|
||||
<span class="text-base font-normal">Coffee</span>
|
||||
</h2>
|
||||
<p class="w-2/5 text-lg italic leading-relaxed">
|
||||
Koffie is one of Mid's accidental creations of life early on. He is a tall Rexouium with warm brown, black, white and orange colors that are themed after coffee.
|
||||
His body is made out of the substance of coffee, milk and similar things. He has partial control over its composition which makes him able to pour you a cup of coffee out of his fingers by temporarily making that part of him fluid.
|
||||
</p>
|
||||
<p class="w-2/5 text-lg italic leading-relaxed">
|
||||
Drinking or coming in contact with coffee-related substances will cause him to absorb it and grow in overall size.
|
||||
Unfortunately enough he is also an addict that will do anything to get a cup, and can smell coffee from miles away. But he is not shy to share if he's in a good mood.
|
||||
All of this coffee has also resulted in him becoming a complete Insomniac.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="bg-cover bg-center" style="background-image: url('/images/pattern5.png')">
|
||||
<div class="bg-amber-900 bg-opacity-50 h-screen">
|
||||
<div id="martin" class="flex justify-between p-10 pl-0 gap-10">
|
||||
<section class="pl-10 pb-10 border-l-8 border-orange-800 flex gap-10 flex-col w-1/2">
|
||||
<h2 class="text-6xl font-bold">Martin</h2>
|
||||
<p class="text-lg italic leading-relaxed">
|
||||
Martin is a short Pine Marten with brown fur that also works in the Thallium military.
|
||||
He is quite shy and unconfident, but loves to help Mid whenever he can and practically sees him as his big bro or dad considering he never had one.
|
||||
With a long flexible body he can fit in a lot of places which makes him very useful.
|
||||
</p>
|
||||
<p class="text-lg italic leading-relaxed">
|
||||
Martin has the special trait that if he is belittled or made fun of, his body can't help but start to steal the size of the parties that are making fun of him pretty much until he feels safe again.
|
||||
In particularly bad situations the ratio that is being converted might even be 2:1 or more, meaning he'll grow 2m for every meter stolen from a single person involved.
|
||||
The only way he is able to shrink back is with Truxton, which was the first machine able to compress someone's size just as it did for Mid.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="w-1/3">
|
||||
<img src="/martin2.png" class="rounded-2xl drop-shadow-2xl" />
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="seffy" class="bg-center bg-cover relative h-screen overflow-hidden" style="background-image: url('/images/seffy.png')">
|
||||
<section class="absolute inset-0 w-1/3 h-screen bg-black scale-150 -rotate-12">
|
||||
|
||||
</section>
|
||||
|
||||
<div class="absolute inset-0 bg-black bg-opacity-30 p-10 pl-0">
|
||||
<section class="pl-10 pb-10 border-l-8 border-white flex gap-10 flex-col">
|
||||
<h2 class="text-6xl font-bold">Seffy</h2>
|
||||
<p class="w-1/2 text-lg italic leading-relaxed">
|
||||
Seffy is a happy, but rather subby, Truxtion. He is an Electrical Engineer at a no-name company and is good at what he does.
|
||||
He is part of Batch 3 of the Truxtion shells and is uniquely modified. Instead of being hooked up to Truxton's network, Seffy has his own mind and internaly independent of the hive-mind.
|
||||
Seffy loves to attach various accessories to his modular body, most notably a set of tails. He is often seen with an oversized shark tail.
|
||||
</p>
|
||||
<p class="w-1/2 text-lg italic leading-relaxed">
|
||||
His biggest modification is to how he is powered. Inside he is entirely hollow to house his fuel. This fuel can be any liquid, as long as it has a form of energy to be consumed.
|
||||
Since Seffy was specially constructed to relieve Mid, this liquid often tends to be his cum. The inlet port is his tail, which can click off with a lock to reveal a hole.
|
||||
</p>
|
||||
<p class="w-1/2 text-lg italic leading-relaxed">
|
||||
Because Mid is very potent Seffy could never hold everything, so there is a way to relieve internal pressure to safe levels so he won't burst under the pressure.
|
||||
This is done by simply expanding his form, thus making him grow bigger. He returns back to normal as he empties out or uses the fuel over time.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section id="others" class="p-10 pl-0">
|
||||
<div class="pl-10 pb-10 border-l-8 border-zinc-600 flex flex-col gap-10">
|
||||
<h2 class="text-6xl font-bold">Other characters</h2>
|
||||
|
||||
<div class="grid grid-cols-3 gap-10">
|
||||
<div class="min-h-80 bg-neutral-700 p-5 rounded shadow-xl flex flex-col gap-5">
|
||||
<h2 class="text-4xl font-bold">Truxton</h2>
|
||||
<p class="italic leading-relaxed">
|
||||
Truxton is more of a mind than any physical thing.
|
||||
</p>
|
||||
</div>
|
||||
<div class="min-h-80 bg-neutral-700 p-5 rounded shadow-xl flex flex-col gap-5">
|
||||
<h2 class="text-4xl font-bold">Dunky</h2>
|
||||
<p class="italic leading-relaxed">
|
||||
Dunky is a sentient worm-on-a-string, one of those old toys. He has no mouth and cannot talk, but he can communicate effectively and makes for the best hugger.
|
||||
Though he is quite big, easily 10 meters in length, and could serve as a pillow or bed as well.
|
||||
</p>
|
||||
<p class="italic leading-relaxed">
|
||||
He likes to put things on his string almost like a tool slot.
|
||||
His pattern is themed after the Asexual flag, representing some of my feelings towards traditional physical intimacy.
|
||||
Because of that he is completely Safe For Work.
|
||||
</p>
|
||||
<img src="/dunky.png" class="rounded-lg" />
|
||||
</div>
|
||||
<div class="min-h-80 bg-neutral-700 p-5 rounded shadow-xl flex flex-col gap-5">
|
||||
<h2 class="text-4xl font-bold">Sprocket</h2>
|
||||
<p class="italic leading-relaxed">
|
||||
Mid is a universal entity that transcends even the 4th dimension, he can do anything from turning into other creatures to making himself and others hyper, to even manipulating the world and objects around him, his only rule is to not mess with souls as this tampers with the fabric of life itself. Mid can be any size he wants to be and can be in any scenario since he is reality itself, he only limits himself from his true godhood so his eternal existence doesn't get boring for him.
|
||||
</p>
|
||||
</div>
|
||||
<div class="min-h-80 bg-neutral-700 p-5 rounded shadow-xl flex flex-col gap-5">
|
||||
<h2 class="text-4xl font-bold">Shiba</h2>
|
||||
<p class="italic leading-relaxed">
|
||||
Mid is a universal entity that transcends even the 4th dimension, he can do anything from turning into other creatures to making himself and others hyper, to even manipulating the world and objects around him, his only rule is to not mess with souls as this tampers with the fabric of life itself. Mid can be any size he wants to be and can be in any scenario since he is reality itself, he only limits himself from his true godhood so his eternal existence doesn't get boring for him.
|
||||
</p>
|
||||
</div>
|
||||
<div class="min-h-80 bg-neutral-700 p-5 rounded shadow-xl flex flex-col gap-5">
|
||||
<h2 class="text-4xl font-bold">Friction</h2>
|
||||
<p class="italic leading-relaxed">
|
||||
Mid is a universal entity that transcends even the 4th dimension, he can do anything from turning into other creatures to making himself and others hyper, to even manipulating the world and objects around him, his only rule is to not mess with souls as this tampers with the fabric of life itself. Mid can be any size he wants to be and can be in any scenario since he is reality itself, he only limits himself from his true godhood so his eternal existence doesn't get boring for him.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
@ -0,0 +1,32 @@
|
||||
<script>
|
||||
import Socials from "$lib/Socials.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Home</title>
|
||||
</svelte:head>
|
||||
|
||||
<main>
|
||||
|
||||
<div class="relative mt-10 h-screen">
|
||||
<section class="absolute inset-0 triangle h-screen mx-auto bg-gradient-to-t from-amber-500 to-red-600 z-0"></section>
|
||||
|
||||
<div class="absolute inset-0 bg-cover h-96 rounded-xl -rotate-2 mt-20 bg-center w-8/12 mx-auto shadow-2xl" style="background-image: url('/esu/banner.jpg')">
|
||||
</div>
|
||||
|
||||
<div class="absolute h-96 inset-0 flex flex-col justify-center items-center mt-20">
|
||||
<h1 class="baron text-white text-9xl drop-shadow-xl">easter system <br/> <h2 class="baron text-white text-7xl ml-1">UNIVERSE</h2></h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<section class="h-screen bg-amber-500"></section>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<style>
|
||||
.triangle {
|
||||
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
|
||||
}
|
||||
</style>
|
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
import Socials from "$lib/Socials.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Home</title>
|
||||
</svelte:head>
|
||||
|
||||
<main />
|
@ -1,7 +0,0 @@
|
||||
<script>
|
||||
import Feed from "$lib/macromarch/Feed.svelte";
|
||||
|
||||
</script>
|
||||
<main>
|
||||
<Feed/>
|
||||
</main>
|
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
import Socials from "$lib/Socials.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Home</title>
|
||||
</svelte:head>
|
||||
|
||||
<main />
|
@ -0,0 +1,9 @@
|
||||
<script>
|
||||
import Socials from "$lib/Socials.svelte";
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Home</title>
|
||||
</svelte:head>
|
||||
|
||||
<main />
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 206 KiB |
Before Width: | Height: | Size: 6.3 MiB After Width: | Height: | Size: 6.3 MiB |
After Width: | Height: | Size: 5.7 MiB |
Before Width: | Height: | Size: 204 KiB After Width: | Height: | Size: 204 KiB |
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 161 KiB |
After Width: | Height: | Size: 229 KiB |
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 2.2 MiB |
Before Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 799 KiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 2.4 MiB |
Before Width: | Height: | Size: 3.0 MiB |
Before Width: | Height: | Size: 3.5 MiB |
Before Width: | Height: | Size: 139 KiB |
Before Width: | Height: | Size: 3.5 MiB |
Before Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 799 KiB |
Before Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 3.5 MiB |
Before Width: | Height: | Size: 152 KiB |
Before Width: | Height: | Size: 309 KiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 570 KiB |
Before Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 447 KiB |
Before Width: | Height: | Size: 773 KiB |
Before Width: | Height: | Size: 224 KiB |
Before Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 703 KiB |
Before Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 3.0 MiB |
Before Width: | Height: | Size: 163 KiB |
Before Width: | Height: | Size: 274 KiB |
Before Width: | Height: | Size: 2.1 MiB |
Before Width: | Height: | Size: 1.7 MiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 3.5 MiB |
Before Width: | Height: | Size: 3.0 MiB |
Before Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 3.0 MiB |
Before Width: | Height: | Size: 3.8 MiB |
Before Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 1.7 MiB |
@ -0,0 +1,540 @@
|
||||
var VanillaTilt = (function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Created by Sergiu Șandor (micku7zu) on 1/27/2017.
|
||||
* Original idea: https://github.com/gijsroge/tilt.js
|
||||
* MIT License.
|
||||
* Version 1.7.2
|
||||
*/
|
||||
|
||||
class VanillaTilt {
|
||||
constructor(element, settings = {}) {
|
||||
if (!(element instanceof Node)) {
|
||||
throw "Can't initialize VanillaTilt because " + element + ' is not a Node.';
|
||||
}
|
||||
|
||||
this.width = null;
|
||||
this.height = null;
|
||||
this.clientWidth = null;
|
||||
this.clientHeight = null;
|
||||
this.left = null;
|
||||
this.top = null;
|
||||
|
||||
// for Gyroscope sampling
|
||||
this.gammazero = null;
|
||||
this.betazero = null;
|
||||
this.lastgammazero = null;
|
||||
this.lastbetazero = null;
|
||||
|
||||
this.transitionTimeout = null;
|
||||
this.updateCall = null;
|
||||
this.event = null;
|
||||
|
||||
this.updateBind = this.update.bind(this);
|
||||
this.resetBind = this.reset.bind(this);
|
||||
|
||||
this.element = element;
|
||||
this.settings = this.extendSettings(settings);
|
||||
|
||||
this.reverse = this.settings.reverse ? -1 : 1;
|
||||
this.glare = VanillaTilt.isSettingTrue(this.settings.glare);
|
||||
this.glarePrerender = VanillaTilt.isSettingTrue(this.settings['glare-prerender']);
|
||||
this.fullPageListening = VanillaTilt.isSettingTrue(this.settings['full-page-listening']);
|
||||
this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope);
|
||||
this.gyroscopeSamples = this.settings.gyroscopeSamples;
|
||||
|
||||
this.elementListener = this.getElementListener();
|
||||
|
||||
if (this.glare) {
|
||||
this.prepareGlare();
|
||||
}
|
||||
|
||||
if (this.fullPageListening) {
|
||||
this.updateClientSize();
|
||||
}
|
||||
|
||||
this.addEventListeners();
|
||||
this.reset();
|
||||
this.updateInitialPosition();
|
||||
}
|
||||
|
||||
static isSettingTrue(setting) {
|
||||
return setting === '' || setting === true || setting === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method returns element what will be listen mouse events
|
||||
* @return {Node}
|
||||
*/
|
||||
getElementListener() {
|
||||
if (this.fullPageListening) {
|
||||
return window.document;
|
||||
}
|
||||
|
||||
if (typeof this.settings['mouse-event-element'] === 'string') {
|
||||
const mouseEventElement = document.querySelector(this.settings['mouse-event-element']);
|
||||
|
||||
if (mouseEventElement) {
|
||||
return mouseEventElement;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.settings['mouse-event-element'] instanceof Node) {
|
||||
return this.settings['mouse-event-element'];
|
||||
}
|
||||
|
||||
return this.element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method set listen methods for this.elementListener
|
||||
* @return {Node}
|
||||
*/
|
||||
addEventListeners() {
|
||||
this.onMouseEnterBind = this.onMouseEnter.bind(this);
|
||||
this.onMouseMoveBind = this.onMouseMove.bind(this);
|
||||
this.onMouseLeaveBind = this.onMouseLeave.bind(this);
|
||||
this.onWindowResizeBind = this.onWindowResize.bind(this);
|
||||
this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this);
|
||||
|
||||
this.elementListener.addEventListener('mouseenter', this.onMouseEnterBind);
|
||||
this.elementListener.addEventListener('mouseleave', this.onMouseLeaveBind);
|
||||
this.elementListener.addEventListener('mousemove', this.onMouseMoveBind);
|
||||
|
||||
if (this.glare || this.fullPageListening) {
|
||||
window.addEventListener('resize', this.onWindowResizeBind);
|
||||
}
|
||||
|
||||
if (this.gyroscope) {
|
||||
window.addEventListener('deviceorientation', this.onDeviceOrientationBind);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method remove event listeners from current this.elementListener
|
||||
*/
|
||||
removeEventListeners() {
|
||||
this.elementListener.removeEventListener('mouseenter', this.onMouseEnterBind);
|
||||
this.elementListener.removeEventListener('mouseleave', this.onMouseLeaveBind);
|
||||
this.elementListener.removeEventListener('mousemove', this.onMouseMoveBind);
|
||||
|
||||
if (this.gyroscope) {
|
||||
window.removeEventListener('deviceorientation', this.onDeviceOrientationBind);
|
||||
}
|
||||
|
||||
if (this.glare || this.fullPageListening) {
|
||||
window.removeEventListener('resize', this.onWindowResizeBind);
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
clearTimeout(this.transitionTimeout);
|
||||
if (this.updateCall !== null) {
|
||||
cancelAnimationFrame(this.updateCall);
|
||||
}
|
||||
|
||||
this.reset();
|
||||
|
||||
this.removeEventListeners();
|
||||
this.element.vanillaTilt = null;
|
||||
delete this.element.vanillaTilt;
|
||||
|
||||
this.element = null;
|
||||
}
|
||||
|
||||
onDeviceOrientation(event) {
|
||||
if (event.gamma === null || event.beta === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateElementPosition();
|
||||
|
||||
if (this.gyroscopeSamples > 0) {
|
||||
this.lastgammazero = this.gammazero;
|
||||
this.lastbetazero = this.betazero;
|
||||
|
||||
if (this.gammazero === null) {
|
||||
this.gammazero = event.gamma;
|
||||
this.betazero = event.beta;
|
||||
} else {
|
||||
this.gammazero = (event.gamma + this.lastgammazero) / 2;
|
||||
this.betazero = (event.beta + this.lastbetazero) / 2;
|
||||
}
|
||||
|
||||
this.gyroscopeSamples -= 1;
|
||||
}
|
||||
|
||||
const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX;
|
||||
const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY;
|
||||
|
||||
const degreesPerPixelX = totalAngleX / this.width;
|
||||
const degreesPerPixelY = totalAngleY / this.height;
|
||||
|
||||
const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero);
|
||||
const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero);
|
||||
|
||||
const posX = angleX / degreesPerPixelX;
|
||||
const posY = angleY / degreesPerPixelY;
|
||||
|
||||
if (this.updateCall !== null) {
|
||||
cancelAnimationFrame(this.updateCall);
|
||||
}
|
||||
|
||||
this.event = {
|
||||
clientX: posX + this.left,
|
||||
clientY: posY + this.top
|
||||
};
|
||||
|
||||
this.updateCall = requestAnimationFrame(this.updateBind);
|
||||
}
|
||||
|
||||
onMouseEnter() {
|
||||
this.updateElementPosition();
|
||||
this.element.style.willChange = 'transform';
|
||||
this.setTransition();
|
||||
}
|
||||
|
||||
onMouseMove(event) {
|
||||
if (this.updateCall !== null) {
|
||||
cancelAnimationFrame(this.updateCall);
|
||||
}
|
||||
|
||||
this.event = event;
|
||||
this.updateCall = requestAnimationFrame(this.updateBind);
|
||||
}
|
||||
|
||||
onMouseLeave() {
|
||||
this.setTransition();
|
||||
|
||||
if (this.settings.reset) {
|
||||
requestAnimationFrame(this.resetBind);
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.event = {
|
||||
clientX: this.left + this.width / 2,
|
||||
clientY: this.top + this.height / 2
|
||||
};
|
||||
|
||||
if (this.element && this.element.style) {
|
||||
this.element.style.transform =
|
||||
`perspective(${this.settings.perspective}px) ` +
|
||||
`rotateX(0deg) ` +
|
||||
`rotateY(0deg) ` +
|
||||
`scale3d(1, 1, 1)`;
|
||||
}
|
||||
|
||||
this.resetGlare();
|
||||
}
|
||||
|
||||
resetGlare() {
|
||||
if (this.glare) {
|
||||
this.glareElement.style.transform = 'rotate(180deg) translate(-50%, -50%)';
|
||||
this.glareElement.style.opacity = '0';
|
||||
}
|
||||
}
|
||||
|
||||
updateInitialPosition() {
|
||||
if (this.settings.startX === 0 && this.settings.startY === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onMouseEnter();
|
||||
|
||||
if (this.fullPageListening) {
|
||||
this.event = {
|
||||
clientX:
|
||||
((this.settings.startX + this.settings.max) / (2 * this.settings.max)) *
|
||||
this.clientWidth,
|
||||
clientY:
|
||||
((this.settings.startY + this.settings.max) / (2 * this.settings.max)) *
|
||||
this.clientHeight
|
||||
};
|
||||
} else {
|
||||
this.event = {
|
||||
clientX:
|
||||
this.left +
|
||||
((this.settings.startX + this.settings.max) / (2 * this.settings.max)) * this.width,
|
||||
clientY:
|
||||
this.top +
|
||||
((this.settings.startY + this.settings.max) / (2 * this.settings.max)) * this.height
|
||||
};
|
||||
}
|
||||
|
||||
let backupScale = this.settings.scale;
|
||||
this.settings.scale = 1;
|
||||
this.update();
|
||||
this.settings.scale = backupScale;
|
||||
this.resetGlare();
|
||||
}
|
||||
|
||||
getValues() {
|
||||
let x, y;
|
||||
|
||||
if (this.fullPageListening) {
|
||||
x = this.event.clientX / this.clientWidth;
|
||||
y = this.event.clientY / this.clientHeight;
|
||||
} else {
|
||||
x = (this.event.clientX - this.left) / this.width;
|
||||
y = (this.event.clientY - this.top) / this.height;
|
||||
}
|
||||
|
||||
x = Math.min(Math.max(x, 0), 1);
|
||||
y = Math.min(Math.max(y, 0), 1);
|
||||
|
||||
let tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2);
|
||||
let tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2);
|
||||
let angle =
|
||||
Math.atan2(
|
||||
this.event.clientX - (this.left + this.width / 2),
|
||||
-(this.event.clientY - (this.top + this.height / 2))
|
||||
) *
|
||||
(180 / Math.PI);
|
||||
|
||||
return {
|
||||
tiltX: tiltX,
|
||||
tiltY: tiltY,
|
||||
percentageX: x * 100,
|
||||
percentageY: y * 100,
|
||||
angle: angle
|
||||
};
|
||||
}
|
||||
|
||||
updateElementPosition() {
|
||||
let rect = this.element.getBoundingClientRect();
|
||||
|
||||
this.width = this.element.offsetWidth;
|
||||
this.height = this.element.offsetHeight;
|
||||
this.left = rect.left;
|
||||
this.top = rect.top;
|
||||
}
|
||||
|
||||
update() {
|
||||
let values = this.getValues();
|
||||
|
||||
this.element.style.transform =
|
||||
'perspective(' +
|
||||
this.settings.perspective +
|
||||
'px) ' +
|
||||
'rotateX(' +
|
||||
(this.settings.axis === 'x' ? 0 : values.tiltY) +
|
||||
'deg) ' +
|
||||
'rotateY(' +
|
||||
(this.settings.axis === 'y' ? 0 : values.tiltX) +
|
||||
'deg) ' +
|
||||
'scale3d(' +
|
||||
this.settings.scale +
|
||||
', ' +
|
||||
this.settings.scale +
|
||||
', ' +
|
||||
this.settings.scale +
|
||||
')';
|
||||
|
||||
if (this.glare) {
|
||||
this.glareElement.style.transform = `rotate(${values.angle}deg) translate(-50%, -50%)`;
|
||||
this.glareElement.style.opacity = `${
|
||||
(values.percentageY * this.settings['max-glare']) / 100
|
||||
}`;
|
||||
}
|
||||
|
||||
this.element.dispatchEvent(
|
||||
new CustomEvent('tiltChange', {
|
||||
detail: values
|
||||
})
|
||||
);
|
||||
|
||||
this.updateCall = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the glare element (if glarePrerender equals false)
|
||||
* and sets the default style
|
||||
*/
|
||||
prepareGlare() {
|
||||
// If option pre-render is enabled we assume all html/css is present for an optimal glare effect.
|
||||
if (!this.glarePrerender) {
|
||||
// Create glare element
|
||||
const jsTiltGlare = document.createElement('div');
|
||||
jsTiltGlare.classList.add('js-tilt-glare');
|
||||
|
||||
const jsTiltGlareInner = document.createElement('div');
|
||||
jsTiltGlareInner.classList.add('js-tilt-glare-inner');
|
||||
|
||||
jsTiltGlare.appendChild(jsTiltGlareInner);
|
||||
this.element.appendChild(jsTiltGlare);
|
||||
}
|
||||
|
||||
this.glareElementWrapper = this.element.querySelector('.js-tilt-glare');
|
||||
this.glareElement = this.element.querySelector('.js-tilt-glare-inner');
|
||||
|
||||
if (this.glarePrerender) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.assign(this.glareElementWrapper.style, {
|
||||
position: 'absolute',
|
||||
top: '0',
|
||||
left: '0',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
overflow: 'hidden',
|
||||
'pointer-events': 'none'
|
||||
});
|
||||
|
||||
Object.assign(this.glareElement.style, {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
'pointer-events': 'none',
|
||||
'background-image': `linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)`,
|
||||
transform: 'rotate(180deg) translate(-50%, -50%)',
|
||||
'transform-origin': '0% 0%',
|
||||
opacity: '0'
|
||||
});
|
||||
|
||||
this.updateGlareSize();
|
||||
}
|
||||
|
||||
updateGlareSize() {
|
||||
if (this.glare) {
|
||||
const glareSize =
|
||||
(this.element.offsetWidth > this.element.offsetHeight
|
||||
? this.element.offsetWidth
|
||||
: this.element.offsetHeight) * 2;
|
||||
|
||||
Object.assign(this.glareElement.style, {
|
||||
width: `${glareSize}px`,
|
||||
height: `${glareSize}px`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
updateClientSize() {
|
||||
this.clientWidth =
|
||||
window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
|
||||
this.clientHeight =
|
||||
window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
|
||||
}
|
||||
|
||||
onWindowResize() {
|
||||
this.updateGlareSize();
|
||||
this.updateClientSize();
|
||||
}
|
||||
|
||||
setTransition() {
|
||||
clearTimeout(this.transitionTimeout);
|
||||
this.element.style.transition = this.settings.speed + 'ms ' + this.settings.easing;
|
||||
if (this.glare)
|
||||
this.glareElement.style.transition = `opacity ${this.settings.speed}ms ${this.settings.easing}`;
|
||||
|
||||
this.transitionTimeout = setTimeout(() => {
|
||||
this.element.style.transition = '';
|
||||
if (this.glare) {
|
||||
this.glareElement.style.transition = '';
|
||||
}
|
||||
}, this.settings.speed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method return patched settings of instance
|
||||
* @param {boolean} settings.reverse - reverse the tilt direction
|
||||
* @param {number} settings.max - max tilt rotation (degrees)
|
||||
* @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0
|
||||
* @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0
|
||||
* @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets
|
||||
* @param {string} settings.easing - Easing on enter/exit
|
||||
* @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc..
|
||||
* @param {number} settings.speed - Speed of the enter/exit transition
|
||||
* @param {boolean} settings.transition - Set a transition on enter/exit
|
||||
* @param {string|null} settings.axis - What axis should be disabled. Can be X or Y
|
||||
* @param {boolean} settings.glare - What axis should be disabled. Can be X or Y
|
||||
* @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
|
||||
* @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise
|
||||
* @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
|
||||
* @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events
|
||||
* @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit
|
||||
* @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events
|
||||
* @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc..
|
||||
* @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position.
|
||||
*/
|
||||
extendSettings(settings) {
|
||||
let defaultSettings = {
|
||||
reverse: false,
|
||||
max: 15,
|
||||
startX: 0,
|
||||
startY: 0,
|
||||
perspective: 1000,
|
||||
easing: 'cubic-bezier(.03,.98,.52,.99)',
|
||||
scale: 1,
|
||||
speed: 300,
|
||||
transition: true,
|
||||
axis: null,
|
||||
glare: false,
|
||||
'max-glare': 1,
|
||||
'glare-prerender': false,
|
||||
'full-page-listening': false,
|
||||
'mouse-event-element': null,
|
||||
reset: true,
|
||||
gyroscope: true,
|
||||
gyroscopeMinAngleX: -45,
|
||||
gyroscopeMaxAngleX: 45,
|
||||
gyroscopeMinAngleY: -45,
|
||||
gyroscopeMaxAngleY: 45,
|
||||
gyroscopeSamples: 10
|
||||
};
|
||||
|
||||
let newSettings = {};
|
||||
for (var property in defaultSettings) {
|
||||
if (property in settings) {
|
||||
newSettings[property] = settings[property];
|
||||
} else if (this.element.hasAttribute('data-tilt-' + property)) {
|
||||
let attribute = this.element.getAttribute('data-tilt-' + property);
|
||||
try {
|
||||
newSettings[property] = JSON.parse(attribute);
|
||||
} catch (e) {
|
||||
newSettings[property] = attribute;
|
||||
}
|
||||
} else {
|
||||
newSettings[property] = defaultSettings[property];
|
||||
}
|
||||
}
|
||||
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
static init(elements, settings) {
|
||||
if (elements instanceof Node) {
|
||||
elements = [elements];
|
||||
}
|
||||
|
||||
if (elements instanceof NodeList) {
|
||||
elements = [].slice.call(elements);
|
||||
}
|
||||
|
||||
if (!(elements instanceof Array)) {
|
||||
return;
|
||||
}
|
||||
|
||||
elements.forEach((element) => {
|
||||
if (!('vanillaTilt' in element)) {
|
||||
element.vanillaTilt = new VanillaTilt(element, settings);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
/* expose the class to window */
|
||||
window.VanillaTilt = VanillaTilt;
|
||||
|
||||
/**
|
||||
* Auto load
|
||||
*/
|
||||
VanillaTilt.init(document.querySelectorAll('[data-tilt]'));
|
||||
}
|
||||
|
||||
return VanillaTilt;
|
||||
})();
|