Skip to content

Instantly share code, notes, and snippets.

@git2358
Created May 10, 2019 00:11
Show Gist options
  • Select an option

  • Save git2358/61bf560571451b413dd9037802fe008e to your computer and use it in GitHub Desktop.

Select an option

Save git2358/61bf560571451b413dd9037802fe008e to your computer and use it in GitHub Desktop.
5-Way Gradient Generator

5-Way Gradient Generator

Click or drag the toggles to adjust the gradient :) A 5-way gradient generator built using vue.js

A Pen by Matthew Fournier on CodePen.

License.

<div id="gradient-map">
<div class="input-holder">
<div class="close-handler" @click="closeBoxes" @mousemove="doDrag"></div>
<div class="picker" v-bind:id="'picker-'+col.key" v-for="col in colors">
<button class="picker-button" @click="toggle(col.key)" v-bind:style="{background: colors[col.key].colorInfo.hex, opacity:colors[col.key].colorInfo.rgba.a}" @mousedown="setDrag(col.key)" @mouseup="removeDrag(col.key)"></button>
<chrome-picker v-if="colors[col.key].isOpen" v-model="colors[col.key].colorInfo"></chrome-picker>
</div>
</div>
<div class="display-gradient" v-show="hasUsed">
<p>Click or drag the toggles to adjust the gradient :)</p>
</div>
<div class="get-code" v-show="showCode" @click="copyToClip">
<textarea type="text" v-model="gradText" spellcheck="false" id="gradCode"></textarea>
<span class="copyMessage" v-show="showCopied">Copied to Clipboard!</span>
</div>
<a class="code-toggle" @click="toggleCode"><i class="fas fa-code"></i><br>{{togMessage}}</a>
</div>
var Chrome = window.VueColor.Chrome;
new Vue({
el: "#gradient-map",
data: {
colors: [
{
key: 0,
isOpen: false,
pos: {
x: 50,
y: 60
},
colorInfo: {
hex: "#95B0F1",
rgba: { r: 149, g: 176, b: 249, a: 1 }
}
},
{
key: 1,
isOpen: false,
pos: {
x: 10,
y: 10
},
colorInfo: {
hex: "#72E2F3",
rgba: { r: 114, g: 226, b: 253, a: 1 }
}
},
{
key: 2,
isOpen: false,
pos: {
x: 90,
y: 10
},
colorInfo: {
hex: "#B896FF",
rgba: { r: 184, g: 150, b: 255, a: 1 }
}
},
{
key: 3,
isOpen: false,
pos: {
x: 90,
y: 90
},
colorInfo: {
hex: "#56CFD2",
rgba: { r: 86, g: 207, b: 210, a: 1 }
}
},
{
key: 4,
isOpen: false,
pos: {
x: 10,
y: 90
},
colorInfo: {
hex: "#A870FD",
rgba: { r: 168, g: 112, b: 253, a: 1 }
}
}
],
selectedPicker: null,
mouseDown: false,
gradText: "",
clickTimer: null,
isDrag: false,
hasUsed: true,
showCode: false,
showCopied: false,
togMessage: "View Gradient Code"
},
components: {
"chrome-picker": Chrome
},
methods: {
init() {
this.updateGradient();
for (var i = 0; i < this.colors.length; i++) {
$("#picker-" + i).css("left", this.colors[i].pos.x + "%");
$("#picker-" + i).css("top", this.colors[i].pos.y + "%");
}
},
toggle(i) {
if (this.isDrag != true) {
this.closeBoxes();
this.colors[i].isOpen = !this.colors[i].isOpen;
}
this.isDrag = false;
},
updateGradient() {
var gradient = "";
for (var i = 0; i < this.colors.length; i++) {
if (i < this.colors.length - 1) {
var com = ", ";
} else {
var com = " ";
}
var gradString =
"radial-gradient(circle at " +
this.colors[i].pos.x +
"% " +
this.colors[i].pos.y +
"%,rgba(" +
this.colors[i].colorInfo.rgba.r +
"," +
this.colors[i].colorInfo.rgba.g +
"," +
this.colors[i].colorInfo.rgba.b +
"," +
this.colors[i].colorInfo.rgba.a +
"), rgba(" +
this.colors[i].colorInfo.rgba.r +
"," +
this.colors[i].colorInfo.rgba.g +
"," +
this.colors[i].colorInfo.rgba.b +
",0) 50%)" +
com;
gradient = gradient + gradString;
}
this.gradText = "background: " + gradient + ";";
$("#gradient-map").css("background", gradient);
},
setDrag(i) {
this.mouseDown = true;
this.selectedPicker = i;
this.hasUsed = false;
var self = this;
this.clickTimer = setTimeout(function() {
self.isDrag = true;
}, 100);
},
removeDrag(i) {
this.mouseDown = false;
this.selectedPicker = null;
var self = this;
clearTimeout(this.clickTimer);
},
doDrag(event) {
var i = this.selectedPicker;
if (this.mouseDown == true) {
var mx = event.clientX;
var my = event.clientY;
var w = $(document).width();
var h = $(document).height();
this.colors[i].pos.x = Math.round(mx / w * 100);
this.colors[i].pos.y = Math.round(my / h * 100);
$("#picker-" + i).css("left", mx - 15 + "px");
$("#picker-" + i).css("top", my - 15 + "px");
}
this.updateGradient();
},
closeBoxes() {
for (var i = 0; i < this.colors.length; i++) {
this.colors[i].isOpen = false;
}
},
toggleCode() {
this.hasUsed = false;
this.showCode = !this.showCode;
if (this.showCode == true) {
this.togMessage = "Hide Gradient Code";
} else {
this.togMessage = "View Gradient Code";
}
},
copyToClip() {
$("#gradCode").focus();
$("#gradCode").select();
document.execCommand("copy");
this.showCopied = true;
var self = this;
setTimeout(function() {
self.showCopied = false;
$("#gradCode").blur();
}, 1500);
}
},
mounted() {
this.init();
},
watch: {
colors: {
handler: function(val, oldVal) {
this.updateGradient();
},
deep: true
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-color/2.2.3/vue-color.js"></script>
@import url("https://fonts.googleapis.com/css?family=Roboto:100,400,700");
*,
*:after {
box-sizing: border-box;
font-family: "Roboto", sans-serif;
}
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#gradient-map,
.input-holder,
.close-handler {
width: 100%;
height: 100%;
float: left;
position: absolute;
top: 0;
left: 0;
}
#gradient-map {
background: #fff;
display: flex;
justify-content: center;
align-items: center;
.display-gradient {
padding: 25px 25px;
border-radius: 15px;
background: rgba(0, 0, 0, 0.2);
// z-index:1000;
transition: all 0.5s ease;
-webkit-transition: all 0.5s ease;
-webkit-box-shadow: 0px 0px 28px 1px rgba(0, 0, 0, 0.34);
-moz-box-shadow: 0px 0px 28px 1px rgba(0, 0, 0, 0.34);
box-shadow: 0px 0px 28px 1px rgba(0, 0, 0, 0.34);
&:hover {
-webkit-box-shadow: 0px 0px 12px 1px rgba(0, 0, 0, 0.34);
-moz-box-shadow: 0px 0px 12px 1px rgba(0, 0, 0, 0.34);
box-shadow: 0px 0px 12px 1px rgba(0, 0, 0, 0.34);
}
p {
padding: 0px;
margin: 0px;
color: #fff;
font-size: 10pt;
text-align: center;
}
}
}
.picker {
position: absolute;
padding: 0px;
top: 50px;
z-index: 100;
padding: 2px;
left: 50px;
.vue-color__chrome {
position: fixed;
top: calc(50% - 112px);
left: calc(50% - 120px);
}
&:after {
content: "";
position: absolute;
left: 0;
top: 0;
z-index: -1;
height: 30px;
width: 30px;
background: #fff;
// border:2px solid #1a1a1a;
border-radius: 500px;
transition: all 0.2s ease;
-webkit-transition: all 0.2s ease;
-webkit-box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.34);
-moz-box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.34);
box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.34);
}
&:hover:after {
-webkit-box-shadow: 0px 0px 2px 1px rgba(0, 0, 0, 0.34);
-moz-box-shadow: 0px 0px 2px 1px rgba(0, 0, 0, 0.34);
box-shadow: 0px 0px 2px 1px rgba(0, 0, 0, 0.34);
}
button {
border: 0px;
width: 26px;
border-radius: 500px;
outline: none !important;
height: 26px;
cursor: pointer;
position: relative;
}
}
#picker-1 {
left: 25%;
top: 25%;
}
.get-code {
position: fixed;
width: 420px;
left: calc(50% - 210px);
textarea {
background: rgba(0, 0, 0, 0.3);
color: #fff;
padding: 10px 10px 0px 10px;
width: 100%;
height: 148px;
overflow: hidden;
outline: none;
border: 0px;
resize: none;
border-radius: 10px;
font-size: 9pt;
line-height: 14pt;
font-weight: 100;
border: 2px solid rgba(0, 0, 0, 0);
cursor: pointer;
transition: all 0.5s ease;
-webkit-transition: all 0.5s ease;
-webkit-box-shadow: 0px 0px 28px 1px rgba(0, 0, 0, 0.34);
-moz-box-shadow: 0px 0px 28px 1px rgba(0, 0, 0, 0.34);
box-shadow: 0px 0px 28px 1px rgba(0, 0, 0, 0.34);
&:focus {
border: 2px solid #fff;
}
&:hover {
-webkit-box-shadow: 0px 0px 12px 1px rgba(0, 0, 0, 0.34);
-moz-box-shadow: 0px 0px 12px 1px rgba(0, 0, 0, 0.34);
box-shadow: 0px 0px 12px 1px rgba(0, 0, 0, 0.34);
}
}
span {
width: 100%;
position: absolute;
bottom: calc(100% + 10px);
text-align: center;
left: 0;
color: rgba(0, 0, 0, 0.7);
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}
}
.code-toggle {
z-index: 1000000;
color: #1a1a1a;
position: absolute;
top: 10px;
cursor: pointer;
text-align: center;
font-size: 8pt;
padding: 10px;
width: 200px;
left: calc(50% - 100px);
line-height: 18pt;
font-weight: 700;
opacity: 0.5;
transition: all 0.3s ease;
-webkit-transition: all 0.3s ease;
user-select: none;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
i {
font-size: 25pt;
}
&:hover {
opacity: 1;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment