Changed up the theme a lot added another simulation
This commit is contained in:
parent
7919aeefdb
commit
8c681f06e3
11 changed files with 232 additions and 113 deletions
|
|
@ -2,8 +2,5 @@
|
||||||
title: "Greeter"
|
title: "Greeter"
|
||||||
date: 2023-10-15T21:48:35+01:00
|
date: 2023-10-15T21:48:35+01:00
|
||||||
---
|
---
|
||||||
### Hi, I'm Warwick. And I:
|
# Warwick
|
||||||
- Make Games
|
Graphics, Games, Web, Education
|
||||||
- Make Websites
|
|
||||||
- Research Papers
|
|
||||||
- Teach Computing at Falmouth University
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
---
|
|
||||||
title: "Hello World!"
|
|
||||||
date: 2023-10-15 20:25:14.038 +0100
|
|
||||||
thumbnail: /img/fof.png
|
|
||||||
---
|
|
||||||
|
|
||||||
# Hello World!
|
|
||||||
Eyy *Finger Guns*
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
title: "Hello World!"
|
|
||||||
date: 2023-10-15 20:25:14.038 +0100
|
|
||||||
---
|
|
||||||
|
|
||||||
# Hello World!
|
|
||||||
Eyy *Finger Guns*
|
|
||||||
|
|
@ -11,19 +11,32 @@
|
||||||
|
|
||||||
#greeter {
|
#greeter {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: space-around;
|
||||||
|
align-content: space-around;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: stretch;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
animation: 1s ease-out 0s 1 slideInLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
#greeter-sim {
|
||||||
|
flex-grow: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#greeter-sim * {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#greeter-content {
|
#greeter-content {
|
||||||
padding: 5%;
|
padding: 2%;
|
||||||
margin: 5% 5% 5% 50%;
|
margin: 0;
|
||||||
animation: 1s ease-out 0s 1 slideInLeft;
|
flex-grow: 2;
|
||||||
background: var(--paper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 950px){
|
@media (max-width: 950px){
|
||||||
|
|
@ -59,45 +72,45 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes down-arrow-before {
|
@-webkit-keyframes down-arrow-before {
|
||||||
50% {
|
50% {
|
||||||
transform: rotate(45deg) translate(70%, 70%);
|
transform: rotate(45deg) translate(70%, 70%);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: rotate(45deg) translate(70%, 70%);
|
transform: rotate(45deg) translate(70%, 70%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes down-arrow-before {
|
@keyframes down-arrow-before {
|
||||||
50% {
|
50% {
|
||||||
transform: rotate(45deg) translate(70%, 70%);
|
transform: rotate(45deg) translate(70%, 70%);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: rotate(45deg) translate(70%, 70%);
|
transform: rotate(45deg) translate(70%, 70%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@-webkit-keyframes down-arrow-after {
|
@-webkit-keyframes down-arrow-after {
|
||||||
50% {
|
50% {
|
||||||
transform: rotate(45deg) translate(110%, 110%);
|
transform: rotate(45deg) translate(110%, 110%);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
51% {
|
51% {
|
||||||
transform: rotate(45deg) translate(-130%, -130%);
|
transform: rotate(45deg) translate(-130%, -130%);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: rotate(45deg) translate(-70%, -70%);
|
transform: rotate(45deg) translate(-70%, -70%);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@keyframes down-arrow-after {
|
@keyframes down-arrow-after {
|
||||||
50% {
|
50% {
|
||||||
transform: rotate(45deg) translate(110%, 110%);
|
transform: rotate(45deg) translate(110%, 110%);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
51% {
|
51% {
|
||||||
transform: rotate(45deg) translate(-130%, -130%);
|
transform: rotate(45deg) translate(-130%, -130%);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: rotate(45deg) translate(-70%, -70%);
|
transform: rotate(45deg) translate(-70%, -70%);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,29 +16,19 @@ h4 {font-size: 1.777rem; /* 28.48px */}
|
||||||
h5 {font-size: 1.333rem; /* 21.28px */}
|
h5 {font-size: 1.333rem; /* 21.28px */}
|
||||||
small {font-size: 0.750rem; /* 12px */}
|
small {font-size: 0.750rem; /* 12px */}
|
||||||
|
|
||||||
/* Colour Scheme stuff
|
|
||||||
:root[data-theme="light"] {
|
|
||||||
--text: #070808;
|
|
||||||
--background: #f7f8f8;
|
|
||||||
--primary: #aeb4bc;
|
|
||||||
--secondary: #dcd5d5;
|
|
||||||
--accent: #7d7468;
|
|
||||||
}
|
|
||||||
:root[data-theme="dark"] {
|
|
||||||
--text: #f7f8f8;
|
|
||||||
--background: #070808;
|
|
||||||
--primary: #434951;
|
|
||||||
--secondary: #2a2323;
|
|
||||||
--accent: #978e82;
|
|
||||||
}*/
|
|
||||||
:root {
|
:root {
|
||||||
/*color-scheme: light dark;*/
|
--text: #f5f3f0;
|
||||||
--text: #f7f8f8;
|
--background: #0a0803;
|
||||||
--background: #070808;
|
--primary: #ff930f;
|
||||||
--primary: #434951;
|
--secondary: #6f613d;
|
||||||
--secondary: #2a2323;
|
--accent: #ad975f;
|
||||||
--accent: #978e82;
|
--paper: #050606;
|
||||||
--paper: #181b1b;
|
|
||||||
|
--text: #b4bfc0;
|
||||||
|
--background: #010202;
|
||||||
|
--primary: #e3eff2;
|
||||||
|
--secondary: #00bcd1;
|
||||||
|
--accent: #8c240d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom CSS */
|
/* Custom CSS */
|
||||||
|
|
@ -56,18 +46,25 @@ body {
|
||||||
a:link, a:active{
|
a:link, a:active{
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
a:hover {
|
|
||||||
color: var(--secondary);
|
|
||||||
}
|
|
||||||
a:visited {
|
a:visited {
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
}
|
}
|
||||||
|
a:hover {
|
||||||
|
color: var(--secondary);
|
||||||
|
}
|
||||||
|
|
||||||
.homepage-header {
|
.homepage-header {
|
||||||
background-color: var(--paper);
|
background-color: var(--paper);
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex-wrap-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 1000px;
|
max-width: 1000px;
|
||||||
min-width: 800px;
|
min-width: 800px;
|
||||||
|
|
@ -80,9 +77,12 @@ a:visited {
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-wrap-container {
|
div.summary__img_container {
|
||||||
display: flex;
|
position:relative; top:0; left:0; width:300px; height:250px;
|
||||||
align-items: flex-start;
|
}
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
img.summary__img {
|
||||||
|
position:absolute; top:0; right:0; width:300px; height:100%;
|
||||||
|
-webkit-mask-image:-webkit-gradient(linear, right top, left top, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));
|
||||||
|
mask-image: linear-gradient(to left, rgba(0,0,0,1), rgba(0,0,0,0));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
themes/warwick_portfolio/assets/img/logo.png
Normal file
BIN
themes/warwick_portfolio/assets/img/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
|
|
@ -2,7 +2,7 @@
|
||||||
let canvas = document.createElement("canvas");
|
let canvas = document.createElement("canvas");
|
||||||
document.body.appendChild(canvas);
|
document.body.appendChild(canvas);
|
||||||
canvas.style.cssText = `
|
canvas.style.cssText = `
|
||||||
background: var(--background);
|
background: #00000000;
|
||||||
position:fixed;
|
position:fixed;
|
||||||
left:0;
|
left:0;
|
||||||
top:0;
|
top:0;
|
||||||
|
|
@ -25,8 +25,8 @@ class Splash {
|
||||||
this.time = 0;
|
this.time = 0;
|
||||||
}
|
}
|
||||||
draw() {
|
draw() {
|
||||||
context.fillStyle = "#2a232300";
|
context.fillStyle = "#00000000";
|
||||||
context.strokeStyle = `rgba(42, 35, 35, ${this.distance + 0.1})`;
|
context.strokeStyle = `rgba(140, 36, 13, ${this.distance + 0.1})`;
|
||||||
|
|
||||||
let splashSize = this.distance * (this.time/100);
|
let splashSize = this.distance * (this.time/100);
|
||||||
|
|
||||||
|
|
@ -51,8 +51,8 @@ class Drop {
|
||||||
this.distance = Math.random();
|
this.distance = Math.random();
|
||||||
}
|
}
|
||||||
draw() {
|
draw() {
|
||||||
context.fillStyle = `rgba(42, 35, 35, ${this.distance + 0.1})`;
|
context.fillStyle = `rgba(140, 36, 13, ${this.distance + 0.1})`;
|
||||||
context.strokeStyle = `rgba(42, 35, 35, ${this.distance + 0.1})`;
|
context.strokeStyle = `rgba(140, 36, 13, ${this.distance + 0.1})`;
|
||||||
|
|
||||||
// draw point
|
// draw point
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
|
|
@ -75,7 +75,7 @@ class Drop {
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate element array
|
// populate element array
|
||||||
for (let i = 0; i < 100; i++) {
|
for (let i = 0; i < 50; i++) {
|
||||||
drawableObjectList.push(new Drop());
|
drawableObjectList.push(new Drop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
117
themes/warwick_portfolio/assets/js/greeter.js
Normal file
117
themes/warwick_portfolio/assets/js/greeter.js
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
// thanks to https://stackoverflow.com/a/74129799
|
||||||
|
const { cos, sin, sqrt, acos, atan, atan2, abs, PI } = Math
|
||||||
|
const clamp = (a, b, x) => x < a ? a : x > b ? b : x
|
||||||
|
const cvs = document.createElement('canvas')
|
||||||
|
cvs.style.cssText = ` background: #00000000; `
|
||||||
|
const primaryCol = getComputedStyle(document.body).getPropertyValue('--secondary');
|
||||||
|
const secondCol = getComputedStyle(document.body).getPropertyValue('--accent');
|
||||||
|
const ctx = cvs.getContext('2d')
|
||||||
|
|
||||||
|
const RADIUS = 150
|
||||||
|
const NB_SECTIONS = 6
|
||||||
|
const LINE_WIDTH = 3
|
||||||
|
|
||||||
|
const SCALE = devicePixelRatio
|
||||||
|
const width = RADIUS * 2 + 20
|
||||||
|
const height = RADIUS * 2 + 20
|
||||||
|
cvs.width = width * SCALE
|
||||||
|
cvs.height = height * SCALE
|
||||||
|
cvs.style.width = `${width}px`
|
||||||
|
cvs.style.height = `${height}px`
|
||||||
|
|
||||||
|
document.getElementById("greeter-sim").appendChild(cvs)
|
||||||
|
|
||||||
|
const vec = (x = 0, y = 0, z = 0) => ({ x, y, z })
|
||||||
|
|
||||||
|
vec.set = (o, x = 0, y = 0, z = 0) => {
|
||||||
|
o.x = x
|
||||||
|
o.y = y
|
||||||
|
o.z = z
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
const X = vec(1, 0, 0)
|
||||||
|
const Y = vec(0, 1, 0)
|
||||||
|
const Z = vec(0, 0, 1)
|
||||||
|
|
||||||
|
// orientation of camera
|
||||||
|
let theta, phi
|
||||||
|
|
||||||
|
// project v to the camera, output to o
|
||||||
|
function project(o, { x, y, z }) {
|
||||||
|
let ct = cos(theta), st = sin(theta)
|
||||||
|
let cp = cos(phi), sp = sin(phi)
|
||||||
|
let a = x * ct + y * st
|
||||||
|
return vec.set(o, y * ct - x * st, cp * z - sp * a, cp * a + sp * z)
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw camera-facing section of sphere with normal v and offset o (-1 < o < 1)
|
||||||
|
const _p = vec()
|
||||||
|
function draw_section(n, o = 0) {
|
||||||
|
let { x, y, z } = project(_p, n) // project normal on camera
|
||||||
|
let a = atan2(y, x) // angle of projected normal -> angle of ellipse
|
||||||
|
let ry = sqrt(1 - o * o) // radius of section -> y-radius of ellipse
|
||||||
|
let rx = ry * abs(z) // x-radius of ellipse
|
||||||
|
let W = sqrt(x * x + y * y)
|
||||||
|
let sa = acos(clamp(-1, 1, o * (1 / W - W) / rx)) // ellipse start angle
|
||||||
|
let sb = z > 0 ? 2 * PI - sa : - sa // ellipse end angle
|
||||||
|
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.ellipse(x * o * RADIUS, y * o * RADIUS, rx * RADIUS, ry * RADIUS, a, sa, sb, z <= 0)
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
|
||||||
|
const _n = vec()
|
||||||
|
function draw_arcs() {
|
||||||
|
for (let i = NB_SECTIONS; i--;) {
|
||||||
|
let a = i / NB_SECTIONS * Math.PI
|
||||||
|
draw_section(vec.set(_n, cos(a), sin(a)))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = NB_SECTIONS - 1; i--;) {
|
||||||
|
let a = (i + 1) / NB_SECTIONS * Math.PI
|
||||||
|
draw_section(Z, cos(a))
|
||||||
|
//draw_section(X, cos(a))
|
||||||
|
//draw_section(Y, cos(a))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ctx.lineCap = 'round'
|
||||||
|
ctx.scale(SCALE, SCALE)
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
requestAnimationFrame(render)
|
||||||
|
|
||||||
|
theta = performance.now() / 24000 * PI
|
||||||
|
phi = cos(performance.now() / 12000 * PI)
|
||||||
|
|
||||||
|
// 1. change the basis of the canvas
|
||||||
|
ctx.save()
|
||||||
|
ctx.clearRect(0, 0, width, height)
|
||||||
|
ctx.translate(width >> 1, height >> 1)
|
||||||
|
ctx.scale(1, -1)
|
||||||
|
|
||||||
|
// 2. draw back arcs
|
||||||
|
ctx.lineWidth = LINE_WIDTH / 2
|
||||||
|
ctx.strokeStyle = secondCol
|
||||||
|
ctx.scale(-1, -1) // the trick is to flip the canvas
|
||||||
|
draw_arcs()
|
||||||
|
ctx.scale(-1, -1)
|
||||||
|
|
||||||
|
// 3. draw sphere border
|
||||||
|
ctx.strokeStyle = primaryCol
|
||||||
|
ctx.lineWidth = LINE_WIDTH + 2
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(0, 0, RADIUS, 0, 2 * Math.PI)
|
||||||
|
ctx.stroke()
|
||||||
|
|
||||||
|
// 4. draw front arcs
|
||||||
|
ctx.lineWidth = LINE_WIDTH
|
||||||
|
ctx.strokeStyle = primaryCol
|
||||||
|
draw_arcs()
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(render)
|
||||||
|
|
@ -12,9 +12,9 @@
|
||||||
</div>
|
</div>
|
||||||
{{ if .Params.thumbnail }}
|
{{ if .Params.thumbnail }}
|
||||||
{{- $image := resources.Get .Params.thumbnail -}}
|
{{- $image := resources.Get .Params.thumbnail -}}
|
||||||
<div style="align-self: center">
|
<div class="summary__img_container" style="align-self: center">
|
||||||
<a style="display: block" href="{{ .Permalink }}">
|
<a style="display: block" href="{{ .Permalink }}">
|
||||||
<img style="margin: 0 1em" src="{{ ($image.Fill "200x200 q100 Center").RelPermalink }}">
|
<img class="summary__img" src="{{ ($image.Fill "300x250 q100 Center").RelPermalink }}">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
{{ partial "greeter.html" .}}
|
{{ partial "greeter.html" .}}
|
||||||
<header id="homepage-header" class="homepage-header">
|
<header id="homepage-header" class="homepage-header">
|
||||||
<div class="container">
|
<div class="flex-wrap-container" style="align-items:center">
|
||||||
<h1>{{.Title}}</h1>
|
{{ $logo := (resources.Get "/img/logo.png").Resize "100x100" }}
|
||||||
|
<a href="/">
|
||||||
|
<img style="padding-right: 1%" src="{{ $logo.RelPermalink }}" alt="logo">
|
||||||
|
</a>
|
||||||
|
<a style="text-decoration: none" href="/">
|
||||||
|
<h1 style="display:inline; color:var(--primary)">{{.Title}}</h1>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
{{ with .Site.GetPage "/greeter" }}
|
{{ with .Site.GetPage "/greeter" }}
|
||||||
{{$greeter_style := resources.Get "css/greeter.css"}}
|
{{$greeter_style := resources.Get "css/greeter.css"}}
|
||||||
|
{{$greeter_sim := resources.Get "js/greeter.js"}}
|
||||||
<link rel="stylesheet" type="" href="{{$greeter_style.RelPermalink}}">
|
<link rel="stylesheet" type="" href="{{$greeter_style.RelPermalink}}">
|
||||||
<div id="greeter">
|
<div id="greeter">
|
||||||
|
<div id="greeter-sim"></div>
|
||||||
<div id="greeter-content">
|
<div id="greeter-content">
|
||||||
{{ .Content }}
|
{{ .Content }}
|
||||||
<div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div style="text-align:center; width:100%">
|
||||||
<div style="text-align:center; width:100%"> </div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<a style="text-align:center" onClick="document.getElementById('homepage-header').scrollIntoView({block: 'start', behavior: 'smooth'});" >
|
<a style="text-align:center" onClick="document.getElementById('homepage-header').scrollIntoView({block: 'start', behavior: 'smooth'});" >
|
||||||
Scroll Down
|
Scroll Down
|
||||||
</a>
|
</a>
|
||||||
<div class="scroll-down-dude" onClick="document.getElementById('homepage-header').scrollIntoView({block: 'start', behavior: 'smooth'});"></div>
|
<div class="scroll-down-dude" onClick="document.getElementById('homepage-header').scrollIntoView({block: 'start', behavior: 'smooth'});"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="{{$greeter_sim.RelPermalink}}"></script>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue