本文介绍了材料设计调色板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谷歌设计了一个调色板。给定一个颜色,我要动态地创建在Android的调色板。

Google has designed a color palette. Given a color, I want to dynamically create the palette in Android.

有没有在Graphic设计网站和 JavaScript的解决方案产生了类似的调色板一个开源。的因素为各颜色被发现这里和用于创建色彩的功能在这个计算器回答发现。

There was a similar question in the Graphic Design site and an open source javascript solution which generates a similar color palette. The factors for each color are found here and the function used to create the color is found in this stackoverflow answer.

我使用的答案,项目生成的调色板,类似于谷歌的。不过,我想一个算法,将返回的谷歌已经产生的精确值(见的第一个链接)。

I used that answer and project to generate a palette that is similar to Google's. However, I want an algorithm that would return the exact values which Google has generated (see the first link).

问:谷歌是如何计算的调色板颜色的材料设计

Question: How does Google calculate the palette colors for material design?

根据掉上面的信息,我创造了这个例子来说明我是如何产生类似的调色板。再一次,我想要的确切值。

Based off the information above, I created this example to show how I generated a similar palette. Again, I want the exact values.

import android.app.Activity;
import android.app.AlertDialog;
import android.graphics.Color;
import android.os.AsyncTask;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;

/**
 * @author Jared Rummler <[email protected]>
 */
public class PaletteTask extends AsyncTask<Integer, Void, List<PaletteTask.Shade>> {

  private static int shadeColor(int color, double percent) {
    return shadeColor(String.format("#%06X", (0xFFFFFF & color)), percent);
  }

  private static int shadeColor(String color, double percent) {
    long f = Long.parseLong(color.substring(1), 16);
    double t = percent < 0 ? 0 : 255;
    double p = percent < 0 ? percent * -1 : percent;
    long R = f >> 16;
    long G = f >> 8 & 0x00FF;
    long B = f & 0x0000FF;
    int red = (int) (Math.round((t - R) * p) + R);
    int green = (int) (Math.round((t - G) * p) + G);
    int blue = (int) (Math.round((t - B) * p) + B);
    return Color.rgb(red, green, blue);
  }

  private final WeakReference<Activity> activityWeakReference;

  private final List<Shade> shades = new LinkedList<>();

  {
    shades.add(new Shade(0.9, "50"));
    shades.add(new Shade(0.7, "100"));
    shades.add(new Shade(0.5, "200"));
    shades.add(new Shade(0.333, "300"));
    shades.add(new Shade(0.166, "400"));
    shades.add(new Shade(0, "500"));
    shades.add(new Shade(-0.125, "600"));
    shades.add(new Shade(-0.25, "700"));
    shades.add(new Shade(-0.375, "800"));
    shades.add(new Shade(-0.5, "900"));
    shades.add(new Shade(0.7, "A100"));
    shades.add(new Shade(0.5, "A200"));
    shades.add(new Shade(0.166, "A400"));
    shades.add(new Shade(-0.25, "A700"));
  }

  public PaletteTask(Activity activity) {
    activityWeakReference = new WeakReference<>(activity);
  }

  @Override protected List<Shade> doInBackground(Integer... colors) {

    for (Shade shade : shades) {
      shade.color = shadeColor(colors[0], shade.percent);
    }

    return shades;
  }

  @Override protected void onPostExecute(List<Shade> shades) {
    Activity activity = activityWeakReference.get();
    if (activity == null || activity.isFinishing()) {
      return;
    }

    // Create a dialog that shows our generated colors:

    ScrollView scrollView = new ScrollView(activity);
    LinearLayout linearLayout = new LinearLayout(activity);
    linearLayout.setOrientation(LinearLayout.VERTICAL);

    int width, height;
    width = LinearLayout.LayoutParams.MATCH_PARENT;
    height = (int) (30/*dp*/ * (activity.getResources().getDisplayMetrics().densityDpi / 160f));

    // add each color
    for (Shade shade : shades) {
      LinearLayout layoutColor = new LinearLayout(activity);
      TextView textView = new TextView(activity);

      layoutColor.setLayoutParams(new LinearLayout.LayoutParams(width, height));
      layoutColor.setBackgroundColor(shade.color);
      layoutColor.setGravity(Gravity.CENTER);

      textView.setText(shade.name + "    " + String.format("#%06X", (0xFFFFFF & shade.color)));

      layoutColor.addView(textView);
      linearLayout.addView(layoutColor);
    }

    scrollView.addView(linearLayout);

    new AlertDialog.Builder(activity).setView(scrollView).show();
  }

