Je travaille sur un logo animé qui sera révélé par un analyseur de spectre allant de zéro à onze. Je cherche quelque chose qui fonctionnera sur une large variété de navigateurs afin de le câbler jusqu'à un HTML5-AUDIO ELEMENT n'est probablement pas une option que les seules bibliothèques que j'ai trouvées pouvant effectuer ce travail sur uniquement les dernières versions WebKit et Firefox. Jusqu'à présent, je joue avec juste générer une valeur aléatoire à un intervalle. Voici un exemple de l'endroit où je suis toujours bloqué (à l'aide de la fonction Animate de JQuery ()):
<div id='Logo'> <div id='channelA' class='channel'></div> <div id='channelB' class='channel'></div> <div id='channelC' class='channel'></div> <div id='channelD' class='channel'></div> <div id='channelE' class='channel'></div> <div id='channelF' class='channel'></div> <div id='channelG' class='channel'></div> </div> <script> setInterval(function () { $('.channel').each(function () { $(this).animate({ height: (Math.round(Math.random() * 185)) + 'px' }); }); }, 100); </script> <style> #Logo { width: 245px; height: 245px; background: red; } div.channel { float: left; z-index: 9; background: white; } #channelA { width: 35px; height: 45px; } #channelB { width: 35px; height: 85px; } #channelC { width: 35px; height: 85px; } #channelD { width: 35px; height: 50px; } #channelE { width: 35px; height: 150px; } #channelF { width: 35px; height: 30px; } #channelG { width: 35px; height: 85px; } </style>
4 Réponses :
Je pense que je suis plus proche (mais j'ai beaucoup fait si je pensais que la réponse à ma propre question était la meilleure approche, je suis toujours ouvert à de meilleures réponses, ou à des commentaires (ha) sur des problèmes. avec cette approche). Voici le code (compliqué) que j'ai mis en œuvre jusqu'à présent ( Demo ).
Utilisation d'un La version nettoyée du HTML et CSS Voici le JavaScript: P>
var amp = 0, flutter_range = 10, channels = $('.channel'), turnItUp = setInterval(function () { amp += 0.01; }, 50), flutter = setInterval(function () { var levels = bezier([[0.3], [0.95], [1], [0]]), channel; for(channel = 0; channel < channels.length; channel++) { $(channels[channel]).animate({ height: 245-(Math.round(((Math.random() * (flutter_range*2))-flutter_range)+(levels(channel/channels.length)*amp)*245))+'px' }, 50); } }, 100), //from: https://gist.github.com/atomizer/1049745 bezier = function (pts) { return function (t) { for (var a = pts; a.length > 1; a = b) // do..while loop in disguise for (var i = 0, b = [], j; i < a.length - 1; i++) // cycle over control points for (b[i] = [], j = 0; j < a[i].length; j++) // cycle over dimensions b[i][j] = a[i][j] * (1 - t) + a[i + 1][j] * t; // interpolation return a[0]; } }; setTimeout(function () { window.clearInterval(turnItUp); }, 5000);
Voici la même approche, mais avec des CSS supplémentaires pour le rendre meilleur: Jsfiddle.net/w9qaf / 8 / Embedded / Résultat
Je pense que la meilleure façon de rendre l'animation est réelle consiste à utiliser des données réelles et à calculer les valeurs réelles pour les barres. Faire l'animation sur les données réelles rendra les barres monter et descendre de manière réaliste, il peut être difficile d'imiter ce comportement sans faire le traitement. P>
Quelles sont les barres d'égaliseur vous dire est quelle est l'amplitude des différentes gammes de fréquences. Vous pouvez calculer ces barres à partir d'un fichier audio réel à l'aide d'une fonction appelée FFT (Fast Fourier Transform). P>
Il existe des implémentations de FFT pour presque toutes les langues, même pour JavaScript. L'algorithme fonctionnera comme suit: p>
Le FFT est assez intensif CPU afin que vous souhaitiez calculer les barres pour suffisamment de cadres, puis utilisez les valeurs calculées de votre script. P>
Si vous voulez qu'un exemple vous achète, consultez cette démo: Fast Fourier transforme avec Audiolib.js . P>
Cette démo génère une forme d'onde synthétique, la joue sur votre navigateur (non nécessaire pour vous) et dessine un égaliseur en temps réel dans un objet en toile. L'exemple sur cette page ne fonctionne pas pour moi pour une raison quelconque pour une raison quelconque, j'ai donc téléchargé le GIST code source et l'a installé sur mon ordinateur pour le faire fonctionner. P>
Je vais profiter de creuser à ces liens :)
J'ai fait un peu de jouant avec des volumes, des retards et des courbes. Voici mon jsfiddle y prends . Vient assez proche de cela, je pense :-) Mais définitivement améliorable (il y a un léger problème avec le canal le plus à droite).
[EDIT:] OK, je me suis amélioré un peu plus. Voici une autre jsfiddle P>
Comme vous pouvez le constater, vous n'avez pas nécessairement besoin d'une courbe de Bézier Mise en œuvre pour obtenir le travail de courbe. P>
$('.channel').each(function () { animate($(this)); }); var beat = 200; var volume = 1; setInterval(function() { beat = 60 + Math.random()*100; volume = Math.min(1,Math.max(0.1,volume + Math.random()-0.5)); }, 200); function animate($channel) { var curving = Math.max(1, 30*Math.abs($channel.prevAll().length - 3)); curving = curving + 100*volume; var height = Math.max(1,Math.min(curving, 240) + (Math.random()*50-25)); $channel.animate({ height: Math.round(height) + 'px', }, { duration: beat, complete: function() { animate($channel); } }); }
La clé pour faire un spectre d'aspect réaliste (données virtuelles ou non) est d'avoir un mécanisme de repli pour la barre de bande.
Une bande n'est définie que si la nouvelle valeur est supérieure à celle du courant. Sinon, la valeur actuelle est diminuée par une valeur (linéaire ou logarithmique). La vitesse de la tombe influence également la perception. P>
Comme les données d'un analyseur de spectre ne représentent pas la forme wave em> mais la transformation FFT (Fast-Fourier Transformer), ou Valeur de chaque bande de fréquences, elle peut fonctionner correctement avec des données aléatoires. Vous n'allez pas obtenir l'empreinte "rythmique" comme pour la musique, mais en raison de la relevée, il ressemblera toujours à un certain degré (comme si quelqu'un voulait écouter le bruit qui est :-)). P> Un exemple suit - p> Démo Ici strong>: HTML initial , un simple div: p> inital CSS: p> et l'appel principal pour créer un spectre virtuel de ce : p> Code complet: p> Le code n'est pas optimisé, il est donc un peu affamé sur la CPU. C'est principalement la façon dont HTML est généré pour les bandes. Je préfère le faire sur un élément en toile qui fonctionnerait beaucoup plus efficace, mais comme une multitude de support de navigateur est nécessaire, je l'ai laissé avec ceci: -) p> mise à jour: < / p> Optimisé la hauteur de réglage de la boucle et le haut sur un élément mis en cache. Il a également une méthode Mise à jour de l'exemple (linge en haut) avec une fondue et nouveau code. p> mise à jour 2: p> a ajouté plus de réalisme dans la fréquence inférieure et en simulant un BPM en fonction de l'horloge interne. Je fais maintenant l'heure affecte les trois premières bandes (si le nombre de bandes permettent): p> C'est peut-être subtile, mais juste pour ajouter un peu plus de réalisme. P> Version de style ici avec fonctionnalité de sourdine: p>
http://jsfiddle.net/abdiassoftware/vxxwt/ p> setvolume () code> qui peut être utilisé pour définir le "volume" global à partir d'une boucle, etc. p>
http://jsfiddle.net/abdiassoftware/hvkpn/ p> p> p>
Cette solution regarde assez réaliste - très impressionnant!
Pourquoi ne pas simplement régler le haut et la hauteur de chaque itération au lieu de reconstruire HTML à chaque fois?
@JasonsonPerske parce que je l'ai fait au milieu de la nuit :) Mais oui, ça fait mal mes yeux un peu aussi et je pensais à le modifier à faire exactement cela.
Ceci est mon choix # 1 pour la bonne façon d'y aller. Le fait que ce soit du bruit aléatoire est si intéressant pour moi. Je joue avec quelques timings, et je pourrais essayer de le mélanger avec la fonction d'intervalle "Turnitup ()" de ma réponse pour obtenir l'effet de la variation du volume. Est-ce le tout en rapport avec ce que vous faites avec le logiciel Abdias?
@JasonsonPerske Je peux ajouter une fonction simple SetVolume code> pouvant être contrôlée de manière globale. À propos de: Pas actuellement, mais beaucoup dans le passé (assembleur 68K 68k / amiga / amiga, etc.).
Vous avez totalement gagné la prime. Si c'est le genre de travail que vous aimez vous faire, vous devez mettre à jour vos informations de contact sur votre profil. Le lien du site va à une page de placement équipé. :)
@JasonsPerske merci Jason. Je mettrai à jour mes données de contact (je n'ai pas eu le temps de préparer ma page Web :-)). Le «perfectionniste» en moi a continué un peu avec ce projet. Je penserai que j'ai besoin d'arrêter là-bas ou d'autre que cela finira par devenir un analyseur de spectre à imprimable 3D. Ou quelque chose: D
Je ne sais pas ce qu'est un signal audio est censé "se sentir", mais je suis sûr que ce n'est pas la même chose que le bruit aléatoire. Peut-être devriez-vous définir la valeur de chaque barre, indiquant une valeur aléatoire dans plus ou moins deux de la valeur de la barre précédente?
Peut-être que j'ai besoin de combiner quelques signaux, bruit aléatoire pour "flotter" et une courbe pour l'effet "Tourner".
Je travaille sur la mise en œuvre d'une courbe de Bézier. Voici mes progrès jusqu'à présent: Jsfiddle.net/w9qaf/5
Vous voulez probablement une forme similaire à
y = 1 / (1 + x ^ 2) code>
.@JasonsPerske Avez-vous envisagé d'utiliser des données à partir d'un fichier audio audio-logiciel réel? Cette question est intéressante, mais à des fins pratiques, c'est probablement ce que je ferais.
@Benjamingruenbaum j'aime cette approche