Difference between revisions of "Test"

From Official Runecraft Wiki
(Blanked the page)
Tag: Blanking
Line 1: Line 1:
 +
#chat-container
 +
#chat-input
 +
#file-input
 +
<style type="text/css" media="screen">
  
 +
html,
 +
body {
 +
background-color: hsl(0, 0%, 8%);
 +
// margin: 0; // Go fixed
 +
// font-size: 0; // Fix white-space issues if present.
 +
// height: 100vh; // Go fixed
 +
user-select: none;
 +
}
 +
 +
// For centering
 +
#chat-container {
 +
display: flex;
 +
justify-content: center;
 +
align-items: center;
 +
}
 +
 +
#chat-input {
 +
position: fixed;
 +
bottom: 10px;
 +
height: 40px;
 +
width: 500px;
 +
background-color: hsl(0, 0%, 14%);
 +
border-radius: 6px;
 +
overflow: hidden;
 +
 +
&:before,
 +
&:after {
 +
content: '';
 +
display: block;
 +
position: absolute;
 +
top: 12px;
 +
bottom: 12px;
 +
background-color: hsla(0, 0%, 22%, 0.4);
 +
}
 +
// Chat input
 +
&:before {
 +
cursor: text;
 +
left: 52px;
 +
width: 40%;
 +
border-radius: 2px;
 +
}
 +
// Emote picker
 +
&:after {
 +
cursor: pointer;
 +
right: 10px;
 +
width: 16px;
 +
border-radius: 8px;
 +
}
 +
#file-input {
 +
cursor: pointer;
 +
display: block;
 +
border-right: 2px solid hsl(0, 0%, 16%);
 +
position: absolute;
 +
top: 2px;
 +
left: 2px;
 +
bottom: 2px;
 +
width: 36px;
 +
transition: background-color 60ms;
 +
 +
&:hover {
 +
top: 0;
 +
left: 0;
 +
bottom: 0;
 +
width: 40px;
 +
background-color: hsl(0, 0%, 28%);
 +
border-right: 0;
 +
transition: background-color 120ms;
 +
}
 +
&:before,
 +
&:after {
 +
content: '';
 +
display: block;
 +
position: absolute;
 +
background-color: hsl(0, 0%, 22%);
 +
}
 +
&:before {
 +
top: 30%;
 +
bottom: 30%;
 +
left: 50%;
 +
width: 2px;
 +
margin-left: -1px;
 +
}
 +
&:after {
 +
left: 30%;
 +
right: 30%;
 +
top: 50%;
 +
height: 2px;
 +
margin-top: -1px;
 +
}
 +
}
 +
}
 +
 +
.chat {
 +
position: fixed;
 +
bottom: 60px;
 +
width: 500px;
 +
display: inline-block;
 +
}
 +
 +
.line-container {
 +
overflow: hidden;
 +
border-radius: 6px;
 +
max-height: 0px;
 +
opacity: 0;
 +
transform: translateX(-300px) scale(0.2);
 +
transition: margin-bottom 200ms, max-height 500ms, opacity 100ms, transform 250ms;
 +
transition-timing-function: ease-out;
 +
 +
 +
&:not(:last-child) {
 +
margin-bottom: 10px;
 +
}
 +
}
 +
 +
.line {
 +
padding: 10px;
 +
background-color: hsl(0, 0%, 14%);
 +
 +
& > div {
 +
display: inline-block;
 +
vertical-align: top;
 +
}
 +
}
 +
 +
.profile-img {
 +
cursor: pointer;
 +
border-radius: 6px;
 +
width: 60px;
 +
height: 60px;
 +
background-color: hsl(0, 0%, 22%);
 +
margin-right: 10px;
 +
}
 +
 +
.body {
 +
// background-color: black;
 +
 +
.name,
 +
.text {
 +
border-radius: 2px;
 +
background-color: hsl(0, 0%, 28%);
 +
height: 16px;
 +
}
 +
}
 +
 +
