How to Build a String in a Loop for a Dynamic Gradient

How can I build a string in a loop for a dynamic gradient?

If I understand the goal correctly what you need is "Property Values Merge" feature so together with certain "Pattern-matching" optimizations the mixin could look like (assuming Less 1.7.x or higher, but I tested this only with v2):

// usage:

@gray: #010101;
@white: #020202;
@black: #030303;

@gradients: @gray 0%, @white 30%, @black 100%;

div {
.make-gradient(@gradients, left);
// or just:
// .make-gradient(@gray 0%, @white 30%, @black 100%; left);
}

// impl.:

.make-gradient(@gradients, @direction, @fade: 50%) {
background+: ~"linear-gradient(" @dir;
.loop(length(@gradients));
.loop(@i) when (@i > 0) {
.loop((@i - 1));
@gradient: extract(@gradients, @i);
@color: extract(@gradient, 1);
@stop: extract(@gradient, 2);
background+: fade(@color, @fade) @stop;
}
background+_:);

.dir(@direction);
.dir(@dir_) {@dir: @dir_}
.dir(left) {@dir: to right}
.dir(top) {@dir: to bottom}
}

I did not include any vendor prefixing because of tools like Autoprefixer (especially since it's now included as a plugin for Less v2), but I guess you'll easily add that yourself if you still find such kludge worthy.

P.S. As suggested in comments below: background+_:); works only in v2 (so it's more like an unintended bogus), more safe syntax is obviously background+_: ~")";

Making dynamic background colors in loop

You can use template literals to bind the color property value dynamically.

Demo :

new Vue({
el: '#app',
data: {
selectedProduct: {
color_attributes: ['green', 'blue', 'yellow']
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(colorAttribute, index) of selectedProduct.color_attributes" :key="index">
<span class="color-attribute" :style="`background: ${colorAttribute}`"> {{ colorAttribute }} </span>
</div>
</div>

Python: Create dynamic loop based on pattern

Something like this should work:

import itertools

mapping = {
'v': 'aeiou',
'c': 'bcdfghjklmnpqrstvwxyz'
}

pattern = 'vcvcv'

for thing in itertools.product(*map(mapping.get, pattern)):
print ''.join(thing)

Here's roughly how it works:

  • map(mapping.get, pattern) just converts 'vcv' to ['aeiou', 'bcdfghjklmnpqrstvwxyz', 'aeiou']. It replaces each letter with the corresponding list of characters.
  • *map(...) unpacks the argument list.
  • itertools.product() is like a bunch of nested for loops.
  • ''.join(thing) joins the list of characters into a single string.

If you want to do this without itertools, you'll have to make a recursive function.

Fill array dynamicly with gradient color c++

We want to go from:

red -> yellow
yellow -> green
green -> cyan
cyan -> blue
blue -> magenta
magenta -> red

In each pass, one of the red, green, blue components is always 0, the second is 255, and the third is increasing or decreasing between 0 and 255.

In other words:

{255,  0,    0} -> {255, 255,   0} grn increases to 255
{255, 255, 0} -> { 0, 255, 0} red decreases to 0
{0 , 255, 0} -> { 0, 255, 255} blu increases to 255
{0 , 255, 255} -> { 0, 0, 255} grn decreases to 0
{0 , 0, 255} -> {255, 0, 255} red increases to 255
{255, 0, 255} -> {255, 0, 0} blu decreases to 0

This produces 256 * 6 colors, we may not want all of those colors, so it has to be normalized. This can be done with following code:

//input: ratio is between 0.0 to 1.0
//output: rgb color
uint32_t rgb(double ratio)
{
//we want to normalize ratio so that it fits in to 6 regions
//where each region is 256 units long
int normalized = int(ratio * 256 * 6);

//find the region for this position
int region = normalized / 256;

//find the distance to the start of the closest region
int x = normalized % 256;

uint8_t r = 0, g = 0, b = 0;
switch (region)
{
case 0: r = 255; g = 0; b = 0; g += x; break;
case 1: r = 255; g = 255; b = 0; r -= x; break;
case 2: r = 0; g = 255; b = 0; b += x; break;
case 3: r = 0; g = 255; b = 255; g -= x; break;
case 4: r = 0; g = 0; b = 255; r += x; break;
case 5: r = 255; g = 0; b = 255; b -= x; break;
}
return r + (g << 8) + (b << 16);
}

Usage:

double range = 500.0;
for (double i = 0; i < range; i++)
{
uint32_t color = rgb(i / range);
...
}

Output:

Sample Image

Assigning gradient using JS fails on dynamically generated gradient

The problem is that you don't have any units on your values. 0 is a special value, it doesn't require any units, but all other values do.

Adding px solves the problem:

let gradient = 'radial-gradient(circle at ' + e.clientX + 'px ' + e.clientY + 'px, blue, red)';
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^−−−−−−−−−−−−−−−−−−^^

FWIW, I'd use a template literal:

let gradient = `radial-gradient(circle at ${e.clientX}px ${e.clientY}px, blue, red)`;
// −−−−−−−−−−−−^−−−−−−−−−−−−−−−−−−−−−−−−−−^^−−−−−−−−−^^^−^^−−−−−−−−−^^^−−−−−−−−−−−−^

let divs = document.getElementsByClassName('buggy-gradient');

for(i = 0; i < divs.length; i++){
divs.item(i).addEventListener('mousemove', e => {
let gradient = `radial-gradient(circle at ${e.clientX}px ${e.clientY}px, blue, red)`;
console.log(gradient);
e.target.style.background = gradient;
});
}
div {
height: 400px;
width: 400px;
background: radial-gradient(green, yellow);
display: inline-block;
margin: 5px;
}
<div class=buggy-gradient></div>
<div class=buggy-gradient></div>
<div class=buggy-gradient></div>

Swiftui: Fetch Dynamic Color Gradient from JSON?

In SwiftUI ForEach is a view that lets you pass a collection of data views similar to the subview of UIView in UIKit. so you can not use it inside the init method. For more (https://developer.apple.com/documentation/swiftui/foreach)

The correct use of code:

struct Item: Codable, Identifiable {
var id = UUID()
let colors: [String]
}

struct ContentView: View {
let item: Item

init(item: Item){
self.item = item
}

var body: some View {
Circle()
.fill(LinearGradient(gradient: Gradient(colors: item.colors.map{Color(hex: $0)}), startPoint: .leading, endPoint: .trailing))
}
}

If you want to iterate your array by using forEach, you need to use the same as the old way.

Example:

struct ContentView: View {
let item: Item

var gradientColors: [Color] = []

init(item: Item){
self.item = item
item.colors.forEach { (strColor) in
gradientColors.append(Color(hex: strColor))
}
}

var body: some View {
Circle()
.fill(LinearGradient(gradient: Gradient(colors: gradientColors), startPoint: .leading, endPoint: .trailing))
}
}

Also, one more thing. If you try to add a gradient to the circle, it's not work with .background(LinearGradient. For this you need to use .fill

var body: some View {
Circle()
.fill(LinearGradient(gradient: Gradient(colors: gradientColors), startPoint: .leading, endPoint: .trailing))
}


Related Topics



Leave a reply



Submit