  public static class Shade {

    final double percent;
    final String name;
    int color;

    public Shade(double percent, String name) {
      this.percent = percent;
      this.name = name;
    }
  }

}

调用 AsynTask

int materialRed500 = 0xFFF44336;
new PaletteTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, materialRed500);

对话从上面的code创建的:

Dialog created from the above code:

推荐答案

底线,您不能生成使用单一颜色总是完全匹配相应的谷歌材料设计调色板的调色板。

这是因为调色板都遵循一个不同的进程颜色。例如,使用下面的进程中产生的红色面板(JS code。使用TinyColor.js,但你仍然可以看到HSL修改):

This is because the palettes all follow a different progression of colors. For example, the red palette is generated using the following progression (JS code using TinyColor.js, but you can still see the HSL modifications):

return [
            { hex : tinycolor( hex ).lighten( 37.7 ).saturate( 10.4 ).spin( -13 ).toHexString(), name : '50' },
            { hex : tinycolor( hex ).lighten( 31.8 ).saturate( 10.4 ).spin( -9.5 ).toHexString(), name : '100' },
            { hex : tinycolor( hex ).lighten( 18.7 ).desaturate( 17 ).spin( -3.9 ).toHexString(), name : '200' },
            { hex : tinycolor( hex ).lighten( 9.1 ).desaturate( 20.9 ).spin( -4 ).toHexString(), name : '300' },
            { hex : tinycolor( hex ).lighten( 4.1 ).desaturate( 6.6 ).spin( -3 ).toHexString(), name : '400' },
            { hex : hex, name : '500' },
            { hex : tinycolor( hex ).darken( 3.1 ).desaturate( 12.4 ).spin( -2.7 ).toHexString(), name: '600' },
            { hex : tinycolor( hex ).darken( 7.8 ).desaturate( 24.5 ).spin( -4 ).toHexString(), name: '700' },
            { hex : tinycolor( hex ).darken( 11.7 ).desaturate( 23.2 ).spin( -4 ).toHexString(), name: '800' },
            { hex : tinycolor( hex ).darken( 17 ).desaturate( 16.1 ).spin( -4 ).toHexString(), name: '900' },
            { hex : tinycolor( hex ).lighten( 16.7 ).saturate( 10.4 ).spin( 0.6 ).toHexString(), name: 'A100' },
            { hex : tinycolor( hex ).lighten( 7.7 ).saturate( 10.4 ).spin( -4 ).toHexString(), name: 'A200' },
            { hex : tinycolor( hex ).darken( 3.9 ).saturate( 10.4 ).spin( -15.5 ).toHexString(), name: 'A400' },
            { hex : tinycolor( hex ).darken( 16.6 ).saturate( 10.4 ).spin( -4 ).toHexString(), name: 'A700' }
        ];

不过,当您应用同样的进展,以靛蓝底色(500),你可以看到调色板不匹配的。在下图中,最左边的调色板是默认MD调色板,第二到左边与上述进程产生的调色板。这两个调色板完全匹配。当我在MD加载使用靛蓝500值与红色面板进展code靛蓝调色板(第三个调色板),然后生成一个调色板,它创建了4调色板。正如你所看到的,而这种发展是精确的红色,它的方式,方法关闭其它颜色:

However, when you apply that same progression to the Indigo base color (500), you can see that the palettes don't match up at all. In the following image, the far left palette is the default MD pallette and the second to the left is the palette generated with the above progression. These two palettes match exactly. When I load in the MD Indigo palette (third palette) and then generate a palette using the Indigo 500 value and the Red Palette progression code, it creates the 4th palette. As you can see, while this progression is exact for red, it's way, way off for other colors:

更多关于这个问题,可以发现这里据谷歌已经选择的颜色是钦点由设计师,而不是编程方式产生的最有可能的。

More on this subject can be found here. It's most likely that the colors google has chosen are hand-picked by a designer and not programmatically generated.

编辑:此外,code为MCG了全面修订。对于色彩的新的逻辑可以发现这里,它使用 tinycolor.js 的修改功能。

Also, the code for that MCG has been completely revised. The new logic for the colors can be found here, and it uses tinycolor.js for the modification functions.

这篇关于材料设计调色板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 15:30