Java:平滑颜色过渡 [英] Java: Smooth Color Transition

查看:384
本文介绍了Java:平滑颜色过渡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想尝试做一个健康吧,并且可能是原来的,它会开始绿色,失去健康后,你会发现它会变黄,

I am trying to make a health bar, and as what might be original, it will start out green, and after losing health you find that it will turn yellow, then orange, then red.. or something relative to that.

我尝试使用此链接中提供的方法:https://stackoverflow.com/questions/19841477/java-smooth-color-transition

I tried using the method provided in this link: https://stackoverflow.com/questions/19841477/java-smooth-color-transition

从这个链接的结果是这个代码,只是一个测试从值100到0,但它结束在 IllegalArgumentException 通常 code>和 Green ,我的猜测是因为它超过了255的值。

The result from that link was this code, just a test from value 100 to 0, but it ended in an IllegalArgumentException at normally Red and Green, and my guess for reason is it being over the value of 255.

Color to = Color.red;
Color base = Color.green;
int red = (int)Math.abs((100 * to.getRed()) + ((1 - 100) * base.getRed()));
int green = (int)Math.abs((100 * to.getGreen()) + ((1 - 100) * base.getGreen()));
int blue = (int)Math.abs((100 * to.getBlue()) + ((1 - 100) * base.getBlue()));
setForeground(new Color(red, green, blue));

它没有真正工作,我绝对不知道如何得到它<

It didn't really work, and I have absolutely no idea how I can get it to transition the way I wish it to.

因此,在我的 HealthBar class,我有一个 update()方法

So within my HealthBar class, I have an update() method

public void update() {
    if (getValue() < 10) setForeground(Color.red);
    else if (getValue() < 25) setForeground(Color.orange);
    else if (getValue() < 60) setForeground(Color.yellow);
    else setForeground(Color.green);
}

此代码在某些点进行基本转换。

This code does a basic transition at certain points.

我需要创建字段以在中使用某些颜色 code>健康吧,所以现在我有这个..

I need to create fields to use certain colors at certain values of the health bar, so now I have this..

if (getValue() < 10) {
    Color to = Color.black;
    // Color current = getForeground() ?
    Color from = Color.red;
    // ?
}

我将使用最后一个例子。

I am just going to use an example for the last bit.

所以我知道我会有一个颜色我要去,和一个 color 这是一个基础。我不太确定如果我需要一个颜色当前。现在我看到的问题是转换的步骤,因为每个转换都有不同的步骤数量。

So I know that I am going to have a color that I am going to, and a color that is a base. I am not so sure if I need a color for current. The problem that I see now is for the steps of the transition because each transition has a different amount of steps.

摘要和问题
>
我不知道如何实现我正在尝试,我知道肯定是我需要一个基础 color ,我提供了一个链接到我看到的答案,但我不能真正地想出来。有了信息,我如何得到转换颜色

Summary and Question
I don't know how to achieve what I am attempting, all I know for sure is I need a to and base color, and I provided a link to an answer that I saw, but I couldn't really figure it out. With the information given, how could I get it to transition colors ?

推荐答案

我花了很多时间试图找到/创建一个适用于我的混合算法,这基本上是我能够在一起摇摆。

I spent a lot of time trying to find/create a blending algorithm that worked for me, this is basically what I was able to hobble together.

我使用此方法生成混合多种颜色的渐变过渡,如此处

I've used this approach to generate a gradient transition mixing multiple colors, as demonstrated here

基本上,此方法允许您设置一系列颜色和百分比标记,以便更好地控制颜色在哪些点之间转换。

Basically, this approach allows you to set up a series of colors and percentage marks so that you gain much greater control over which points the colors transition between.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.text.NumberFormat;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ColorFading {

    public static void main(String[] args) {
        new ColorFading();
    }

    public ColorFading() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new FadePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class FadePane extends JPanel {

        private final float[] fractions = new float[]{0f, 0.5f, 1f};
        private final Color[] colors = new Color[]{Color.RED, Color.YELLOW, Color.GREEN};
        private float progress = 1f;
        private JSlider slider;

        public FadePane() {
            slider = new JSlider(0, 100);
            setLayout(new BorderLayout());
            add(slider, BorderLayout.SOUTH);

            slider.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    progress = ((float)slider.getValue() / 100f);
                    repaint();
                }
            });
            slider.setValue(100);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int width = getWidth();
            int height = getHeight();
            Color startColor = blendColors(fractions, colors, progress);
            g2d.setColor(startColor);
            g2d.fillRect(0, 0, width, height);
            g2d.dispose();
        }
    }

    public static Color blendColors(float[] fractions, Color[] colors, float progress) {
        Color color = null;
        if (fractions != null) {
            if (colors != null) {
                if (fractions.length == colors.length) {
                    int[] indicies = getFractionIndicies(fractions, progress);

                    float[] range = new float[]{fractions[indicies[0]], fractions[indicies[1]]};
                    Color[] colorRange = new Color[]{colors[indicies[0]], colors[indicies[1]]};

                    float max = range[1] - range[0];
                    float value = progress - range[0];
                    float weight = value / max;

                    color = blend(colorRange[0], colorRange[1], 1f - weight);
                } else {
                    throw new IllegalArgumentException("Fractions and colours must have equal number of elements");
                }
            } else {
                throw new IllegalArgumentException("Colours can't be null");
            }
        } else {
            throw new IllegalArgumentException("Fractions can't be null");
        }
        return color;
    }

    public static int[] getFractionIndicies(float[] fractions, float progress) {
        int[] range = new int[2];

        int startPoint = 0;
        while (startPoint < fractions.length && fractions[startPoint] <= progress) {
            startPoint++;
        }

        if (startPoint >= fractions.length) {
            startPoint = fractions.length - 1;
        }

        range[0] = startPoint - 1;
        range[1] = startPoint;

        return range;
    }

    public static Color blend(Color color1, Color color2, double ratio) {
        float r = (float) ratio;
        float ir = (float) 1.0 - r;

        float rgb1[] = new float[3];
        float rgb2[] = new float[3];

        color1.getColorComponents(rgb1);
        color2.getColorComponents(rgb2);

        float red = rgb1[0] * r + rgb2[0] * ir;
        float green = rgb1[1] * r + rgb2[1] * ir;
        float blue = rgb1[2] * r + rgb2[2] * ir;

        if (red < 0) {
            red = 0;
        } else if (red > 255) {
            red = 255;
        }
        if (green < 0) {
            green = 0;
        } else if (green > 255) {
            green = 255;
        }
        if (blue < 0) {
            blue = 0;
        } else if (blue > 255) {
            blue = 255;
        }

        Color color = null;
        try {
            color = new Color(red, green, blue);
        } catch (IllegalArgumentException exp) {
            NumberFormat nf = NumberFormat.getNumberInstance();
            System.out.println(nf.format(red) + "; " + nf.format(green) + "; " + nf.format(blue));
            exp.printStackTrace();
        }
        return color;
    }
}

这篇关于Java:平滑颜色过渡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