210 lines
4.7 KiB
HTML
210 lines
4.7 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<style>
|
||
|
body
|
||
|
{
|
||
|
margin:0;
|
||
|
}
|
||
|
section
|
||
|
{
|
||
|
position:relative;
|
||
|
height: 100vh;
|
||
|
box-sizing: border-box;
|
||
|
}
|
||
|
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>
|
||
|
</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="video">
|
||
|
<h2 data-spy="0.2|0.8">Videos</h2>
|
||
|
</section>
|
||
|
<section id="about">
|
||
|
<h2 data-spy="0.2|0.8">About</h2>
|
||
|
</section>
|
||
|
<section id="specs">
|
||
|
<h2 data-spy="0.2|0.8">Specs</h2>
|
||
|
</section>
|
||
|
<script>
|
||
|
var Time =
|
||
|
{
|
||
|
Jobs:[],
|
||
|
Stamp:false,
|
||
|
Queue:false,
|
||
|
Add:function(inJob)
|
||
|
{
|
||
|
if(!Time.Queue)
|
||
|
{
|
||
|
window.requestAnimationFrame(Time.Update);
|
||
|
}
|
||
|
Time.Queue = true;
|
||
|
Time.Jobs.push(inJob);
|
||
|
},
|
||
|
Update:function(inTimestamp)
|
||
|
{
|
||
|
var delta;
|
||
|
var i;
|
||
|
|
||
|
if(!Time.Stamp)
|
||
|
{
|
||
|
Time.Stamp = inTimestamp;
|
||
|
}
|
||
|
delta = inTimestamp - Time.Stamp;
|
||
|
Time.Stamp = inTimestamp;
|
||
|
|
||
|
for(i=0; i<Time.Jobs.length; i++)
|
||
|
{
|
||
|
if(!Time.Jobs[i](delta))
|
||
|
{
|
||
|
Time.Jobs.splice(i, 1);
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(Time.Jobs.length > 0)
|
||
|
{
|
||
|
window.requestAnimationFrame(Time.Update);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Time.Stamp = false;
|
||
|
Time.Queue = false;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function JobConic(inFrom, inRange, inDuration, inHandler)
|
||
|
{
|
||
|
var timeCurrent = 0;
|
||
|
var timeLimit = inDuration*1000;
|
||
|
var timeRelative = 0;
|
||
|
var timeMaxed = false;
|
||
|
return function(inDelta)
|
||
|
{
|
||
|
timeCurrent += inDelta;
|
||
|
timeMaxed = timeCurrent > timeLimit;
|
||
|
if(timeMaxed){ timeCurrent = timeLimit; }
|
||
|
timeRelative = timeCurrent / timeLimit;
|
||
|
inHandler(inFrom + inRange*Math.sqrt(1 - Math.pow(1-(timeRelative), 2)));
|
||
|
return !timeMaxed;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
|
||
|
document.querySelector("nav").addEventListener("click", function(inEvent)
|
||
|
{
|
||
|
var href = inEvent.target.getAttribute("href");
|
||
|
var html = document.querySelector("html");
|
||
|
var goal = document.querySelector(href).getBoundingClientRect().top;
|
||
|
|
||
|
Time.Add( JobConic(html.scrollTop, goal, 0.4, function(inOutput){ html.scrollTop = inOutput; } ) );
|
||
|
inEvent.preventDefault();
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
<script>
|
||
|
var Spy =
|
||
|
{
|
||
|
Attribute:"data-spy",
|
||
|
Members:[],
|
||
|
Defaults:[0, 1, 0, 1],
|
||
|
UpdateAll:function()
|
||
|
{
|
||
|
var i, member, aabb, top, bottom, left, right;
|
||
|
var visible;
|
||
|
|
||
|
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});
|
||
|
}
|
||
|
};
|
||
|
Spy.Init();
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|