Difference between revisions of "Test"

From Official Runecraft Wiki
 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
#chat-container
+
{{triDRender
#chat-input
+
|disp_widget={{#widget:RuneDisp|runefile=/images/7/7a/Runecraft.glb|multilayer=false}}
#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>
 

Latest revision as of 20:07, 25 September 2023