From 7e77ed2ea342ba18f6bb953d4eb697e37cb7c9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Schmelczer=20Andr=C3=A1s?= Date: Thu, 2 Jan 2020 15:38:30 +0100 Subject: [PATCH] WIP --- .idea/workspace.xml | 7 +- src/framework/helper.ts | 2 - src/page/background/background.html.ts | 5 +- src/page/background/background.scss | 50 ++--------- src/page/background/background.ts | 71 +++++++++++---- src/page/background/blob.ts | 117 ++++++++----------------- 6 files changed, 101 insertions(+), 151 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 3483d2c..0d483dd 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,15 +3,11 @@ - - - - @@ -112,6 +108,7 @@ + diff --git a/src/framework/helper.ts b/src/framework/helper.ts index 194d701..d4f98c7 100644 --- a/src/framework/helper.ts +++ b/src/framework/helper.ts @@ -91,5 +91,3 @@ export const range = ({ export const last = (list: Array): T => list.length > 0 ? list[list.length - 1] : undefined; - -export const isChrome = (): boolean => !!navigator.appVersion.match(/chrome/i); diff --git a/src/page/background/background.html.ts b/src/page/background/background.html.ts index cbd0a13..a4ac278 100644 --- a/src/page/background/background.html.ts +++ b/src/page/background/background.html.ts @@ -2,8 +2,5 @@ import { html } from "../../model/misc"; import "./background.scss"; export const generate = (): html => ` -
-
-
-
+ `; diff --git a/src/page/background/background.scss b/src/page/background/background.scss index b77167d..c03ed19 100644 --- a/src/page/background/background.scss +++ b/src/page/background/background.scss @@ -1,48 +1,12 @@ @import "../../style/vars"; @import "../../style/mixins"; -#background-container { - position: absolute; - left: 0; - top: 0; - height: 100%; - width: 100%; - - z-index: -1; - -webkit-overflow-scrolling: touch; - perspective: 5px; - perspective-origin: center center; - overflow: hidden; - - #background { - overflow: hidden; - will-change: width, height; - transition: height $long-transition-time, width $long-transition-time; - transform-style: flat; - - div { - position: -webkit-sticky; - position: absolute; - left: 0; - top: 0; - border-radius: 100px; - width: 140px; - - transition: transform $long-transition-time, opacity $long-transition-time; - will-change: transform, opacity; - animation: fade-in 1s linear; - @keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } - } - } - } -} - -#edge-hack { +canvas#background { position: fixed; + top: 0; + left: 0; + height: 100vh; + width: 100%; + z-index: -10; + background-color: hotpink; } diff --git a/src/page/background/background.ts b/src/page/background/background.ts index 4b7ce6c..07cc38c 100644 --- a/src/page/background/background.ts +++ b/src/page/background/background.ts @@ -4,7 +4,7 @@ import { createElement, randomFactory, sum, - isChrome + randomInInterval } from "../../framework/helper"; import { PageEvent, PageEventType } from "../../framework/page-event"; import { Blob } from "./blob"; @@ -13,20 +13,21 @@ import { generate } from "./background.html"; export class PageBackground extends PageElement { private readonly blobs: Array = []; private readonly blobSpacing = 350; - private previousWidth: number; - private previousHeight: number; - private previousScrollPositionToSet: number = 0; - private previousTimestamp: DOMHighResTimeStamp = null; private readonly baseDeltaTime = (1 / 30) * 1000; - private readonly maxBaseSpeedInPixels = 20; + private readonly perspective = 5; + private readonly zMin = 10; + private readonly zMax = 30; + private width: number; + private height: number; + private scrollPosition: number = 0; + private previousTimestamp: DOMHighResTimeStamp = null; + private readonly ctx: RenderingContext; public constructor(private start: PageElement, private end: PageElement) { super(); - this.setElement(createElement(generate())); - if (isChrome()) { - this.query("#background").style.transformStyle = "preserve-3d"; - } - Blob.initialize(10, 30, 5); + const canvas = createElement(generate()) as HTMLCanvasElement; + this.ctx = canvas.getContext("2d"); + this.setElement(canvas); } protected handleEvent(event: PageEvent, parent: PageElement) { @@ -46,8 +47,46 @@ export class PageBackground extends PageElement { ); } + public drawBlob(blob: Blob) { + const topLeft = this.convertFrom3Dto2D(blob.topLeft); + const bottomRight = this.convertFrom3Dto2D(blob.bottomRight); + } + + private convertFrom3Dto2D(point: [number, number, number]): [number, number] { + let [x, y, z] = point; + return [ + (z / this.perspective) * (this.width / 2 - x) + x, + (z / this.perspective) * (this.height / 2 - y) + y - this.scrollPosition + ]; + } + + private randomWithKnownZ( + random: () => number, + viewportSize: number, + scrollSize: number, + startOffset = 0, + endOffset = 0 + ): number { + const m = 1 + this.z / Blob.perspective; + + const variableOffset = (offset, q) => + Math.max( + 0, + offset - ((this.z - Blob.zMin) / (Blob.zMax - Blob.zMin)) * (offset * q) + ); + + startOffset = variableOffset(startOffset, 1); + endOffset = variableOffset(endOffset, 0.2); + + const lowerBound = viewportSize / 2 - (viewportSize / 2 - startOffset) * m; + const l = + scrollSize - viewportSize + (viewportSize - startOffset - endOffset) * m; + + return randomInInterval(lowerBound, lowerBound + l, random); + } + private scrollContainer(timestamp: DOMHighResTimeStamp, parent: PageElement) { - const deltaTime = this.getDeltaTime(timestamp); + /*const deltaTime = this.getDeltaTime(timestamp); const scrollPositionToSet = parent.getElement().scrollTop; const deltaScroll = scrollPositionToSet - this.previousScrollPositionToSet; this.previousScrollPositionToSet = scrollPositionToSet; @@ -70,7 +109,7 @@ export class PageBackground extends PageElement { window.requestAnimationFrame(timestamp => this.scrollContainer(timestamp, parent) - ); + );*/ } private getDeltaTime(timestamp: DOMHighResTimeStamp): number { @@ -105,14 +144,14 @@ export class PageBackground extends PageElement { while (requiredBlobCount > this.blobs.length) { const blob = new Blob(); - this.query("#background").appendChild(blob.htmlElement); + // this.query("#background").appendChild(blob.htmlElement); this.blobs.push(blob); } const random = randomFactory(2662); this.blobs.forEach((b, i) => { - if (i >= requiredBlobCount) { + /*if (i >= requiredBlobCount) { b.hide(); } else { b.transform( @@ -124,7 +163,7 @@ export class PageBackground extends PageElement { getHeight(this.end.getElement()) ); b.show(); - } + }*/ }); } diff --git a/src/page/background/blob.ts b/src/page/background/blob.ts index ccd5448..c235c65 100644 --- a/src/page/background/blob.ts +++ b/src/page/background/blob.ts @@ -1,6 +1,5 @@ import { choose, - createElement, mixColors, randomFactory, randomInInterval @@ -9,96 +8,52 @@ import { export class Blob { private static readonly creatorRandom = randomFactory(44); private static readonly colors = ["#fff9e0", "#ffd6d6"]; - private static zMin: number; - private static zMax: number; - private static perspective: number; - public static initialize(zMin: number, zMax: number, perspective: number) { - Blob.zMin = zMin; - Blob.zMax = zMax; - Blob.perspective = perspective; - } - private readonly z = randomInInterval( - Blob.zMin, - Blob.zMax, - Blob.creatorRandom - ); + private readonly x = Blob.creatorRandom(); + private readonly y = Blob.creatorRandom(); + private readonly z = Blob.creatorRandom(); + private readonly rotation = 20; + private readonly width = 140; + private readonly height = randomInInterval(160, 740, Blob.creatorRandom); + private readonly color: string; - private readonly element: HTMLElement = createElement("
"); constructor() { - this.element.style.backgroundColor = + this.color = "#" + - mixColors( - "#ffffff", - choose(Blob.colors, Blob.creatorRandom), - (this.z - Blob.zMin) / (Blob.zMax - Blob.zMin) - ); - this.element.style.zIndex = (-this.z).toString(); - this.element.style.height = `${randomInInterval( - 160, - 740, - Blob.creatorRandom - )}px`; + mixColors("#ffffff", choose(Blob.colors, Blob.creatorRandom), this.z); } - get htmlElement(): HTMLElement { - return this.element; + public get topLeft(): [number, number, number] { + return [this.x, this.y, this.z]; } - private randomWithKnownZ( - random: () => number, - viewportSize: number, - scrollSize: number, - startOffset = 0, - endOffset = 0 - ): number { - const m = 1 + this.z / Blob.perspective; - - const variableOffset = (offset, q) => - Math.max( - 0, - offset - ((this.z - Blob.zMin) / (Blob.zMax - Blob.zMin)) * (offset * q) - ); - - startOffset = variableOffset(startOffset, 1); - endOffset = variableOffset(endOffset, 0.2); - - const lowerBound = viewportSize / 2 - (viewportSize / 2 - startOffset) * m; - const l = - scrollSize - viewportSize + (viewportSize - startOffset - endOffset) * m; - - return randomInInterval(lowerBound, lowerBound + l, random); + public get bottomRight(): [number, number, number] { + return [this.x + this.width, this.y + this.height, this.z]; } - public show() { - this.element.style.opacity = "1"; - } - - public hide() { - this.element.style.opacity = "0"; - } - - public transform( - random: () => number, - width: number, - viewportHeight: number, - scrollHeight: number, - startOffset: number, - endOffset: number + public draw( + ctx: CanvasRenderingContext2D, + position: [number, number], + size: [number, number] ) { - const value = ` - translateX(${this.randomWithKnownZ(random, width, width)}px) - translateY(${this.randomWithKnownZ( - random, - viewportHeight, - scrollHeight, - startOffset, - endOffset - )}px) - translateZ(${-this.z}px) - rotate(-20deg) - `; - this.element.style["-webkit-transform"] = value; - this.element.style.transform = value; + const [x, y] = position; + const [width, height] = size; + const radius = Math.min(width, height) / 2; + + ctx.save(); + ctx.translate(-x, -y); + ctx.rotate(this.rotation); + ctx.fillStyle = this.color; + + ctx.beginPath(); + ctx.moveTo(x + radius, y); + ctx.arcTo(x + width, y, x + width, y + height, radius); + ctx.arcTo(x + width, y + height, x, y + height, radius); + ctx.arcTo(x, y + height, x, y, radius); + ctx.arcTo(x, y, x + width, y, radius); + ctx.closePath(); + ctx.fill(); + + ctx.restore(); } }