.name {
 +
width: 100px;
 +
margin-bottom: 10px;
 +
position: relative;
 +
cursor: pointer;
 +
 +
&:after {
 +
content: '';
 +
display: block;
 +
border-radius: 2px;
 +
background-color: hsla(0, 0%, 22%, 0.4);
 +
height: 16px;
 +
width: 50px;
 +
position: absolute;
 +
right: -60px;
 +
transition: 100ms;
 +
}
 +
}
 +
 +
.profile-img:hover + .body .name:after,
 +
.name:hover:after {
 +
background-color: hsla(0, 0%, 22%, 1);
 +
width: 100px;
 +
right: -110px;
 +
}
 +
 +
.text {
 +
&:not(:last-child) {
 +
margin-bottom: 10px;
 +
}
 +
}
 +
 +
.img {
 +
}
 +
 +
.rich-body {
 +
margin-left: 14px;
 +
margin-top: 36px;
 +
position: relative;
 +
 +
&:before {
 +
content: '';
 +
display: block;
 +
position: absolute;
 +
top: -26px;
 +
left: -14px;
 +
bottom: 0;
 +
width: 4px;
 +
background-color: inherit;
 +
}
 +
&:after {
 +
content: '';
 +
display: block;
 +
position: absolute;
 +
height: 16px;
 +
width: 200px;
 +
top: -26px;
 +
background-color: inherit;
 +
border-radius: 2px;
 +
}
 +
}
 +
 +
.img,
 +
.rich-body {
 +
width: 300px;
 +
height: 300px;
 +
cursor: pointer;
 +
border-radius: 6px;
 +
background-color: hsl(0, 0%, 20%);
 +
}
 +
 +
.profile-img,
 +
.name,
 +
.text,
 +
.img,
 +
.rich-body {
 +
opacity: 0;
 +
transform: translateY(20px);
 +
transition: 200ms;
 +
}
 +
</style>
 +
<style type="text/javascript" media="screen">
 +
 +
let amountOfColors = 18; // Or "participants"
 +
 +
let container = document.getElementById('chat-container');
 +
let lineWidth = 500;
 +
let profileImgWidth = 60;
 +
let textWidth = lineWidth - 20 - profileImgWidth - 10;
 +
let chats = [];
 +
let maxTexts = 4;
 +
 +
function createElement(opts = {}) {
 +
let ele = document.createElement('div');
 +
if('class' in opts) {
 +
if(!Array.isArray(opts.class)) {
 +
opts.class = [ opts.class ];
 +
}
 +
ele.classList.add(...opts.class);
 +
}
 +
return ele;
 +
}
 +
 +
function addChat() {
 +
let chat = new Chat();
 +
chats.push(chat);
 +
setTimeout(() => chat.loop(), 200);
 +
return chat;
 +
}
 +
 +
class Chat {
 +
constructor() {
 +
this.ele = createElement({ class: 'chat' });
 +
this.lines = [];
 +
this.anim = null;
 +
container.appendChild(this.ele);
 +
}
 +
addLine() {
 +
let l = new Line();
 +
this.lines.push(l);
 +
this.ele.appendChild(l.ele.lineContainer);
 +
return l;
 +
}
 +
removeOldest() {
 +
let maxCount = Math.ceil(window.innerHeight / 1080 * 12);
 +
if(this.lines.length > maxCount) {
 +
let oldest = this.lines.splice(0, this.lines.length - maxCount);
 +
oldest.forEach(n => this.ele.removeChild(n.ele.lineContainer));
 +
}
 +
}
 +
loop() {
 +
if(this.anim) {
 +
this.stopLoop();
 +
}
 +
this.addLine();
 +
this.removeOldest();
 +
this.anim = setTimeout(() => this.loop(), Math.random() * 1300 + 180);
 +
}
 +
stopLoop() {
 +
clearTimeout(this.anim);
 +
this.anim = null;
 +
}
 +
}
 +
 +
