{"__browser":{"country":"US","device":"unknown_device","mobile":false,"name":"unknown browser","platform":"unknown_platform","version":"0"},"__constants":{},"__CPDATA":{"domain_iframe":"https://cdpn.io","environment":"production","host":"codepen.io","iframe_allow":"accelerometer *; ambient-light-sensor *; camera *; display-capture *; encrypted-media *; geolocation *; gyroscope *; microphone *; midi *; payment *; serial *; vr *; web-share *; xr-spatial-tracking *","iframe_sandbox":"allow-downloads allow-forms allow-modals allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts allow-top-navigation-by-user-activation"},"__graphql":{"data":{"data":{"sessionUser":{"id":"VoDkNZ","name":"Captain Anonymous","title":"Captain Anonymous","avatar":"https://assets.codepen.io/t-1/user-default-avatar.jpg?format=auto&version=0","currentContext":{"id":"VoDkNZ","title":"Captain Anonymous","name":"Captain Anonymous","avatar":"https://assets.codepen.io/t-1/user-default-avatar.jpg?format=auto&version=0","username":"anon","__typename":"User"},"currentTeamId":null,"username":"anon","admin":false,"anon":true,"pro":false,"verified":false,"featureFlags":[],"teams":[],"__typename":"User"}}},"url":"https://codepen.io/graphql","api":"cprails"},"__user":{"anon":true,"base_url":"/anon/","cohorts":[],"current_team_hashid":null,"current_team_id":0,"hashid":"VoDkNZ","id":1,"itemType":"user","name":"Captain Anonymous","paid":false,"tier":0,"username":"anon","created_at":null,"email_verified":null,"collections_count":0,"collections_private_count":0,"followers_count":0,"followings_count":0,"pens_count":0,"pens_private_count":0,"projects_count":0,"projects_private_count":0},"__firebase":{"config":{"apiKey":"AIzaSyBgLAe7N_MdFpuVofMkcQLGwwhUu5tuxls","authDomain":"codepen-store-production.firebaseapp.com","databaseURL":"https://codepen-store-production.firebaseio.com","disabled":false,"projectId":"codepen-store-production"},"token":"eyJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJodHRwczovL2lkZW50aXR5dG9vbGtpdC5nb29nbGVhcGlzLmNvbS9nb29nbGUuaWRlbnRpdHkuaWRlbnRpdHl0b29sa2l0LnYxLklkZW50aXR5VG9vbGtpdCIsImNsYWltcyI6eyJvd25lcklkIjoiVm9Ea05aIiwiYWRtaW4iOmZhbHNlfSwiZXhwIjoxNzUwNjMzMzYxLCJpYXQiOjE3NTA2Mjk3NjEsImlzcyI6ImZpcmViYXNlLWFkbWluc2RrLThva3lsQGNvZGVwZW4tc3RvcmUtcHJvZHVjdGlvbi5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInN1YiI6ImZpcmViYXNlLWFkbWluc2RrLThva3lsQGNvZGVwZW4tc3RvcmUtcHJvZHVjdGlvbi5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInVpZCI6IlZvRGtOWiJ9.JPdkr6umi63N8xjA5J-SUB6PQuXPRffn87zmM3yNnB7STjXTNw-zetTIxx01MfLZ7lDSEe1YJxsUJLxP6n2bsP5u_LTPco1-0Odz_Rwe9P1ssghTzxlKkDeRyc0hfsq6teOHrrSDVEyAcZYsgLQ4DPUe0Op1HNh1nlKazVtNKAauPFluSYegCZQo6_PqoUMKIcDoTB8vc4VustEfzB5JtEFS042xYZn3RmDg7E2xerdVWpR-jgNNz1WLuEoi5JpFzXtQV06tqTPj0rVmk2O74UHvgvKkdxiX-SDjyNOBnntFphZn1aU3dU0frL1D0Ct9zjmzOSJdL6gtv6irVhy5Lw"},"__pay_stripe_public_key":"pk_live_2GndomDfiklqpSNQn8FrGuwZSMIMzha7DkLJqlYe7IR0ihKAlKdiHg68JJc5eVPt68rzAjzAAVXcUwjySHRCsgjQQ00gtRBUFNH","__pay_braintree_env":"production","__item":"{\"id\":76949158,\"user_id\":252820,\"html\":\"<a href=\\\"https:\\/\\/www.uiguy.dev\\\" rel=\\\"author\\\" class=\\\"seo-author-link\\\">Peter Benoit<\\/a>\\n<div id=\\\"app\\\" class=\\\"section\\\">\\n\\t<div class=\\\"container is-fluid\\\">\\n\\t\\t<div class=\\\"columns is-desktop\\\">\\n\\t\\t\\t<div class=\\\"column is-half gradient-panel\\\">\\n\\t\\t\\t\\t<div class=\\\"box gradient-preview\\\" :style=\\\"{ background: gradientStyle }\\\"><\\/div>\\n\\t\\t\\t<\\/div>\\n\\n\\t\\t\\t<div class=\\\"column is-half control-panel\\\">\\n\\t\\t\\t\\t<div class=\\\"box controls\\\">\\n\\t\\t\\t\\t\\t<h2 class=\\\"title\\\">GradientMaker<\\/h2>\\n\\n\\t\\t\\t\\t\\t<div class=\\\"field\\\">\\n\\t\\t\\t\\t\\t\\t<label class=\\\"label\\\">Colors:<\\/label>\\n\\t\\t\\t\\t\\t\\t<div class=\\\"control color-pickers\\\">\\n\\t\\t\\t\\t\\t\\t\\t<div v-for=\\\"(color, index) in colors\\\" :key=\\\"index\\\" class=\\\"color-picker\\\">\\n\\t\\t\\t\\t\\t\\t\\t\\t<input type=\\\"color\\\" v-model=\\\"color.value\\\" @input=\\\"updateGradient\\\" \\/>\\n\\t\\t\\t\\t\\t\\t\\t\\t<input class=\\\"slider-vertical\\\" type=\\\"range\\\" v-model=\\\"color.position\\\" min=\\\"0\\\" max=\\\"100\\\" @input=\\\"updateGradient\\\" \\/>\\n\\t\\t\\t\\t\\t\\t\\t\\t<button class=\\\"remove-button\\\" @click=\\\"removeColor(index)\\\" v-if=\\\"colors.length > 2\\\">-<\\/button>\\n\\t\\t\\t\\t\\t\\t\\t<\\/div>\\n\\t\\t\\t\\t\\t\\t\\t<button class=\\\"button add-color\\\" @click=\\\"addColor\\\">+<\\/button>\\n\\t\\t\\t\\t\\t\\t<\\/div>\\n\\t\\t\\t\\t\\t<\\/div>\\n\\n\\t\\t\\t\\t\\t<div class=\\\"field color-mode\\\">\\n\\t\\t\\t\\t\\t\\t<label class=\\\"label\\\">Color Mode:<\\/label>\\n\\t\\t\\t\\t\\t\\t<div class=\\\"control mode-selector\\\">\\n\\t\\t\\t\\t\\t\\t\\t<button class=\\\"button mode-button\\\" v-for=\\\"mode in colorModes\\\" :key=\\\"mode\\\" :class=\\\"{ active: mode === selectedColorMode }\\\" @click=\\\"selectColorMode(mode)\\\">\\n\\t\\t\\t\\t\\t\\t\\t\\t{{ mode }}\\n\\t\\t\\t\\t\\t\\t\\t<\\/button>\\n\\t\\t\\t\\t\\t\\t<\\/div>\\n\\t\\t\\t\\t\\t<\\/div>\\n\\n\\t\\t\\t\\t\\t<div class=\\\"field\\\">\\n\\t\\t\\t\\t\\t\\t<label class=\\\"label\\\">Precision:<\\/label>\\n\\t\\t\\t\\t\\t\\t<div class=\\\"precision-control\\\">\\n\\t\\t\\t\\t\\t\\t\\t<input class=\\\"slider\\\" type=\\\"range\\\" v-model=\\\"precision\\\" min=\\\"1\\\" max=\\\"10\\\" @input=\\\"updateGradient\\\" \\/>\\n\\t\\t\\t\\t\\t\\t\\t<span class=\\\"precision-display\\\">{{ precision }}<\\/span>\\n\\t\\t\\t\\t\\t\\t<\\/div>\\n\\t\\t\\t\\t\\t<\\/div>\\n\\n\\t\\t\\t\\t\\t<div class=\\\"field\\\">\\n\\t\\t\\t\\t\\t\\t<label class=\\\"label\\\">Gradient Type:<\\/label>\\n\\t\\t\\t\\t\\t\\t<div class=\\\"control gradient-type-selector\\\">\\n\\t\\t\\t\\t\\t\\t\\t<button class=\\\"button type-button\\\" :class=\\\"{ active: gradientType === 'linear' }\\\" @click=\\\"selectGradientType('linear')\\\">Linear<\\/button>\\n\\t\\t\\t\\t\\t\\t\\t<button class=\\\"button type-button\\\" :class=\\\"{ active: gradientType === 'radial' }\\\" @click=\\\"selectGradientType('radial')\\\">Radial<\\/button>\\n\\t\\t\\t\\t\\t\\t<\\/div>\\n\\t\\t\\t\\t\\t<\\/div>\\n\\n\\t\\t\\t\\t\\t<div class=\\\"field\\\" v-if=\\\"gradientType === 'linear'\\\">\\n\\t\\t\\t\\t\\t\\t<label class=\\\"label\\\">Angle:<\\/label>\\n\\t\\t\\t\\t\\t\\t<div class=\\\"angle-control\\\">\\n\\t\\t\\t\\t\\t\\t\\t<input class=\\\"slider\\\" type=\\\"range\\\" v-model=\\\"angle\\\" min=\\\"0\\\" max=\\\"360\\\" @input=\\\"updateGradient\\\" \\/>\\n\\t\\t\\t\\t\\t\\t\\t<span class=\\\"angle-display\\\">{{ angle }}deg<\\/span>\\n\\t\\t\\t\\t\\t\\t<\\/div>\\n\\t\\t\\t\\t\\t<\\/div>\\n\\n\\t\\t\\t\\t\\t<div class=\\\"field\\\">\\n\\t\\t\\t\\t\\t\\t<label class=\\\"label\\\">Your Gradient:<\\/label>\\n\\t\\t\\t\\t\\t\\t<div class=\\\"gradient-css\\\" v-html=\\\"colorizedGradientStyle\\\"><\\/div>\\n\\t\\t\\t\\t\\t<\\/div>\\n\\n\\t\\t\\t\\t\\t<div class=\\\"field is-grouped is-relative\\\">\\n\\t\\t\\t\\t\\t\\t<div v-if=\\\"notification.visible\\\" class=\\\"notification is-info popup\\\">\\n\\t\\t\\t\\t\\t\\t\\t{{ notification.message }}\\n\\t\\t\\t\\t\\t\\t<\\/div>\\n\\t\\t\\t\\t\\t\\t<button class=\\\"button is-primary\\\" @click=\\\"copyCssToClipboard\\\">Copy CSS<\\/button>\\n\\t\\t\\t\\t\\t\\t<button class=\\\"button is-primary\\\" @click=\\\"exportAsImage\\\">Export as Image<\\/button>\\n\\t\\t\\t\\t\\t<\\/div>\\n\\t\\t\\t\\t<\\/div>\\n\\t\\t\\t<\\/div>\\n\\t\\t<\\/div>\\n\\t<\\/div>\\n<\\/div>\",\"css\":\".dark-theme {\\n\\tbackground-color: #1a1a1a;\\n\\tcolor: #e0e0e0;\\n\\tfont-family: \\\"Inter\\\", sans-serif;\\n}\\n\\n.gradient-panel,\\n.control-panel {\\n\\tpadding: 20px;\\n}\\n\\n.controls {\\n\\tbackground-color: #2a2a2a;\\n\\tborder-radius: 12px;\\n\\tpadding: 20px;\\n}\\n\\n.title,\\n.subtitle {\\n\\tcolor: #ffffff;\\n\\ttext-align: center;\\n}\\n\\n.gradient-preview {\\n\\theight: 800px;\\n\\tborder-radius: 12px;\\n\\tbackground-size: cover;\\n\\tbackground-repeat: no-repeat;\\n}\\n\\n.color-pickers {\\n\\tdisplay: flex;\\n\\talign-items: center;\\n\\tgap: 10px;\\n}\\n\\n.color-picker-wrapper {\\n\\tdisplay: flex;\\n\\talign-items: center;\\n\\tgap: 10px;\\n}\\n\\n.color-picker {\\n\\tdisplay: flex;\\n\\tflex-direction: row;\\n\\talign-items: center;\\n\\tgap: 5px;\\n\\tposition: relative;\\n}\\n\\n.color-picker input[type=\\\"color\\\"] {\\n\\twidth: 80px;\\n\\theight: 80px;\\n\\tborder: none;\\n\\tborder-radius: 4px;\\n}\\n\\n.remove-button {\\n\\tposition: absolute;\\n\\ttop: -5px;\\n\\tleft: -5px;\\n\\tbackground-color: #ff6b6b;\\n\\tcolor: #fff;\\n\\tborder: none;\\n\\tborder-radius: 50%;\\n\\twidth: 18px;\\n\\theight: 18px;\\n\\tdisplay: flex;\\n\\talign-items: center;\\n\\tjustify-content: center;\\n\\tfont-size: 12px;\\n\\tcursor: pointer;\\n\\tz-index: 10;\\n}\\n\\n.add-color {\\n\\tbackground-color: #3a3a3a;\\n\\tcolor: #ffffff;\\n\\tborder: none;\\n\\tpadding: 5px;\\n\\tborder-radius: 4px;\\n\\theight: 80px;\\n\\twidth: 80px;\\n}\\n\\n.mode-button {\\n\\tbackground-color: #444;\\n\\tcolor: #e0e0e0;\\n\\tborder: none;\\n\\tmargin: 5px;\\n}\\n\\n.mode-button.active {\\n\\tbackground-color: #ff5722;\\n\\tcolor: #ffffff;\\n}\\n\\n.slider {\\n\\twidth: 100%;\\n\\tmargin-top: 10px;\\n}\\n\\n.angle-control {\\n\\tdisplay: flex;\\n\\talign-items: center;\\n\\tgap: 10px;\\n}\\n\\n.angle-display {\\n\\tcolor: #ffffff;\\n\\tfont-size: 14px;\\n}\\n\\n.easing-curve {\\n\\tdisplay: flex;\\n\\tjustify-content: space-around;\\n\\tmargin-top: 10px;\\n}\\n\\n.easing-button {\\n\\tbackground-color: #3a3a3a;\\n\\tcolor: #ffffff;\\n\\tborder: none;\\n\\tpadding: 5px 15px;\\n\\tborder-radius: 4px;\\n}\\n\\n.gradient-css {\\n\\tbackground-color: #1e1e1e;\\n\\tcolor: #e0e0e0;\\n\\tborder: none;\\n\\tpadding: 10px;\\n\\tborder-radius: 4px;\\n\\tresize: none;\\n}\\n\\ninput[type=\\\"range\\\"] {\\n\\t-webkit-appearance: none;\\n\\twidth: 100%;\\n\\theight: 3px;\\n\\tbackground: #666;\\n\\toutline: none;\\n\\tborder-radius: 2px;\\n\\ttransition: background 0.2s;\\n\\tmargin-top: 10px;\\n\\n\\t&.slider-vertical {\\n\\t\\theight: 80px;\\n\\t\\twidth: 3px;\\n\\t\\twriting-mode: bt-lr;\\n\\t\\t-webkit-appearance: slider-vertical;\\n\\t}\\n}\\n\\ninput[type=\\\"range\\\"],\\ninput[type=\\\"range\\\"].slider-vertical {\\n\\t&::-webkit-slider-thumb {\\n\\t\\t-webkit-appearance: none;\\n\\t\\twidth: 20px;\\n\\t\\theight: 20px;\\n\\t\\tbackground: #d4d4d4;\\n\\t\\tborder-radius: 50%;\\n\\t\\tcursor: pointer;\\n\\t\\ttransition: background 0.2s;\\n\\t\\tborder: 2px solid #444;\\n\\t}\\n}\\n\\ninput[type=\\\"range\\\"]:focus {\\n\\tbackground: #888;\\n}\\n\\n.slider-vertical {\\n\\tposition: relative;\\n\\ttop: -5px;\\n}\\n\\n.precision-control {\\n\\tdisplay: flex;\\n\\talign-items: center;\\n\\tgap: 10px;\\n}\\n\\n.precision-display {\\n\\tcolor: #fff;\\n\\tfont-size: 14px;\\n}\\n\\n.button.is-primary {\\n\\tbackground-color: #444;\\n\\tcolor: #ffffff;\\n\\tborder: none;\\n\\tmargin: 5px;\\n\\tpadding: 5px 15px;\\n\\tborder-radius: 4px;\\n\\tcursor: pointer;\\n\\ttransition: background 0.3s;\\n}\\n\\n.button.is-primary:hover {\\n\\tbackground-color: #ff5722;\\n}\\n\\n.gradient-css {\\n\\tbackground-color: #1e1e1e;\\n\\tcolor: #e0e0e0;\\n\\tborder: none;\\n\\tpadding: 10px;\\n\\tborder-radius: 4px;\\n\\tfont-family: monospace;\\n\\twhite-space: pre-wrap;\\n\\toverflow: auto;\\n\\t\\/\\/ max-height: 200px;\\n}\\n\\n.css-function {\\n\\tcolor: #ff9800;\\n}\\n\\n.css-value {\\n\\tcolor: #4caf50;\\n}\\n\\n.css-color {\\n\\tcolor: #2196f3;\\n}\\n\\n.gradient-type-selector {\\n\\tdisplay: flex;\\n\\talign-items: center;\\n\\tgap: 10px;\\n\\tmargin-bottom: 10px;\\n}\\n\\n.type-button {\\n\\tbackground-color: #444;\\n\\tcolor: #e0e0e0;\\n\\tborder: none;\\n\\tpadding: 5px 15px;\\n\\tborder-radius: 4px;\\n\\tcursor: pointer;\\n\\ttransition: background 0.3s;\\n}\\n\\n.type-button.active {\\n\\tbackground-color: #ff5722;\\n\\tcolor: #ffffff;\\n}\\n\\n.color-mode {\\n\\tdisplay: none;\\n}\\n\\n.popup {\\n\\tposition: absolute;\\n\\ttop: -30px;\\n\\tbackground-color: #3298dc;\\n\\tcolor: #fff;\\n\\tpadding: 5px 10px;\\n\\tborder-radius: 4px;\\n\\tbox-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\\n\\ttransition: opacity 0.3s;\\n\\tz-index: 10;\\n}\",\"js\":\"const { createApp } = Vue;\\n\\ncreateApp({\\n\\tdata() {\\n\\t\\treturn {\\n\\t\\t\\tgradientType: \\\"linear\\\",\\n\\t\\t\\tcolors: [\\n\\t\\t\\t\\t{ value: \\\"#D16BA5\\\", position: 0 },\\n\\t\\t\\t\\t{ value: \\\"#86A8E7\\\", position: 50 },\\n\\t\\t\\t\\t{ value: \\\"#5FFBF1\\\", position: 80 }\\n\\t\\t\\t],\\n\\t\\t\\tangle: 45,\\n\\t\\t\\tsize: 50,\\n\\t\\t\\tprecision: 1,\\n\\t\\t\\tselectedColorMode: \\\"HSL\\\",\\n\\t\\t\\tcolorModes: [\\\"LRGB\\\", \\\"HSL\\\", \\\"HSV\\\", \\\"HCL\\\", \\\"LAB\\\"],\\n\\t\\t\\tnotification: {\\n\\t\\t\\t\\tmessage: \\\"\\\",\\n\\t\\t\\t\\tvisible: false\\n\\t\\t\\t}\\n\\t\\t};\\n\\t},\\n\\tcomputed: {\\n\\t\\tgradientStyle() {\\n\\t\\t\\tconst colorStops = this.generateIntermediateColors(\\n\\t\\t\\t\\tthis.colors,\\n\\t\\t\\t\\tthis.precision\\n\\t\\t\\t)\\n\\t\\t\\t\\t.map((color) => `${color.value} ${color.position}%`)\\n\\t\\t\\t\\t.join(\\\", \\\");\\n\\n\\t\\t\\tif (this.gradientType === \\\"linear\\\") {\\n\\t\\t\\t\\treturn `linear-gradient(${this.angle}deg, ${colorStops})`;\\n\\t\\t\\t} else if (this.gradientType === \\\"radial\\\") {\\n\\t\\t\\t\\treturn `radial-gradient(circle at ${this.size}%, ${colorStops})`;\\n\\t\\t\\t}\\n\\t\\t\\treturn \\\"\\\";\\n\\t\\t},\\n\\t\\troundedGradientStyle() {\\n\\t\\t\\tconst colorStops = this.generateIntermediateColors(\\n\\t\\t\\t\\tthis.colors,\\n\\t\\t\\t\\tthis.precision\\n\\t\\t\\t)\\n\\t\\t\\t\\t.map((color) => `${color.value} ${Math.round(color.position * 100) \\/ 100}%`)\\n\\t\\t\\t\\t.join(\\\", \\\");\\n\\n\\t\\t\\tif (this.gradientType === \\\"linear\\\") {\\n\\t\\t\\t\\treturn `linear-gradient(${this.angle}deg, ${colorStops})`;\\n\\t\\t\\t} else if (this.gradientType === \\\"radial\\\") {\\n\\t\\t\\t\\treturn `radial-gradient(circle at ${this.size}%, ${colorStops})`;\\n\\t\\t\\t}\\n\\t\\t\\treturn \\\"\\\";\\n\\t\\t},\\n\\t\\tcolorizedGradientStyle() {\\n\\t\\t\\tconst css = `background-image: ${this.roundedGradientStyle};`;\\n\\n\\t\\t\\treturn css\\n\\t\\t\\t\\t.replace(\\n\\t\\t\\t\\t\\t\\/(background-image:|linear-gradient|radial-gradient)\\/g,\\n\\t\\t\\t\\t\\t'<span class=\\\"css-function\\\">$1<\\/span>'\\n\\t\\t\\t\\t)\\n\\t\\t\\t\\t.replace(\\/(\\\\d+deg|\\\\d+%)\\/g, '<span class=\\\"css-value\\\">$1<\\/span>')\\n\\t\\t\\t\\t.replace(\\n\\t\\t\\t\\t\\t\\/(rgb\\\\([^)]*\\\\)|#[a-fA-F0-9]{6})\\/g,\\n\\t\\t\\t\\t\\t'<span class=\\\"css-color\\\">$1<\\/span>'\\n\\t\\t\\t\\t)\\n\\t\\t\\t\\t.replace(\\/,(?![^(]*\\\\))\\/g, \\\",<br>\\\");\\n\\t\\t}\\n\\t},\\n\\tmethods: {\\n\\t\\tupdateGradient() {\\n\\t\\t\\tthis.adjustPositions();\\n\\t\\t},\\n\\t\\tselectGradientType(type) {\\n\\t\\t\\tthis.gradientType = type;\\n\\t\\t\\tthis.updateGradient();\\n\\t\\t},\\n\\t\\taddColor() {\\n\\t\\t\\tif (this.colors.length < 10) {\\n\\t\\t\\t\\tthis.colors.push({ value: \\\"#ffffff\\\", position: 50 });\\n\\t\\t\\t\\tthis.updateGradient();\\n\\t\\t\\t} else {\\n\\t\\t\\t\\talert(`Maximum of 10 colors allowed.`);\\n\\t\\t\\t}\\n\\t\\t},\\n\\t\\tremoveColor(index) {\\n\\t\\t\\tif (this.colors.length > 2) {\\n\\t\\t\\t\\tthis.colors.splice(index, 1);\\n\\t\\t\\t\\tthis.updateGradient();\\n\\t\\t\\t} else {\\n\\t\\t\\t\\talert(\\\"At least two colors are required for a gradient.\\\");\\n\\t\\t\\t}\\n\\t\\t},\\n\\t\\tcopyCssToClipboard() {\\n\\t\\t\\tnavigator.clipboard.writeText(this.roundedGradientStyle).then(\\n\\t\\t\\t\\t() => alert(\\\"CSS copied to clipboard!\\\"),\\n\\t\\t\\t\\t() => alert(\\\"Failed to copy CSS.\\\")\\n\\t\\t\\t);\\n\\t\\t},\\n\\t\\texportAsImage() {\\n\\t\\t\\tconst canvas = document.createElement(\\\"canvas\\\");\\n\\t\\t\\tcanvas.width = 500;\\n\\t\\t\\tcanvas.height = 800;\\n\\t\\t\\tconst ctx = canvas.getContext(\\\"2d\\\");\\n\\n\\t\\t\\tconst gradient =\\n\\t\\t\\t\\tthis.gradientType === \\\"linear\\\"\\n\\t\\t\\t\\t\\t? ctx.createLinearGradient(0, 0, canvas.width, canvas.height)\\n\\t\\t\\t\\t\\t: ctx.createRadialGradient(\\n\\t\\t\\t\\t\\t\\t\\tcanvas.width \\/ 2,\\n\\t\\t\\t\\t\\t\\t\\tcanvas.height \\/ 2,\\n\\t\\t\\t\\t\\t\\t\\t0,\\n\\t\\t\\t\\t\\t\\t\\tcanvas.width \\/ 2,\\n\\t\\t\\t\\t\\t\\t\\tcanvas.height \\/ 2,\\n\\t\\t\\t\\t\\t\\t\\t(canvas.width * this.size) \\/ 100\\n\\t\\t\\t\\t\\t );\\n\\n\\t\\t\\tthis.colors.forEach((color) => {\\n\\t\\t\\t\\tgradient.addColorStop(color.position \\/ 100, color.value);\\n\\t\\t\\t});\\n\\n\\t\\t\\tctx.fillStyle = gradient;\\n\\t\\t\\tctx.fillRect(0, 0, canvas.width, canvas.height);\\n\\n\\t\\t\\tconst link = document.createElement(\\\"a\\\");\\n\\t\\t\\tlink.download = \\\"gradient.png\\\";\\n\\t\\t\\tlink.href = canvas.toDataURL();\\n\\t\\t\\tlink.click();\\n\\t\\t},\\n\\t\\tgenerateIntermediateColors(colors, precision) {\\n\\t\\t\\tif (precision <= 1) return colors;\\n\\n\\t\\t\\tconst steps = [];\\n\\t\\t\\tfor (let i = 0; i < colors.length - 1; i++) {\\n\\t\\t\\t\\tconst start = colors[i];\\n\\t\\t\\t\\tconst end = colors[i + 1];\\n\\t\\t\\t\\tsteps.push(start);\\n\\n\\t\\t\\t\\tfor (let j = 1; j < precision; j++) {\\n\\t\\t\\t\\t\\tconst t = j \\/ precision;\\n\\t\\t\\t\\t\\tconst interpolatedColor = this.lerpColor(start.value, end.value, t);\\n\\t\\t\\t\\t\\tconst interpolatedPosition = (1 - t) * start.position + t * end.position;\\n\\n\\t\\t\\t\\t\\tsteps.push({ value: interpolatedColor, position: interpolatedPosition });\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\tsteps.push(colors[colors.length - 1]);\\n\\t\\t\\treturn steps;\\n\\t\\t},\\n\\t\\tlerpColor(start, end, t) {\\n\\t\\t\\tconst startRGB = this.hexToRgb(start);\\n\\t\\t\\tconst endRGB = this.hexToRgb(end);\\n\\n\\t\\t\\tconst r = Math.round(startRGB.r + (endRGB.r - startRGB.r) * t);\\n\\t\\t\\tconst g = Math.round(startRGB.g + (endRGB.g - startRGB.g) * t);\\n\\t\\t\\tconst b = Math.round(startRGB.b + (endRGB.b - startRGB.b) * t);\\n\\n\\t\\t\\treturn `rgb(${r}, ${g}, ${b})`;\\n\\t\\t},\\n\\t\\thexToRgb(hex) {\\n\\t\\t\\tlet shorthandRegex = \\/^#?([a-f\\\\d])([a-f\\\\d])([a-f\\\\d])$\\/i;\\n\\t\\t\\thex = hex.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b);\\n\\t\\t\\tlet result = \\/^#?([a-f\\\\d]{2})([a-f\\\\d]{2})([a-f\\\\d]{2})$\\/i.exec(hex);\\n\\t\\t\\treturn result\\n\\t\\t\\t\\t? {\\n\\t\\t\\t\\t\\t\\tr: parseInt(result[1], 16),\\n\\t\\t\\t\\t\\t\\tg: parseInt(result[2], 16),\\n\\t\\t\\t\\t\\t\\tb: parseInt(result[3], 16)\\n\\t\\t\\t\\t }\\n\\t\\t\\t\\t: null;\\n\\t\\t},\\n\\t\\tadjustPositions() {\\n\\t\\t\\tfor (let i = 1; i < this.colors.length; i++) {\\n\\t\\t\\t\\tif (this.colors[i].position <= this.colors[i - 1].position) {\\n\\t\\t\\t\\t\\tthis.colors[i].position = Math.min(this.colors[i - 1].position + 1, 100);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\tif (\\n\\t\\t\\t\\tthis.colors[this.colors.length - 1].position <\\n\\t\\t\\t\\tthis.colors[this.colors.length - 2].position\\n\\t\\t\\t) {\\n\\t\\t\\t\\tthis.colors[this.colors.length - 1].position = Math.min(\\n\\t\\t\\t\\t\\tthis.colors[this.colors.length - 2].position + 1,\\n\\t\\t\\t\\t\\t100\\n\\t\\t\\t\\t);\\n\\t\\t\\t}\\n\\t\\t},\\n\\t\\tshowNotification(message) {\\n\\t\\t\\tthis.notification.message = message;\\n\\t\\t\\tthis.notification.visible = true;\\n\\t\\t\\tsetTimeout(() => {\\n\\t\\t\\t\\tthis.notification.visible = false;\\n\\t\\t\\t}, 2000);\\n\\t\\t},\\n\\t\\taddColor() {\\n\\t\\t\\tif (this.colors.length < 10) {\\n\\t\\t\\t\\tthis.colors.push({ value: \\\"#ffffff\\\", position: 50 });\\n\\t\\t\\t\\tthis.updateGradient();\\n\\t\\t\\t\\tthis.showNotification(\\\"Color added successfully!\\\");\\n\\t\\t\\t} else {\\n\\t\\t\\t\\tthis.showNotification(\\\"Maximum of 10 colors allowed.\\\");\\n\\t\\t\\t}\\n\\t\\t},\\n\\t\\tcopyCssToClipboard() {\\n\\t\\t\\tnavigator.clipboard.writeText(this.roundedGradientStyle).then(\\n\\t\\t\\t\\t() => this.showNotification(\\\"CSS copied to clipboard!\\\"),\\n\\t\\t\\t\\t() => this.showNotification(\\\"Failed to copy CSS.\\\")\\n\\t\\t\\t);\\n\\t\\t}\\t\\t\\n\\t}\\n}).mount(\\\"#app\\\");\\n\",\"html_pre_processor\":\"none\",\"css_pre_processor\":\"scss\",\"js_pre_processor\":\"none\",\"html_classes\":\"dark-theme\",\"css_starter\":\"neither\",\"js_library\":null,\"created_at\":\"2024-09-12T13:51:40.459Z\",\"updated_at\":\"2025-06-01T15:50:09.106Z\",\"title\":\"GradientMaker\",\"description\":\"Yet another CSS gradient generator. Really more of a fun project to work in Vue.\",\"slug_hash\":\"bGPJeWj\",\"head\":\"<meta name=\\\"author\\\" content=\\\"Peter Benoit\\\">\\n<meta name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1\\\">\",\"private\":false,\"slug_hash_private\":\"276e7eca8494ca1322afe31dff07ea99\",\"has_animation\":false,\"team_id\":0,\"css_prefix\":\"neither\",\"template\":false,\"parent_id\":76936997,\"comments_count\":0,\"custom_screenshot_filename\":null,\"loves_count\":0,\"pick\":false,\"popularity\":6,\"views_count\":58,\"pick_visible_at\":null,\"cpid\":\"0191e681-03ab-7c8c-8cb0-e09c230ddacb\",\"is_new_editor_pen\":false,\"access\":\"Public\",\"pen_hash\":null,\"hashid\":\"bGPJeWj\"}"}