#app.wrap
.bg
.colors()
button.refresh(v-on:click="newColors").
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" viewBox="0 0 23 23" version="1.1" x="0px" y="0px"><path d="M 12.109896,2.9653518 C 10.830826,2.9134678 9.5257058,3.132602 8.2817758,3.648946 c -3.9806,1.652399 -6.2540499,5.897846 -5.4179699,10.123046 0.8360799,4.2253 4.5540699,7.274132 8.8613301,7.269532 a 0.9995584,1.0006417 14.999899 1 0 0,-2 c -3.3667302,0 -6.2475202,-2.360557 -6.9004002,-5.660157 -0.65294,-3.2997 1.11025,-6.592765 4.22266,-7.884765 3.1124002,-1.292 6.6825102,-0.213669 8.5488302,2.582031 1.85391,2.77709 1.49946,6.460477 -0.8418,8.845703 l 0.0781,-2.365234 a 1.0001,1.0001 0 0 0 -0.98242,-1.046875 1.0001,1.0001 0 0 0 -1.01758,0.982422 l -0.15235,4.59375 a 1.0001,1.0001 0 0 0 1.03321,1.033203 l 4.5957,-0.152344 a 1.0001,1.0001 0 1 0 -0.0664,-1.998047 l -1.79492,0.06055 c 2.74739,-3.056097 3.10892,-7.618693 0.80859,-11.064453 -1.64326,-2.461525 -4.33252,-3.887808 -7.14648,-4.0019532 z"/></svg>
button.expand(v-on:click="newColors").
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23" x="0px" y="0px"><defs><style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:round;}</style></defs><polyline class="cls-1" points="18.5 14.5 21.5 11.5 18.5 8.5"/><polyline class="cls-1" points="4.5 8.5 1.5 11.5 4.5 14.5"/><line class="cls-1" x1="1.5" y1="11.5" x2="8.5" y2="11.5"/><line class="cls-1" x1="14.5" y1="11.5" x2="21.5" y2="11.5"/></svg>
color(v-for="(c, i) in colors", v-bind:name="names[i]" v-bind:color="c")
a.fulllink(href="https://farbvelo.elastiq.ch/", target="_blank")
strong
span F
span u
span l
span l
span
span V
span e
span r
span s
span i
span o
span n
View Compiled
@import url('https://fonts.googleapis.com/css?family=Space+Mono');
button {
border: none;
margin: 0;
padding: 0;
width: auto;
overflow: visible;
background: transparent;
/* inherit font & color from ancestor */
color: inherit;
font: inherit;
/* Normalize `line-height`. Cannot be changed from `normal` in Firefox 4+. */
line-height: normal;
/* Corrects font smoothing for webkit */
-webkit-font-smoothing: inherit;
-moz-osx-font-smoothing: inherit;
/* Corrects inability to style clickable `input` types in iOS */
-webkit-appearance: none;
}
html {
font-size: calc(.75rem + 1.15vh);
font-family: 'Space Mono', monospace;
}
body {
height: 100vh;
background: #212121;
overflow: hidden;
}
input {
position: absolute;
z-index: 2;
}
.wrap, .bg {
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}
.bg {
//opacity: .9;
//clip-path: inset(12vmin 26% 12vmin 26%);
}
.colors {
position: absolute;
left: 50%;
bottom: 10vmin; top: 10vmin;
display: flex;
flex-direction: column;
cursor: pointer;
transform: translateX(-50%);
width: 52%;
@media (max-width: 700px){
width: 75%;
}
}
.colors .color {
position: relative;
display: flex;
@media (max-width: 700px){
display: block;
padding: 1rem;
}
align-items: center;
padding: 0 1rem;
flex-grow: 1;
&::after {
opacity: .5;
content: '';
position: absolute;
left: 0; right: 0; bottom: 0; top: 0;
box-shadow: 0 0 10rem currentColor;
}
/*
border: solid currentColor;
border-width: 0 2px;
*/
transition: 200ms color linear, 200ms background-color linear, 300ms padding-bottom cubic-bezier(.7, .3, .3, 1) 100ms;
min-height: 0.1vmax;
&:last-child {
padding-bottom: #{1.61803 * 4rem};
}
&:hover {
padding-bottom: #{1.61803 * 4rem};
}
}
.colors:hover .color {
&:last-child {
padding-bottom: 1rem;
}
&:hover {
padding-bottom: #{1.61803 * 4rem};
}
}
.label {
flex-grow: 1;
padding-right: 1rem;
font-size: .75em;
@media (max-width: 700px) {
font-size: .6em;
margin-bottom: .15em;
}
}
.name {
font-size: .8em;
text-align: right;
@media (max-width: 700px){
text-align: left;
}
}
.refresh, .expand {
z-index: 1;
position: absolute;
top: 100%; left: 100%;
margin: 0;
padding: 0;
transform: translate(-60%,-60%);
font-size: 2em;
width: 1.2em; height: 1.2em;
background: #000;
color: #fff;
border-radius: 50%;
outline: 0;
box-shadow: 0 0 2rem rgba(#000, .2);
cursor: pointer;
svg {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%,-50%);
animation-name: rotate;
animation-duration: 3s;
width: .6em; height: .6em;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-play-state: paused;
line-height: 1;
fill: #fff;
}
&:hover {
svg {
animation-play-state: running;
}
}
}
.expand {
display: none;
margin-left: -1.4em;
svg {
fill: none;
stroke: #fff;
stroke-width: 1.5;
animation: none;
width: .75em; height: .75em;
}
}
@keyframes rotate {
from {transform: translate(-50%,-50%) rotate(0deg);}
to {transform: translate(-50%,-50%) rotate(360deg);}
}
.fulllink {
position: fixed;
top: 0;
right: 0;
font-size: .65em;
text-decoration: none;
padding: 1.2em 3.5em;
width: 10ex;
text-align: center;
transform: translateX(30%) rotate(45deg);
span {
position: relative;
animation: .5s ease-in 1s infinite alternate jumpup;
animation-duration: 1s;
@for $i from 1 through 20 {
&:nth-child(#{$i}) {
animation-delay: 1000ms + $i * 100ms;
}
}
}
}
@keyframes jumpup {
100% {
opacity: .1;
}
}
View Compiled
// full version: https://farbvelo.elastiq.ch/
// color-names: https://github.com/meodai/color-nameshttps://github.com/meodai/color-names
const shuffleArray = arr => arr
.map(a => [Math.random(), a])
.sort((a, b) => a[0] - b[0])
.map(a => a[1]);
const random = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var generateRandomColors = (total, mode = 'lab', padding = .175, parts = 4) => {
let colors = [];
const part = Math.floor(total / parts);
const reminder = total % parts;
// hues to pick from
const baseHue = random(0, 360);
const hues = [0, 60, 120, 180, 240, 300].map(offset => {
return (baseHue + offset) % 360;
});
// low saturated color
const baseSaturation = random(5, 40);
const baseLightness = random(0, 20);
const rangeLightness = 90 - baseLightness;
colors.push( HUSL.toHex(
hues[0],
baseSaturation,
baseLightness * random(.25, .75)
) );
for (let i = 0; i < (part - 1); i++) {
colors.push( HUSL.toHex(
hues[0],
baseSaturation,
baseLightness + (rangeLightness * Math.pow(i/(part - 1), 1.5))
) );
}
// random shades
const minSat = random(50, 70);
const maxSat = minSat + 30;
const minLight = random(45, 80);
const maxLight = Math.min(minLight + 40, 95);
for (let i = 0; i < (part + reminder - 1); i++) {
colors.push( HUSL.toHex(
hues[random(0, hues.length - 1)],
random(minSat, maxSat),
random(minLight, maxLight)
) )
}
colors.push( HUSL.toHex(
hues[0],
baseSaturation,
rangeLightness
) );
//colors = shuffleArray(colors);
return chroma.scale(colors).padding(padding).mode(mode).colors(total);
}
function getContrastColor(color) {
let currentColor = chroma( color );
let lum = currentColor.luminance();
let contrastColor;
if ( lum < 0.15 ) {
contrastColor = currentColor.set('hsl.l', '+.25');
} else {
contrastColor = currentColor.set('hsl.l', '-.35');
}
return contrastColor;
}
Vue.component('color', {
props: ['color', 'name'],
template: `<div class="color" v-bind:style="{background: color, color: textColor}">
<div class="label">{{ color }}</div>
<div class="name">{{ name.name }}</div>
</div>`,
computed: {
/*name: function () {
console.log(name)
return getClosestNamedColor( this.color ).name;
},*/
textColor: function () {
return getContrastColor(this.color);
}
}
});
let colors = new Vue({
el: '#app',
data: () => {
return {
colors: [],
names: [],
amount: 6,
}
},
methods: {
getNames: function () {
fetch(`https://api.color.pizza/v1/${this.colors.join().replace(/#/g, '')}?noduplicates=true&goodnamesonly=true`)
.then(data => data.json())
.then(data => {
this.names = data.colors;
});
},
newColors: function () {
let colorArr = generateRandomColors(this.amount)
this.colors = colorArr;
this.getNames();
let gradient = [...colorArr];
gradient[0] += ' 12vmin'
gradient[gradient.length - 1] += ' 69%'
//url("https://www.transparenttextures.com/patterns/concrete-wall.png"),
document.querySelector('.bg').style['background-image'] = `
linear-gradient(to bottom, ${gradient.join(',')})
`;
document.querySelector('.refresh').style.background = this.colors[this.colors.length - 1];
document.querySelector('.expand').style.background = this.colors[this.colors.length - 1];
document.querySelector('.fulllink').style.background = this.colors[1];
document.querySelector('.fulllink').style.color = getContrastColor(this.colors[1]);
}
},
mounted: function () {
this.newColors();
}
});
View Compiled
This Pen doesn't use any external CSS resources.