class Line {
 +
constructor() {
 +
this.pickColor();
 +
this.pickName();
 +
this.pickText();
 +
this.pickHasImg();
 +
this.pickHasRichBody();
 +
this.setupElements();
 +
this.animateIn();
 +
}
 +
 +
pickColor() {
 +
this.hue = Math.floor(Math.random() * amountOfColors) * (360 / amountOfColors);
 +
this.color = `hsl(${this.hue}, 90%, 50%)`;
 +
this.profileImgColor = `hsl(${this.hue}, 40%, 55%)`;
 +
return this.hue;
 +
}
 +
 +
pickName() {
 +
this.name = Math.max(0.3, Math.random());
 +
}
 +
 +
pickText() {
 +
let lengthChoice = Math.random();
 +
let lengthWeight = 1;
 +
if(lengthChoice < 0.5) {
 +
lengthWeight = 0.6;
 +
}
 +
else if(lengthChoice < 0.9) {
 +
lengthWeight = 0.8;
 +
}
 +
this.length = Math.max(0.02, lengthChoice * lengthWeight);
 +
this.textCount = this.length * maxTexts;
 +
}
 +
 +
pickHasImg() {
 +
this.hasImg = Math.random() > 0.9;
 +
}
 +
 +
pickHasRichBody() {
 +
this.hasRichBody = !this.hasImage && Math.random() > 0.85;
 +
}
 +
 +
setupElements() {
 +
let ele = this.createElement();
 +
this.ele = ele;
 +
ele.name.style.width = this.name * (textWidth / 2) + 'px';
 +
ele.texts.forEach((n, i, arr) => {
 +
let w = textWidth;
 +
if(i === arr.length - 1) {
 +
w = Math.max(0.2, (this.textCount - i)) * textWidth;
 +
}
 +
n.style.width = w + 'px';
 +
});
 +
ele.name.style.backgroundColor = this.color;
 +
ele.profileImg.style.backgroundColor = this.profileImgColor;
 +
}
 +
 +
animateIn() {
 +
let delay = 35; // Some times it won't animate correctly without this
 +
let ele = this.ele;
 +
setTimeout(() => {
 +
ele.lineContainer.style.opacity = 1;
 +
ele.lineContainer.style.maxHeight = '200px';
 +
ele.lineContainer.style.transform = 'translateX(0px) scale(1)';
 +
}, delay);
 +
 +
let otherEleList = [ ele.profileImg, ele.name, ...ele.texts ];
 +
 +
if('img' in ele) {
 +
otherEleList.push(ele.img);
 +
}
 +
else if('richBody' in ele) {
 +
otherEleList.push(ele.richBody);
 +
}
 +
 +
delay += 40;
 +
 +
otherEleList.forEach((e, i) => {
 +
setTimeout(() => {
 +
e.style.opacity = 1;
 +
e.style.transform = 'translateY(0px)';
 +
}, delay += 50);
 +
});
 +
 +
ele.texts.forEach((n, i, arr) => setTimeout(() => n.style.opacity = 1, 70 * (i + 3) + delay));
 +
}
 +
 +
createElement() {
 +
let lineContainer = createElement({ class: 'line-container' });
 +
let line = createElement({ class: 'line' });
 +
let profileImg = createElement({ class: 'profile-img' });
 +
let body = createElement({ class: 'body' });
 +
let name = createElement({ class: 'name' });
 +
let texts = [];
 +
let img = createElement({ class: 'img' });
 +
let richBody = createElement({ class: 'rich-body' });
 +
body.appendChild(name);
 +
for(let i = 0; i < (this.textCount || 1); i++) {
 +
let text = createElement({ class: 'text' });
 +
texts.push(text);
 +
body.appendChild(text);
 +
}
 +
line.appendChild(profileImg);
 +
line.appendChild(body);
 +
lineContainer.appendChild(line);
 +
let out = { lineContainer, line, profileImg, body, name, texts };
 +
this.hasImg && (out.img = img) && body.appendChild(img);
 +
this.hasRichBody && (out.richBody = richBody) && body.appendChild(richBody);
 +
return out;
 +
}
 +
}
 +
 +
function loop() {
 +
chats.forEach(n => n.loop());
 +
}
 +
 +
function stopLoop() {
 +
chats.forEach(n => n.stopLoop());
 +
}
 +
 +
(() => addChat())();
 +
 +
</style>

Revision as of 12:42, 16 December 2022

  1. chat-container

