1
0
Fork 0

Use shaped.js

This commit is contained in:
Moritz Ruth 2020-01-13 22:37:25 +01:00
parent 7b9ead0f63
commit 82447b6a92
No known key found for this signature in database
GPG key ID: FE38A0B03AA331BA
5 changed files with 120 additions and 134 deletions

View file

@ -1,126 +0,0 @@
/* eslint-disable no-extra-parens */
const PROBABILITY = 1 / 50000;
const HEIGHT = 2;
const MIN_LINE_LENGTH = 20;
const MAX_LINE_LENGTH = 300;
const SPEED = 0.4;
const APPEAR_PROBABILITY = 1;
const COLORS = [
"#000000",
"#00ff64",
"rgba(0,255,100,0.2)",
"#0064ff"
];
function randomBetween (min, max) {
return (Math.random() * (max - min)) + min;
}
export class BackgroundCanvas {
constructor (element) {
this._element = element;
this._ctx = element.getContext("2d");
this._destroyed = false;
this._animationFrameRequestID = null;
this._lines = null;
this.width = null;
this.height = null;
this._windowListeners = {
touchstart: () => {
this._isTouch = true;
},
resize: () => {
this._points = [];
this._init();
}
};
Object.entries(this._windowListeners)
.forEach(([event, listener]) => window.addEventListener(event, listener, { passive: true }));
this._init();
this._loop();
}
destroy() {
if (this._destroyed) {
throw new Error("Instance is already destroyed.");
}
this._destroyed = true;
this._element = null;
this._ctx = null;
Object.entries(this._windowListeners)
.forEach(([event, listener]) => window.removeEventListener(event, listener));
if (this._animationFrameRequestID !== null) {
cancelAnimationFrame(this._animationFrameRequestID);
}
}
get destroyed() {
return this._destroyed;
}
_init() {
this._element.width = window.innerWidth;
this._element.height = window.innerHeight;
this.width = this._element.clientWidth;
this.height = this._element.clientHeight;
while (this._lines === null || this._lines.length < 8) {
this._lines = [];
for (let x = 0; x < this.width; x += 1) {
for (let y = 0; y < this.height; y += 1) {
if (Math.random() < PROBABILITY) {
const color = Math.round(Math.random() * (COLORS.length - 1));
const length = 0;
this._lines.push({ x, y, color, length });
}
}
}
}
}
_loop() {
this._animationFrameRequestID = null;
this._draw();
if (!this._destroyed) {
requestAnimationFrame(() => this._loop());
}
}
_draw() {
// eslint-disable-next-line unicorn/prevent-abbreviations
const ctx = this._ctx;
if (ctx === null) return;
ctx.clearRect(0, 0, this.width, this.height);
for (const line of this._lines) {
if (line.length === 0) {
if (Math.random() < APPEAR_PROBABILITY) {
line.length = randomBetween(MIN_LINE_LENGTH, MAX_LINE_LENGTH);
}
}
ctx.fillStyle = COLORS[line.color];
ctx.fillRect(line.x, line.y, line.length, HEIGHT);
line.x += SPEED;
if (line.x >= this.width) {
line.x = -line.length;
}
}
}
}

View file

@ -12,7 +12,7 @@
},
"dependencies": {
"@nuxtjs/pwa": "^3.0.0-beta.19",
"kiste": "^1.2.6",
"kiste": "^1.2.7",
"nuxt": "^2.11.0",
"vue": "^2.6.11",
"vue-ripple-directive": "^2.0.1"
@ -28,6 +28,7 @@
"sass": "^1.24.4",
"sass-loader": "^8.0.1",
"serve": "^11.3.0",
"shaped.js": "^1.0.2",
"svg-to-vue-component": "^0.3.8"
}
}

View file

