Add animated hero according to design spec, fixes #78

This commit is contained in:
Alistair 2018-06-30 17:51:00 +12:00 committed by Tobias Schulmann
parent 99c74f1ccc
commit d32a609def
4 changed files with 248 additions and 19 deletions

View file

@ -10,13 +10,30 @@ crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js" <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"
integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="
crossorigin=""></script> crossorigin=""></script>
{% endblock %} {% endblock %}
{% block body_out %} {% block body_out %}
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<img src="{% static 'assets/Header_placeholder.jpg' %}" id="hero"> <div class="content">
<h1 class="text-primary text-upper" id="loe-wrapper" style="z-index: 1;">
Linux <br />
<span id="of">of</span><br />
<span id="word" style="color: #ccd5c5;"></span>
</h1>
<canvas id="hero" style="z-index: -1;" width="0" height="0"></canvas>
<div>
<h1 id="things-heading" class="text-primary text-upper">Things</h1>
</div>
<div class="text-primary" id="bottom-wrapper" style="z-index: 1;">
<h2>21-25<br/>Jan 19<br/></h2>
<h4><small>University of Canterbury<br/>Christchurch, New Zealand</small></h4>
</div>
<a id="register-link" class="btn btn-secondary border-primary text-primary" href="/dashboard/">Register</a>
</div>
</div> </div>
</div> </div>
@ -29,7 +46,7 @@ crossorigin=""></script>
<div><img src="{% static 'assets/memorial.jpg' %}" /></div> <div><img src="{% static 'assets/memorial.jpg' %}" /></div>
</div> </div>
</div> </div>
<div class="col-12 col-xl-6 content pt-5 pb-xl-5"> <div class="col-12 col-xl-6 content pt-5 pb-xl-5">
<p> <p>
Themed <strong>Linux of Things</strong>, the 2019 linux.conf.au will again attract speakers and attendees from across the world to socialise, fraternise, lecture, listen, ask, answer and share with their peers. Themed <strong>Linux of Things</strong>, the 2019 linux.conf.au will again attract speakers and attendees from across the world to socialise, fraternise, lecture, listen, ask, answer and share with their peers.
@ -61,6 +78,8 @@ crossorigin=""></script>
{% endblock %} {% endblock %}
{% block extra_body %} {% block extra_body %}
<script src="{% static 'js/lot_word.js' %}" type="text/javascript"></script>
<script src="{% static 'js/lot_hero.js' %}" type="text/javascript"></script>
<script> <script>
var map = L.map('map', var map = L.map('map',
{ {

171
static/src/js/lot_hero.js Normal file
View file

@ -0,0 +1,171 @@
function hero() {
var timeouts = new Array(3);
let green = "#0F7C11";
let radius = 7;
let windowWidth;
let breakPoint = 768;
var loeWrapper = document.getElementById("loe-wrapper");
var loeOf = document.getElementById("of");
var canvas = document.getElementById("hero");
var bottomWrapper = document.getElementById("bottom-wrapper");
var registerLink = document.getElementById("register-link");
var thingsHeading = document.getElementById("things-heading");
var ctx = canvas.getContext("2d");
var canvasPadding = 10;
function positionRegisterLink() {
registerLink.style.position = 'static';
registerLink.style.float = 'none';
var offset = registerLink.offsetTop - loeOf.offsetTop - 0.25 * loeOf.offsetHeight;
if (window.innerWidth >= breakPoint) {
registerLink.style.top = -1 * offset + 'px';
registerLink.style.position = 'relative';
registerLink.style.float = 'right';
}
}
function getCanvasPos() {
var canvasRatio = window.innerWidth < 576 ? 1.1 : 2.5;
var width = loeWrapper.offsetWidth - loeOf.offsetWidth - (2 * canvasPadding);
var minHeight = 180;
if (window.innerWidth >= breakPoint) {
width -= registerLink.offsetWidth;
minHeight = 260;
}
return {
width: width,
height: Math.max(width / canvasRatio, minHeight),
left: loeOf.offsetWidth + canvasPadding,
top: -1.25 * loeOf.offsetHeight,
}
}
function sizeCanvas(pos) {
var c = canvas;
c.width = pos.width;
c.height = pos.height;
c.style.width = pos.width + 'px';
c.style.height = pos.height + 'px';
c.style.position = 'relative';
c.style.left = pos.left + 'px';
c.style.top = pos.top + 'px';
c.style.marginBottom = c.style.top;
}
function positionThingsHeading() {
thingsHeading.style.position = 'relative';
thingsHeading.style.display = 'inline-block';
var left = canvas.offsetWidth - thingsHeading.offsetWidth
if(window.innerWidth >= breakPoint) {
left += registerLink.offsetWidth;
}
thingsHeading.style.left = left + 'px';
thingsHeading.style.top = -0.7 * thingsHeading.offsetHeight + 'px';
thingsHeading.style.marginBottom = thingsHeading.style.top;
}
function positionDate() {
bottomWrapper.style.position = 'static';
bottomWrapper.style.marginBottom = 0;
var offs = -0.7 * thingsHeading.offsetHeight;
offs -= bottomWrapper.offsetHeight * 0.8;
if (window.innerWidth >= 576) {
bottomWrapper.style.position = 'relative';
bottomWrapper.style.top = offs + 'px';
bottomWrapper.style.marginBottom = offs + 20 + 'px';
}
}
let drawLine = (ind, context, startX, startY, endX, endY, color) => {
let dx = startX - endX;
let dy = startY - endY;
let theta = Math.atan2(dy, dx);
var x = startX - 15 * Math.cos(theta);
var y = startY - 15 * Math.sin(theta);
endX = endX + 30 * Math.cos(theta);
endY = endY + 30 * Math.sin(theta)
let delay = 8;
let increments = 2080 / delay;
let xAdjust = (endX - startX) / increments;
let yAdjust = (endY - startY) / increments;
let counter = 1;
let line = () => {
context.beginPath();
context.lineWidth = 1.9;
context.moveTo(x, y);
x = x + xAdjust;
y = y + yAdjust;
context.lineTo(x, y);
context.strokeStyle = color;
context.stroke();
counter++;
if (counter <= increments) {
timeouts[ind] = window.setTimeout(line, delay);
}
};
timeouts[ind] = window.setTimeout(line, delay);
}
let drawCircle = (context, x, y, radius, color) => {
context.beginPath();
context.fillStyle = color;
context.arc(x, y, radius, 0, 2 * Math.PI);
context.fill();
}
function windowResize() {
if(window.innerWidth === windowWidth) {
// Catch mobile scroll event, as this can hide/unhide the address
// bar and fire a resize event.
return;
} else {
windowWidth = window.innerWidth;
}
for(var i = 0; i < 3; i++) {
window.clearTimeout(timeouts[i]);
}
var canvasPos = getCanvasPos();
sizeCanvas(canvasPos)
positionThingsHeading();
positionDate();
function getLowestPoint() {
var pos = thingsHeading.offsetLeft - canvas.offsetLeft - 20;
if(pos < 10) {
pos = thingsHeading.offsetLeft + 0.5 * thingsHeading.offsetWidth;
}
return pos
}
let points = [
[10, 10],
[canvasPos.width - 10, 10],
[
getLowestPoint(),
canvasPos.height -10
]
];
positionRegisterLink();
drawCircle(ctx, points[0][0], points[0][1], radius, green);
drawCircle(ctx, points[1][0], points[1][1], radius, green);
drawCircle(ctx, points[2][0], points[2][1], radius, green);
drawLine(0, ctx, points[0][0], points[0][1], points[2][0], points[2][1], green);
drawLine(1, ctx, points[2][0], points[2][1], points[1][0], points[1][1], green);
drawLine(2, ctx, points[1][0], points[1][1], points[0][0], points[0][1], green);
}
windowResize();
window.addEventListener('resize', windowResize, false);
}
hero();

19
static/src/js/lot_word.js Normal file
View file

@ -0,0 +1,19 @@
function loeWord() {
var wordlist = ["health", "environment", "security", "communication", "people",];
var target = document.getElementById("word");
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
function setWord() {
target.innerText = wordlist[i%wordlist.length]
i += 1;
}
var i = getRandomInt(wordlist.length);
setWord()
setInterval(setWord, 5000)
};
loeWord();

View file

@ -20,15 +20,7 @@ body {
overflow-x: hidden; overflow-x: hidden;
} }
.navbar-brand {
width: 200px;
img {
max-width: 100%;
height: auto;
}
}
.text-page { .text-page {
h2 { h2 {
@ -71,17 +63,43 @@ html {
font-size: 16px; font-size: 16px;
} }
@import "nav.scss";
@import "bootstrap.scss";
h1 {
@include media-breakpoint-down(md) {
font-size: 3rem;
}
}
.navbar-brand {
@include media-breakpoint-up(md) {
width: 200px;
img {
max-width: 100%;
height: auto;
}
}
img {
padding-left: $padding-left-default / 3;
}
}
footer { footer {
margin-top: 12rem; margin-top: 12rem;
padding-left: $padding-left-default; padding-left: $padding-left-default / 3 !important;
color: $primary; color: $primary;
font-size: 0.81rem font-size: 0.81rem;
@include media-breakpoint-up(md) {
padding-left: $padding-left-default !important;
}
} }
#hero { #hero {
width: 100%; width: 100%;
padding-left: $padding-left-default;
padding-right: 5.3125rem;
} }
.green-block { .green-block {
@ -107,12 +125,10 @@ main.container-fluid {
padding: 0; padding: 0;
} }
@import "nav.scss";
@import "bootstrap.scss";
.content { .content {
//padding-top: 1rem;
padding-bottom: 1rem; padding-bottom: 1rem;
padding-left: $padding-left-default / 3 !important; padding-left: $padding-left-default / 3 !important;
padding-right: $padding-left-default / 3 !important; padding-right: $padding-left-default / 3 !important;
@ -266,3 +282,7 @@ label.list-label {
color: $primary; color: $primary;
} }
} }
nav.navbar {
margin-bottom: 0;
}