#chat-input #file-input <style type="text/css" media="screen">

html, body { background-color: hsl(0, 0%, 8%); // margin: 0; // Go fixed // font-size: 0; // Fix white-space issues if present. // height: 100vh; // Go fixed user-select: none; }

// For centering

  1. chat-container {

display: flex; justify-content: center; align-items: center; }

  1. chat-input {

position: fixed; bottom: 10px; height: 40px; width: 500px; background-color: hsl(0, 0%, 14%); border-radius: 6px; overflow: hidden;

&:before, &:after { content: ; display: block; position: absolute; top: 12px; bottom: 12px; background-color: hsla(0, 0%, 22%, 0.4); } // Chat input &:before { cursor: text; left: 52px; width: 40%; border-radius: 2px; } // Emote picker &:after { cursor: pointer; right: 10px; width: 16px; border-radius: 8px; } #file-input { cursor: pointer; display: block; border-right: 2px solid hsl(0, 0%, 16%); position: absolute; top: 2px; left: 2px; bottom: 2px; width: 36px; transition: background-color 60ms;

&:hover { top: 0; left: 0; bottom: 0; width: 40px; background-color: hsl(0, 0%, 28%); border-right: 0; transition: background-color 120ms; } &:before, &:after { content: ; display: block; position: absolute; background-color: hsl(0, 0%, 22%); } &:before { top: 30%; bottom: 30%; left: 50%; width: 2px; margin-left: -1px; } &:after { left: 30%; right: 30%; top: 50%; height: 2px; margin-top: -1px; } } }

.chat { position: fixed; bottom: 60px; width: 500px; display: inline-block; }

.line-container { overflow: hidden; border-radius: 6px; max-height: 0px; opacity: 0; transform: translateX(-300px) scale(0.2); transition: margin-bottom 200ms, max-height 500ms, opacity 100ms, transform 250ms; transition-timing-function: ease-out;


&:not(:last-child) { margin-bottom: 10px; } }

.line { padding: 10px; background-color: hsl(0, 0%, 14%);

& > div { display: inline-block; vertical-align: top; } }

.profile-img { cursor: pointer; border-radius: 6px; width: 60px; height: 60px; background-color: hsl(0, 0%, 22%); margin-right: 10px; }

.body { // background-color: black;

.name, .text { border-radius: 2px; background-color: hsl(0, 0%, 28%); height: 16px; } }

.name { width: 100px; margin-bottom: 10px; position: relative; cursor: pointer;

&:after { content: ; display: block; border-radius: 2px; background-color: hsla(0, 0%, 22%, 0.4); height: 16px; width: 50px; position: absolute; right: -60px; transition: 100ms; } }

.profile-img:hover + .body .name:after, .name:hover:after { background-color: hsla(0, 0%, 22%, 1); width: 100px; right: -110px; }

.text { &:not(:last-child) { margin-bottom: 10px; } }

.img { }

.rich-body { margin-left: 14px; margin-top: 36px; position: relative;

&:before { content: ; display: block; position: absolute; top: -26px; left: -14px; bottom: 0; width: 4px; background-color: inherit; } &:after { content: ; display: block; position: absolute; height: 16px; width: 200px; top: -26px; background-color: inherit; border-radius: 2px; } }

.img, .rich-body { width: 300px; height: 300px; cursor: pointer; border-radius: 6px; background-color: hsl(0, 0%, 20%); }

.profile-img, .name, .text, .img, .rich-body { opacity: 0; transform: translateY(20px); transition: 200ms; } </style> <style type="text/javascript" media="screen">

let amountOfColors = 18; // Or "participants"

let container = document.getElementById('chat-container'); let lineWidth = 500; let profileImgWidth = 60; let textWidth = lineWidth - 20 - profileImgWidth - 10; let chats = []; let maxTexts = 4;

function createElement(opts = {}) { let ele = document.createElement('div'); if('class' in opts) { if(!Array.isArray(opts.class)) { opts.class = [ opts.class ]; } ele.classList.add(...opts.class); } return ele; }

function addChat() { let chat = new Chat(); chats.push(chat); setTimeout(() => chat.loop(), 200); return chat; }

