Quelqu'un connait-il un moyen de donner un effet de relief (3D) à une shape ?
Version imprimable
Quelqu'un connait-il un moyen de donner un effet de relief (3D) à une shape ?
Du relief ? avec des formes 2D ? Comme les graphes 3D dans Excel par exemple ?
La solution habituelle consiste a dessiner plusieurs fois la forme decalee par rapport a sa position initiale et de dessiner la forme finale pardessus. Mais c'est un peu basique et demande du temps CPU. En utilisant GeneralPath, Area et/ou le PathIterator de la forme tu peux probablement genererer une forme correspondante aux vues des cotes et avoir ainsi des colos plus fines des cotes ombres, eclaires, etc... bien sur ca sera un peu plus prise de tete a faire sur des formes generalistes.
Oui, l'idée est d'avoir un effet "bouton de commande" avec des formes simples ou des polygones.
Pour tout ce qui est UI, l'effet 3D consiste principalement en un judicieux choix et usage des couleurs. Le mieux consiste a prendre des screens des inferfaces graphiques 2D et de les explorer de pres ou alors de trouver des didacticiels sur le net (ex : comment dessiner un bouton Aqua comme sur MacOS, comment faire une sphere dans Photoshop, etc...) pour comprendre les techniques et les differents calques a supperposer. Ensuite ca peux etre fait via des images externes au programmes dans le logiciel de dessin, en SVG ou en Java2D si tu arrive a trouver les bons filtres (ex : le GaussianBlur dispo dans les exemples du livre de Gfx de meme que ses composites similaires a celles utilises dans les logiciels de dessin -lighten, darken, dodge, multiply, etc...).
Outre le lien donne par Sinok, je te propose de jeter un coup d'oeil dans ce code que j'ai poste et qui est inspire des techniques de rendu indiquees par Gfx dans son livre : http://www.developpez.net/forums/sho...ighlight=loupe
J'avais cree des prototypes dans PaintShopPro en separant bien chaque calque et en nottant les composite, filtres et valeurs utilisees avant de faire un code Java2D qui rendait sensiblement la meme chose.
J' avais effectivement découvert l'article de Campbell. Vaste sujet d'étude pour un débutant!
merci à tous. ;)
Je tente de récupérer l'example de Campbell, dans une classe Java standard. Cependant, sorti de l "'Interactive Graphic Editor", je ne sais que mettre dans la méthode paint()
Don't mess with the paint method est une règle d'or en java.
Pour te donner un exemple de l'utilisation de la méthode donnée par Chris Campbell:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246 import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.RadialGradientPaint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Transparency; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class ClipComponent extends JComponent implements GraduationListener{ private GraduationModel model; private int border = 10; private Shape clipShape; private Shape lightShape; private static final Color clrGlowInnerHi = new Color(200, 200, 200, 148); private static final Color clrGlowInnerLo = new Color(100, 50, 100); private static final Color clrGlowOuterHi = new Color(200, 200, 200, 124); private static final Color clrGlowOuterLo = new Color(100, 50, 100); private static final Color clrHi = new Color(0, 0, 0); private static final Color clrLo = new Color(50, 0, 50); private Shape createClipShape() { return new RoundRectangle2D.Double(border, border, getWidth() - border * 2, getHeight() - border * 2, 30, 30); } private Shape createlightShape() { return new Ellipse2D.Double( border+getWidth()/10 , border+getHeight()/10 , getWidth() - (border+getWidth()/10)*2 , getHeight() - (border+getHeight()/10)*2 ); } @Override protected void paintComponent(Graphics g) { // TODO Auto-generated method stub super.paintComponent(g); if (isShowing()) { Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //g2d.setPaint(Color.black); //g2d.fill(createClipShape()); clipShape = createClipShape(); lightShape = createlightShape(); // Shape clipShape = new Ellipse2D.Float(width/4, height/4, width/2, height/2); // Clear the background to white // Set the clip shape BufferedImage clipImage = createClipImage(clipShape); Graphics2D g2 = clipImage.createGraphics(); // Fill the shape with a gradient g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setComposite(AlphaComposite.SrcAtop); g2.setPaint(new GradientPaint(0, 0, clrHi, 0, getHeight(), clrLo)); g2.fill(clipShape); // Apply the border glow effect paintBorderGlow(clipShape, g2, 8); paintBorderShadow(clipShape, g2, 3); g2.dispose(); BufferedImage lightImage = createClipImage(lightShape); Graphics2D g2b = lightImage.createGraphics(); g2b.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2b.setPaint(Color.black); g2b.fill(lightShape); // Fill the shape with a gradient g2b.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,model.getFloatValue())); float[] dist = {0.1f,0.4f, 1f}; Color[] colors = {Color.white,Color.yellow, Color.red}; g2b.setPaint(new RadialGradientPaint(new Point2D.Double(getWidth()/2,getHeight()/2),100,dist,colors)); g2b.fill(lightShape); // Apply the border glow effect paintBorderGlow(lightShape, g2b, 8); paintBorderShadow(lightShape, g2, 3); g2b.dispose(); g2d.drawImage(clipImage, 0, 0, null); g2d.drawImage(lightImage, 0, 0, null); } } private BufferedImage createClipImage(Shape s) { // Create a translucent intermediate image in which we can perform // the soft clipping GraphicsConfiguration gc = GraphicsEnvironment .getLocalGraphicsEnvironment().getDefaultScreenDevice() .getDefaultConfiguration(); BufferedImage img = gc.createCompatibleImage(getWidth(), getHeight(),Transparency.TRANSLUCENT); Graphics2D g2 = img.createGraphics(); // Clear the image so all pixels have zero alpha g2.setComposite(AlphaComposite.Clear); g2.fillRect(0, 0, getWidth(), getHeight()); // Render our clip shape into the image. Note that we enable // antialiasing to achieve the soft clipping effect. Try // commenting out the line that enables antialiasing, and // you will see that you end up with the usual hard clipping. g2.setComposite(AlphaComposite.Src); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setColor(Color.WHITE); g2.fill(s); g2.dispose(); return img; } private static Color getMixedColor(Color c1, float pct1, Color c2, float pct2) { float[] clr1 = c1.getComponents(null); float[] clr2 = c2.getComponents(null); for (int i = 0; i < clr1.length; i++) { clr1[i] = (clr1[i] * pct1) + (clr2[i] * pct2); } return new Color(clr1[0], clr1[1], clr1[2], clr1[3]); } private void paintBorderGlow(Shape shape,Graphics2D g2, int glowWidth) { int gw = glowWidth * 2; for (int i = gw; i >= 2; i -= 2) { System.out.println(i); float pct = (float) (gw - i) / (gw - 1); Color mixHi = getMixedColor(clrGlowInnerHi, pct, clrGlowOuterHi, 1.0f - pct); Color mixLo = getMixedColor(clrGlowInnerLo, pct, clrGlowOuterLo, 1.0f - pct); g2.setPaint(new GradientPaint(0.0f, getHeight() * 0.25f, mixHi, 0.0f, getHeight(), mixLo)); //g2.setColor(Color.WHITE); // See my "Java 2D Trickery: Soft Clipping" entry for more // on why we use SRC_ATOP here g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, pct)); g2.setStroke(new BasicStroke(i)); g2.draw(shape); } } public ClipComponent(GraduationModel model) { super(); this.model = model; this.model.addGraduateListener(this); // TODO Auto-generated constructor stub } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub final GraduationModel m = new GraduationModel(50); ClipComponent c = new ClipComponent(m); final JSlider s = new JSlider(0,100); s.setOrientation(JSlider.VERTICAL); s.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { // TODO Auto-generated method stub m.setValue(s.getValue()); } }); JFrame f = new JFrame(); f.add(c); f.add(s, BorderLayout.EAST); f.setSize(200, 200); f.setLocationRelativeTo(null); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } public void valueChanged(GraduationEvent e) { // TODO Auto-generated method stub this.repaint(); } private void paintBorderShadow(Shape shape,Graphics2D g2, int shadowWidth) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int sw = shadowWidth*2; for (int i=sw; i >= 2; i-=2) { float pct = (float)(sw - i) / (sw - 1); g2.setColor(getMixedColor(Color.lightGray, pct, Color.lightGray, 1.0f-pct)); g2.setStroke(new BasicStroke(i)); g2.draw(shape); } } }
Avec les classes qui vont avec
http://pourraves.free.fr/trucs/Diver...tionEvent.java
http://pourraves.free.fr/trucs/Diver...nListener.java
http://pourraves.free.fr/trucs/Diver...tionModel.java
Ensuite il faudrait que je me replonge dedans, mais après 4 pintes et un shot de vodka c'est un peu tendu :mouarf:
Ahhh, c'est beau d'avoir encore 27 ans. Moi, après tout ça, c'est pas tendu, c'est carrément foutu :aie:
Merci pour le code ;)