devo-book/index.html
2021-08-05 09:47:17 -04:00

348 lines
9.8 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<style>
body
{
margin:0;
}
section
{
position:relative;
height: 100vh;
box-sizing: border-box;
padding:50px;
}
nav
{
position:fixed;
right:50px;
bottom:50px;
z-index:10;
}
h2
{
width:500px;
margin:0 auto;
text-align:center;
}
h2[data-spy='true']
{
background:black;
color: white;;
}
</style>
<script>
var Time =
{
Jobs:[],
Stamp:false,
Queue:false,
Loop:false,
Add:function(inJob)
{
if(Time.Loop)
{
console.log("cannot modify queue while processing");
return;
}
if(!Time.Queue)
{
window.requestAnimationFrame(Time.Update);
}
Time.Queue = true;
Time.Jobs.push(inJob);
},
Remove:function(inJob)
{
if(Time.Loop)
{
console.log("cannot modify queue while processing");
return;
}
var index = Time.Jobs.indexOf(inJob);
if(index > -1)
{
Time.Jobs.splice(index, 1);
}
},
Update:function(inTimestamp)
{
var delta;
var i;
if(!Time.Stamp)
{
Time.Stamp = inTimestamp;
}
delta = inTimestamp - Time.Stamp;
Time.Stamp = inTimestamp;
Time.Loop = true;
for(i=0; i<Time.Jobs.length; i++)
{
if(Time.Jobs[i](delta) === false)
{
Time.Jobs.splice(i, 1);
i--;
}
}
Time.Loop = false;
if(Time.Jobs.length > 0)
{
window.requestAnimationFrame(Time.Update);
}
else
{
Time.Stamp = false;
Time.Queue = false;
}
}
};
</script>
<script>
var Spy =
{
Attribute:"data-spy",
Members:[],
Defaults:[0, 1, 0, 1],
Disabled:false,
Suspend:function()
{
Spy.Disabled = true;
},
Resume:function()
{
Spy.Disabled = false;
Spy.UpdateAll();
},
UpdateAll:function()
{
var i, member, aabb, top, bottom, left, right;
var visible;
if(Spy.Disabled){ return; }
for(i=0; i<Spy.Members.length; i++)
{
member = Spy.Members[i];
top = window.innerHeight * member.Bounds[0];
bottom = window.innerHeight * member.Bounds[1];
left = window.innerWidth * member.Bounds[2];
right = window.innerWidth * member.Bounds[3];
aabb = member.Element.getBoundingClientRect();
visible = (aabb.top < bottom && aabb.bottom > top) && (aabb.left < right && aabb.right > left);
if(visible != member.Visible)
{
member.Element.setAttribute(Spy.Attribute, visible);
member.Visible = visible;
member.Change(visible);
}
}
},
Create:function(inElement)
{
var j, bounds;
var attr;
var obj;
attr = inElement.getAttribute(Spy.Attribute)||"";
inElement.removeAttribute(Spy.Attribute);
bounds = attr.split("|");
for(j=0; j<Spy.Defaults.length; j++)
{
if(bounds[j])
{
bounds[j] = parseFloat(bounds[j]);
}
else
{
bounds[j] = Spy.Defaults[j];
}
}
obj = {
Element:inElement,
Bounds:bounds,
Visible:undefined,
Change:function(){}
};
Spy.Members.push(obj);
return obj;
},
CreateAll:function()
{
var i, elements;
elements = document.querySelectorAll("*["+Spy.Attribute+"]");
for(i=0; i<elements.length; i++)
{
Spy.Create(elements[i]);
}
},
Init:function()
{
Spy.CreateAll();
Spy.UpdateAll();
document.addEventListener("scroll", Spy.UpdateAll, {passive:true});
window.addEventListener("resize", Spy.UpdateAll, {passive:true});
}
};
</script>
</head>
<body>
<nav>
<a href="#top" >Top</a>
<a href="#order">Order</a>
<a href="#video">Video</a>
<a href="#about">About</a>
<a href="#specs">Specs</a>
<a href="#email">Sign-up</a>
</nav>
<section id="order">
<style>
.shot3d
{
transform: perspective(1000px) rotateY(25deg);
transform-style: preserve-3d;
perspective-origin: 50% 50%;
position: relative;
width: 350px;
height: 350px;
line-height: 350px;
text-align:center;
white-space: nowrap;
}
.shot3d__shadow
{
display: inline;
position: relative;
font-size: 0px;
line-height:0;
vertical-align: bottom;
}
.shot3d__shadow::after, .shot3d__shadow::before
{
transform-origin: center 30px;
position: absolute;
padding: 0 6px 0 6px;
content: " ";
top: 100%;
left: -6px;
width: 100%;
height: 6px;
border-radius: 6px;
box-shadow: 0px 30px 14px black, 0px 43px 22px black, 0px 60px 33px black;
}
.shot3d__shadow::before{ transform: translateY(-30px) rotateX(-90deg) translateY( 5px); }
.shot3d__shadow::after { transform: translateY(-30px) rotateX( 90deg) translateY( 5px); }
.shot3d__shadow img
{
vertical-align: bottom;
display: inline;
max-width: 100%;
max-height: 100%;
}
</style>
<div class="shot3d">
<div class="shot3d__shadow">
<!-- <img src="https://truthforlife.org/static/images/productimage-picture-encore-2021-9729.jpg"/> -->
<div>
<img src="https://placekitten.com/100/200"/>
<img class="panel panel--front" src="https://placekitten.com/400/800"/>
</div>
</div>
<h2 data-spy="0.2|0.8">Order</h2>
<h3>Truth For Life</h3>
<h4>365 Daily Devotionals</h4>
<h5>by Alistair Begg</h5>
<p>
Duis augue neque, dignissim at diam ac, mattis cursus justo. Morbi blandit in ligula eu scelerisque.
Maecenas hendrerit eu nunc non molestie. Vivamus augue enim, egestas a magna vitae, consequat facilisis urna.
Nullam semper ligula in est tincidunt, vel fringilla nunc vehicula. Nam tempus pellentesque ante, nec iaculis nisi porta id.
Ut aliquet purus nec mi egestas ornare.
</p>
<a href="https://truthforlife.org/store/buy/">Buy Now</a>
<span>$10.00 (free shipping)</span>
</section>
<section id="video">
<h2 data-spy="0.2|0.8">Videos</h2>
</section>
<section id="about">
<h2 data-spy="0.2|0.8">About</h2>
<p>
Duis augue neque, dignissim at diam ac, mattis cursus justo. Morbi blandit in ligula eu scelerisque.
Maecenas hendrerit eu nunc non molestie. Vivamus augue enim, egestas a magna vitae, consequat facilisis urna.
Nullam semper ligula in est tincidunt, vel fringilla nunc vehicula. Nam tempus pellentesque ante, nec iaculis nisi porta id.
Ut aliquet purus nec mi egestas ornare.
</p>
<ul>
<li>
<strong>Head</strong><p>Nam tempus pellentesque ante, nec iaculis nisi porta id.</p>
</li>
<li>
<strong>Hands</strong><p>Vivamus augue enim, egestas a magna vitae, consequat facilisis urna.</p>
</li>
<li>
<strong>Heart</strong><p>Morbi blandit in ligula eu scelerisque. Maecenas hendrerit eu nunc non molestie.</p>
</li>
</ul>
<a href="#">Look Inside</a>
</section>
<section id="specs">
<h2 data-spy="0.2|0.8">Specs</h2>
</section>
<section id="email">
<h2 data-spy="0.2|0.8">Sign Up</h2>
</section>
<script>
Spy.Init();
function JobDuration(inDuration, inHandler, inDone)
{
var timeCurrent = 0;
var timeLimit = inDuration*1000;
var timeRelative = 0;
var timeMaxed = false;
return function(inDelta)
{
timeCurrent += inDelta;
timeMaxed = timeCurrent > timeLimit;
if(timeMaxed)
{
inHandler(1);
inDone();
return false;
}
return inHandler(timeCurrent / timeLimit);
};
}
document.querySelector("nav").addEventListener("click", function(inEvent)
{
var domHtml = document.querySelector("html");
var domGoal = document.querySelector(inEvent.target.getAttribute("href"));
var posStart = domHtml.scrollTop;
var posRange = domGoal.getBoundingClientRect().top;
var evtTick = function(inProgress){ domHtml.scrollTop = posStart + posRange*Math.sqrt(1 - Math.pow(1-(inProgress), 2)); };
var evtDone = function(){ Spy.Resume(); };
Spy.Suspend();
Time.Add( JobDuration(0.4, evtTick, evtDone) );
inEvent.preventDefault();
});
</script>
</body>
</html>