class Chat { constructor() { this.ele = createElement({ class: 'chat' }); this.lines = []; this.anim = null; container.appendChild(this.ele); } addLine() { let l = new Line(); this.lines.push(l); this.ele.appendChild(l.ele.lineContainer); return l; } removeOldest() { let maxCount = Math.ceil(window.innerHeight / 1080 * 12); if(this.lines.length > maxCount) { let oldest = this.lines.splice(0, this.lines.length - maxCount); oldest.forEach(n => this.ele.removeChild(n.ele.lineContainer)); } } loop() { if(this.anim) { this.stopLoop(); } this.addLine(); this.removeOldest(); this.anim = setTimeout(() => this.loop(), Math.random() * 1300 + 180); } stopLoop() { clearTimeout(this.anim); this.anim = null; } }

class Line { constructor() { this.pickColor(); this.pickName(); this.pickText(); this.pickHasImg(); this.pickHasRichBody(); this.setupElements(); this.animateIn(); }

pickColor() { this.hue = Math.floor(Math.random() * amountOfColors) * (360 / amountOfColors); this.color = `hsl(${this.hue}, 90%, 50%)`; this.profileImgColor = `hsl(${this.hue}, 40%, 55%)`; return this.hue; }

pickName() { this.name = Math.max(0.3, Math.random()); }

pickText() { let lengthChoice = Math.random(); let lengthWeight = 1; if(lengthChoice < 0.5) { lengthWeight = 0.6; } else if(lengthChoice < 0.9) { lengthWeight = 0.8; } this.length = Math.max(0.02, lengthChoice * lengthWeight); this.textCount = this.length * maxTexts; }

pickHasImg() { this.hasImg = Math.random() > 0.9; }

pickHasRichBody() { this.hasRichBody = !this.hasImage && Math.random() > 0.85; }

setupElements() { let ele = this.createElement(); this.ele = ele; ele.name.style.width = this.name * (textWidth / 2) + 'px'; ele.texts.forEach((n, i, arr) => { let w = textWidth; if(i === arr.length - 1) { w = Math.max(0.2, (this.textCount - i)) * textWidth; } n.style.width = w + 'px'; }); ele.name.style.backgroundColor = this.color; ele.profileImg.style.backgroundColor = this.profileImgColor; }

animateIn() { let delay = 35; // Some times it won't animate correctly without this let ele = this.ele; setTimeout(() => { ele.lineContainer.style.opacity = 1; ele.lineContainer.style.maxHeight = '200px'; ele.lineContainer.style.transform = 'translateX(0px) scale(1)'; }, delay);

let otherEleList = [ ele.profileImg, ele.name, ...ele.texts ];

if('img' in ele) { otherEleList.push(ele.img); } else if('richBody' in ele) { otherEleList.push(ele.richBody); }

delay += 40;

otherEleList.forEach((e, i) => { setTimeout(() => { e.style.opacity = 1; e.style.transform = 'translateY(0px)'; }, delay += 50); });

ele.texts.forEach((n, i, arr) => setTimeout(() => n.style.opacity = 1, 70 * (i + 3) + delay)); }

createElement() { let lineContainer = createElement({ class: 'line-container' }); let line = createElement({ class: 'line' }); let profileImg = createElement({ class: 'profile-img' }); let body = createElement({ class: 'body' }); let name = createElement({ class: 'name' }); let texts = []; let img = createElement({ class: 'img' }); let richBody = createElement({ class: 'rich-body' }); body.appendChild(name); for(let i = 0; i < (this.textCount || 1); i++) { let text = createElement({ class: 'text' }); texts.push(text); body.appendChild(text); } line.appendChild(profileImg); line.appendChild(body); lineContainer.appendChild(line); let out = { lineContainer, line, profileImg, body, name, texts }; this.hasImg && (out.img = img) && body.appendChild(img); this.hasRichBody && (out.richBody = richBody) && body.appendChild(richBody); return out; } }

function loop() { chats.forEach(n => n.loop()); }

function stopLoop() { chats.forEach(n => n.stopLoop()); }

(() => addChat())();

</style>