@ -110,19 +110,102 @@
<script>
import KNavigationBar from "kiste/components/KNavigationBar.vue";
import KFooter from "kiste/components/KFooter.vue";
import { Canvas } from "shaped.js";
import AnimatedLogo from "@/components/AnimatedLogo.vue";
import GitHubIcon from "@/assets/icons/github.svg";
import TwitterIcon from "@/assets/icons/twitter.svg";
import InstagramIcon from "@/assets/icons/instagram.svg";
import EmailIcon from "@/assets/icons/email.svg";
import { BackgroundCanvas } from "@/assets/js/background-canvas";
const COLORS = [
"rgba(0, 0, 0, 0.8)",
"rgba(0, 255, 150, 0.8)",
"rgba(0, 255, 150, 0.2)",
"rgba(0, 150, 255, 0.8)",
"rgba(0, 150, 255, 0.2)"
];
const LINES = [
{
minCount: 8,
probability: 1 / 10000,
height: 2,
length: 100,
speed: [-0.2, 0.2],
colors: COLORS
},
{
minCount: 8,
probability: 1 / 50000,
height: 5,
length: [20, 200],
speed: [0.2, 0.3],
colors: COLORS,
randomizeYAfterLeave: true
},
{
probability: 1 / 50000,
height: 50,
length: 50,
speed: [0.2, 0.5],
colors: COLORS
},
{
probability: 1 / 5000,
height: 3,
length: 3,
speed: [-1, 1],
colors: COLORS
},
{
minCount: 8,
probability: 1 / 50000,
height: [20, 200],
length: [20, 200],
speed: [0.2, 0.3],
colors: COLORS,
randomizeYAfterLeave: true
},
{
probability: 1 / 5000,
height: [20, 200],
length: 2,
speed: [-0.2, 0.2],
colors: COLORS
}
];
export default {
name: "IndexPage",
layout: "none",
components: { AnimatedLogo, GitHubIcon, TwitterIcon, InstagramIcon, EmailIcon, KNavigationBar, KFooter },
mounted () {
const backgroundCanvas = new BackgroundCanvas(this.$refs.canvas);
let nextConfig = 0;
if (localStorage !== undefined) {
const rawValue = localStorage.getItem("nextBackground");
if (rawValue) {
try {
nextConfig = JSON.parse(rawValue);
// eslint-disable-next-line no-empty
} catch {}
}
}
if (nextConfig > LINES.length - 1) {
nextConfig = 0;
}
if (localStorage !== undefined) {
localStorage.setItem("nextBackground", nextConfig + 1);
}
const config = LINES[nextConfig];
const backgroundCanvas = new Canvas(this.$refs.canvas, {
lines: config,
fillWindowSize: true
});
this.$once("hook:beforeDestroy", () => {
backgroundCanvas.destroy();

View file

@ -1,10 +1,20 @@
<template>
<div class="projects-page">
<KNavigationBar title="Projects"/>
<KNavigationBar title="Projects" background-after-scroll/>
<div class="content">
<h1 class="heading--1">
Projects
</h1>
<GProject
type="JavaScript library"
title="shaped.js"
github="moritzruth/shaped.js"
npm="shaped.js"
>
Generate beautiful moving shapes using a canvas element which can for example be used for backgrounds.
See it in action <nuxt-link class="link" to="/">on the home page</nuxt-link>.
Every time you reload the page, it shows another variation.
</GProject>
<GProject
type="App (english)"
title="RelaxYourEyes"

View file

@ -5025,10 +5025,10 @@ kind-of@^6.0.0, kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==
kiste@^1.2.6:
version "1.2.6"
resolved "https://registry.yarnpkg.com/kiste/-/kiste-1.2.6.tgz#4810d0aabb3fbe1a317079a71c854941cb504add"
integrity sha512-v8K2LGhUnMT4PRMTVLM2kTKxNm7ypU9aw/3fcrnU69JVtHwpLtRPRVdoFbG6D3kaJv1H51XFQ5uUg+rA9drXmg==
kiste@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/kiste/-/kiste-1.2.7.tgz#f861f4a50ee324fc96345eccfddfd20f62118a57"
integrity sha512-VJFQqNVmufyjXZt+rrjjfymYFkNzBOUrREibioIDjZHFN1Hy5Mb3AywzjpGW3FLpjPAHQNb7uxj8rY45ndI1uQ==
dependencies:
chroma-js "^2.1.0"
lodash.defaultsdeep "^4.6.1"
@ -5219,6 +5219,11 @@ lodash.templatesettings@^4.0.0:
dependencies:
lodash._reinterpolate "^3.0.0"
lodash.throttle@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=
lodash.topairs@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.topairs/-/lodash.topairs-4.3.0.tgz#3b6deaa37d60fb116713c46c5f17ea190ec48d64"
@ -7150,6 +7155,11 @@ querystring@0.2.0, querystring@^0.2.0:
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
random-item@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/random-item/-/random-item-3.0.0.tgz#a94edca6845de662072e325c29eca8e85ef88ced"
integrity sha512-IpO3Jk9/Dt79R7iS/Fn2d2asGXahMNnXLNRsgSmjTTtiS0tZ972BWEEm9uUgm3YAon5YFUt8126FA9wJAjmeZw==
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@ -7751,6 +7761,14 @@ shallow-clone@^3.0.0:
dependencies:
kind-of "^6.0.2"
shaped.js@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/shaped.js/-/shaped.js-1.0.2.tgz#bb53612cd2def9e5e05f99ff2b74c2a6f576031f"
integrity sha512-kSUdVpXNR1KDF5iknA6dwrkJ0rxgWOGmjmgCefoWTWPN2kon6QW972+K0L0rAEaxJYeWSgKcrKPEEuT3JGcccA==
dependencies:
lodash.throttle "^4.1.1"
random-item "^3.0.0"
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"