実現したいこと
Java swingでクリックすると円を揺らすアニメーションを実装したいのですが(トグルクラスのように)再度クリックするとアニメーションは止まる)理想の動きになりません。どなたか助けてください。
理想の動きをするコード
html
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Document</title> 7 <style> 8 9.container { 10 display: flex; 11 align-items:center; 12 justify-content: center; 13 height: 200px; 14} 15 16 17.fluid { 18 margin: auto; 19 position: relative; 20 width: 150px; /* ボタンの幅を設定 */ 21 height: 150px; /* ボタンの高さを設定 */ 22 border-radius: 50%; /* 円形のボタン */ 23 background-color: rgba(204,204,204,0.9); 24 border: none; 25 cursor: pointer; 26 /* overflow: hidden; */ 27 animation: none; 28} 29 30.fluid::after { 31 display: block; 32 width: 20px; 33 height: 35px; 34 border-radius: 50%; 35 background: rgba(255, 255, 255, 0.95); 36 box-shadow: 0 0 20px 10px white; 37 content: ""; 38 position: absolute; 39 top: 20%; 40 left: 20%; 41 transform: rotate(30deg); 42} 43 44.fluid.active { 45 background-color: #bce2e8; 46 animation: fluid-animation 0.2s ease 0s infinite; 47} 48 49/* 50.fluid-shape.paused { 51 animation-play-state: paused; 52} 53*/ 54 55@keyframes fluid-animation { 56 0%, 50%, 100% { 57 border-radius: 50% 50% 50% 50% / 50% 50% 50% 50%; 58 } 59 25% { 60 border-radius: 40% 60% 40% 60% / 40% 60% 40% 60%; 61 } 62 75%{ 63 border-radius: 60% 40% 60% 40% / 60% 40% 60% 40%; 64 } 65} 66 </style> 67</head> 68<body> 69 <div class="container"> 70 <div class="fluid" id="fluid"></div> 71 </div> 72 <script> 73 console.clear(); 74 75 76const fluid = document.querySelector(".fluid"); 77 78 79// ボタンクリックでアニメーション再生・停止の切り替え 80fluid.addEventListener( 81 "click", 82 () => { 83 84 85 if (fluid.classList.contains("active")) { 86 // 再生中の場合 87 88 fluid.classList.remove("active"); 89 } else { 90 91 fluid.classList.add("active"); 92 93 } 94 }, 95 false 96); 97 98 99 </script> 100</body> 101</html>
該当のソースコード
java
1package music2; 2 3import java.awt.Color; 4import java.awt.Graphics; 5import java.awt.Graphics2D; 6import java.awt.event.ActionEvent; 7import java.awt.event.ActionListener; 8import java.awt.event.MouseAdapter; 9import java.awt.event.MouseEvent; 10import java.awt.geom.Ellipse2D; 11import java.io.IOException; 12import java.net.URL; 13 14import javax.sound.sampled.AudioInputStream; 15import javax.sound.sampled.AudioSystem; 16import javax.sound.sampled.Clip; 17import javax.sound.sampled.FloatControl; 18import javax.sound.sampled.LineEvent; 19import javax.sound.sampled.LineListener; 20import javax.sound.sampled.LineUnavailableException; 21import javax.sound.sampled.UnsupportedAudioFileException; 22import javax.swing.JFrame; 23import javax.swing.JLabel; 24import javax.swing.JPanel; 25import javax.swing.JSlider; 26import javax.swing.Timer; 27import javax.swing.event.ChangeEvent; 28import javax.swing.event.ChangeListener; 29 30public class TestFrame extends JFrame implements ChangeListener, LineListener { 31 public static void main(String[] args) { 32 new TestFrame().setVisible(true); 33 } 34 35 private JSlider slider; 36 private JLabel label; 37 private CirclePanel circlePanel; 38 private Clip clip; 39 private FloatControl gainControl; 40 41 TestFrame() { 42 super("アプリ"); 43 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 44 setSize(800, 800); 45 46 circlePanel = new CirclePanel(); 47 setContentPane(circlePanel); 48 49 label = new JLabel("test"); 50 label.setBounds(300, 10, 100, 100); 51 add(label); 52 53 JLabel label2 = new JLabel("テスト"); 54 label2.setBounds(300, 500, 100, 100); 55 add(label2); 56 57 slider = new JSlider(50, 150, 100); 58 slider.addChangeListener(this); 59 JPanel p = new JPanel(); 60 p.add(slider); 61 p.setBounds(300, 300, 200, 50); 62 add(p); 63 64 try { 65 loadAudioFile("ogawa.wav"); 66 } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) { 67 e.printStackTrace(); 68 } 69 } 70 71 private void loadAudioFile(String filePath) throws UnsupportedAudioFileException, IOException, LineUnavailableException { 72 URL url = getClass().getResource(filePath); 73 if (url != null) { 74 AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url); 75 clip = AudioSystem.getClip(); 76 clip.open(audioInputStream); 77 gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN); 78 clip.addLineListener(this); 79 System.err.println("音声ファイルが見つかった: " + filePath); 80 } else { 81 System.err.println("音声ファイルが見つかりません: " + filePath); 82 } 83 } 84 85 public void stateChanged(ChangeEvent e) { 86 label.setText("値:" + slider.getValue()); 87 circlePanel.setDiameter(slider.getValue()); 88 float value = (float) slider.getValue() / 100f; // 0.5 ~ 1.5の範囲に正規化 89 gainControl.setValue(20f * (float) Math.log10(value)); // 音量の調整 90 } 91 92 @Override 93 public void update(LineEvent event) { 94 LineEvent.Type type = event.getType(); 95 if (type == LineEvent.Type.STOP) { 96 circlePanel.setStart(false); 97 } 98 } 99 100 private class CirclePanel extends JPanel { 101 private final int X = 350, Y = 250; 102 private int diameterOfCircle = 100; 103 private Ellipse2D ellipse; 104 private boolean start = false; 105 private Color ellipseColor = Color.GRAY; // 円の色を保持する変数 106 private Timer shakeTimer; 107 private int shakeOffset = 0; 108 109 private class EllipseClickListener extends MouseAdapter { 110 @Override 111 public void mouseClicked(MouseEvent e) { 112 if (ellipse.contains(e.getPoint())) { 113 System.out.println(e.getPoint() + "=図形内"); 114 if (!start) { 115 start = true; 116 clip.start(); 117 setEllipseColor(Color.CYAN); // 円の色を水色に変更 118 startShaking(); 119 System.out.println(start); 120 } else { 121 start = false; 122 clip.stop(); 123 setEllipseColor(Color.LIGHT_GRAY); 124 stopShaking(); 125 System.out.println(start); 126 } 127 } else { 128 System.out.println(e.getPoint() + "=図形外"); 129 } 130 } 131 } 132 133 void setEllipseColor(Color color) { 134 this.ellipseColor = color; 135 repaint(); 136 } 137 138 CirclePanel() { 139 super(null); 140 setBackground(Color.WHITE); 141 addMouseListener(new EllipseClickListener()); 142 initShakeTimer(); 143 setEllipseColor(Color.LIGHT_GRAY); 144 } 145 146 void setDiameter(int diameter) { 147 this.diameterOfCircle = diameter; 148 repaint(); 149 } 150 151 void setStart(boolean start) { 152 this.start = start; 153 } 154 155 private void initShakeTimer() { 156 shakeTimer = new Timer(50, new ActionListener() { 157 @Override 158 public void actionPerformed(ActionEvent e) { 159 shakeOffset = (shakeOffset == 0) ? 5 : 0; 160 repaint(); 161 } 162 }); 163 } 164 165 private void startShaking() { 166 shakeTimer.start(); 167 } 168 169 private void stopShaking() { 170 shakeTimer.stop(); 171 shakeOffset = 0; 172 repaint(); 173 } 174 175 @Override 176 protected void paintComponent(Graphics g) { 177 super.paintComponent(g); 178 Graphics2D g2 = (Graphics2D) g; 179 g2.setColor(ellipseColor); // 円の色を設定 180 ellipse = new Ellipse2D.Double(X - diameterOfCircle / 2 + shakeOffset, Y - diameterOfCircle / 2, diameterOfCircle, diameterOfCircle); 181 g2.fill(ellipse); 182 183 // ぼうっと光った楕円形の水玉模様を描画 184 int spotWidth = diameterOfCircle / 3; // 横幅は外側の円の1/3 185 int spotHeight = spotWidth / 2; // 縦幅は横幅の半分 186 int spotX = X - diameterOfCircle / 4 + shakeOffset; // 円の中心から1/4の距離に配置 187 int spotY = Y - diameterOfCircle / 4; 188 Ellipse2D spot = new Ellipse2D.Double(spotX, spotY, spotWidth, spotHeight); 189 190 // 水玉模様にぼけ効果を追加 191 g2.setColor(new Color(255, 255, 255, 128)); // 半透明の白色 192 g2.fill(spot); 193 g2.setColor(new Color(255, 255, 255, 255)); // 完全な白色 194 g2.fillOval(spotX + spotWidth / 4, spotY, spotWidth / 2, spotHeight); 195 } 196 } 197}
試したこと
試行錯誤しましたが、できません。java swing 水玉 アニメーションなどでGoogle検索しても出てきません。
開発環境
Eclipse使用しています。
回答2件
あなたの回答
tips
プレビュー