 
						今天,我们将创建一个可以通过点击,点击或使用键盘来演奏的SVG动画鼓套件,也可以编程为单独播放!我们将使用GreenSock的 TweenMax动画库,jQuery和<audio>元素。
打开你选择的矢量编辑软件(我使用的是Adobe Illustrator,但有许多选择,如Affinity Designer, Sketch或Inkscape),并得到绘图!我发现有几张照片想要画在我的画板上,以供参考。保持风格平坦,相当简单,无论是在绘画还是动画方面,都会让生活变得更加轻松,而功能较弱的设备会感谢您减少渲染的内容。在这种风格中,鼓套件实际上是一组相当简单的(大部分)矩形对象。在绘制任何想要动画的SVG的同时,还有几件事值得记住:
“g元素是一个用于分组其他SVG元素的容器。应用于g元素的转换将在其所有子元素上执行,并且其任何属性都由其子元素继承。
对于我们来说,这个关键部分是“在所有子元素上执行应用于g元素的转换”,这在将SVG动画化时非常方便, 我们可以简单地将我们想要的动画元素进行分组,并将单个动画应用到该组,从而不用将动画应用到小鼓的每个单独组件。 命名良好的组织将在以后更轻松地操纵SVG!
如果您的绘图应用程序有这样的选项,请启用XML标识名称(在Illustrator首选项>单位>标识对象:> XML ID),这允许您编辑/查看id我们将使用的元素和组的实际属性瞄准他们。
我们需要将两个主要元素集合在一起:
我们希望能够触发我们的动画和声音基于他们各自的鼓被点击/点击,所以我们需要将点击/点击“目标”元素分组在一起。 例如,将整个小鼓,包括支架组合在一起,所以用户触摸的任何部分都会触发动画/声音。

将我们想要动画的元素组合在一起。例如,将小军鼓组合起来; 当小军鼓动画被触发时,我们只想要鼓动画,而不是立场。

“我发现绘制所有东西都很有用,然后在需要时显示部分。”
我们希望能够用键盘演奏鼓,所以某些指示哪些键触发鼓将是有用的。选择你想要“演奏”每个鼓的键,并添加一些指示到您的SVG。将它们组合在一起,以便我们稍后可以隐藏/显示。

将所有组保存为一个.svg文件,然后在文本编辑器中打开它。
我们可以把它直接放到我们的HTML文档中。不过,我建议首先优化Web的SVG。有足够的工具可以做到这一点,SVGOMG可能是最简单的使用之一。
我们提供音频元素ID,以便我们可以在需要播放时对其进行定位。
| 1 2 3 | <audioid="Snare-Audio">  <sourcesrc="mp3/Snare.mp3"type="audio/mp3"></audio> | 
通过添加属性,preload="auto"我们可以告诉浏览器“用户需要这个,确保它被下载”。这就是它在某些浏览器中的工作原理。其他浏览器(特别是移动设备上的浏览器)实际上忽略了这一点,这可能会导致一些奇怪的行为,但我们稍后会回到这一点。
| 1 2 3 | <audioid="Snare-Audio"preload="auto">  <sourcesrc="mp3/Snare.mp3"type="audio/mp3"></audio> | 
在我们打鼓之前,我们还有很多事情要做,但每个鼓部分可以分成三个步骤:
音频、动画、触发这些用户交互。
首先将我们需要的DOM元素作为变量进行存储。例如,对于小鼓,我们想要小鼓音频和小鼓,两个位我们想要动画和部分将触发动画和音频。
播放我们的音频实际上非常简单:我们只是.play()在我们想播放的音频元素上使用该方法。
| 1 2 | varsnareAudio = $('#Snare-Audio');snareAudio.get(0).play(); | 
就是这样!嗯, 几乎..。这很有用, 但是如果我们在音频已经播放时再次调用该方法, 则不会发生任何事情。我们希望在每次触发鼓时从音频文件的开头触发声音。因此, 我们需要设置的音频开始位置是每次触发。
| 1 2 3 4 | varsnareAudio = $('#Snare-Audio');varsnareAudioEl = snareAudio.get(0);snareAudioEl.currentTime = 0;snareAudioEl.play(); | 
对于那些不熟悉的人来说,TweenMax是一个JavaScript库,可以随时间处理任何对象(或对象数组)的一个或多个属性的“补间”。我不打算深入每一个动画的解剖,但每个可以分解成几个简单的步骤:
创建一个新的时间轴Tween属性补 (或大量属性)
我们只是试图模拟一些接近于我们“期望”鼓被击中时移动的东西。有时为了达到预期的效果,夸大运动量是值得的。这在一定程度上是反复试验的,但幸运的是,GreenSock在行动中有很多很好的例子,你可以检查灵感。同样,像Chris Gannon这样的人是看GreenSock能做什么的好方法。
最后,easing是GreenSock提供给你的动画最有用的工具之一。GreenSock有一个很容易的可视化,它可以帮助你决定什么是适合你的动画。
| 1 2 3 4 5 6 7 8 9 10 11 12 | snareDrum = $('#Snare-Drum');// Create a new timeline, that's paused by defaultvarsnaretl = newTimelineMax({  paused: true});// The animation tweenssnaretl.to(snareDrum, 0.1, {scaleX: 1.04, transformOrigin: "50% 50%", ease: Expo.easeOut})       .to(snareDrum, 0.1, {scaleY: 0.9, transformOrigin: "50% 100%", ease: Expo.easeOut}, '0')       // The last tween, returns the element to it's original properties       .to(snareDrum, 0.4, {scale: 1, transformOrigin: "50% 100%", ease: Elastic.easeOut}); | 
我们有我们的音频和我们的动画准备。现在我们只需要把它放在一起并在用户交互中触发它。我们将音频和动画方法封装在一个函数中:
| 1 2 3 4 5 6 7 | functionsnare(){  snaretl.restart();  snaretl.play();  varsnareAudioEl = snareAudio.get(0);  snareAudioEl.currentTime = 0;  snareAudioEl.play();} | 
然后,在点击/触摸事件上调用该函数:
| 1 2 3 4 5 6 7 8 9 10 11 | varclickTouchSnareDone = false;snareDrumAll.on("touchstart click", function() {    if(!clickTouchSnareDone) {        clickTouchSnareDone = true;        setTimeout(function() {            clickTouchSnareDone = false;        }, 100);        snare();        returnfalse;    }}); | 
当用户点击或触摸鼓时,会触发动画和音频。下一步是连接键盘。
| 1 2 3 4 5 6 7 | document.onkeydown = function(e) {  switch(e.keyCode) {    case72:      snare();      break;  }}; | 
使用键盘时,我们甚至可以为键盘指定动画:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | functionanimateKey(key) {  keytl = newTimelineMax({    paused: true  });  keytl.to(key, 0.1, {scale: 1.1, transformOrigin: "50% 50%", ease: Expo.easeOut})  .to(key, 0.4, {scale: 1, transformOrigin: "50% 50%", ease: Elastic.easeOut});  keytl.restart();  keytl.play();}document.onkeydown = function(e) {  // This string will have to match the id of your key guides  thisKeyID = 'Key-'+ e.keyCode;  thisKey = $('#'+ thisKeyID);  switch(e.keyCode) {    case72:    snare();    animateKey(thisKey);    break;  }}; | 
冲洗并重复这个过程中的每个鼓在我们的套件。
现在我们已经有了一个功能齐全的鼓组套件,我们可以用鼠标,键盘或触摸来玩。但是,我们不要停留在这里。
我们有可玩的鼓,但可以使我们的鼓可编程。我们要构建一个可以编程来播放循环的音序器。这可能相当复杂,但同样可以分解成简单的步骤:
创建一个表示鼓和时间 (或节拍) 的 "矩阵"
循环通过列或节拍
如果鼓是活跃的在当前敲打, 演奏鼓
幸运的是,我可以确切地告诉你我们的矩阵是什么!这是一个简单的网格,其中:
行将代表我们的鼓列将代表节拍
我们需要能够选择在我们的音序器的每个节拍中是否播放鼓。<input>具有该type="checkbox"属性的< 元素是完全适合这个,但是,这不是那么容易的风格,但有一个黑客。
我们将为每个鼓创建一个行,并为每个节拍创建一个列。在这个演示中,我们将使用8节拍。我们将添加一个data-target-drum属性(这可以被称为任何东西)与我们之前创建的鼓功能的名称。我们可以使用该属性来帮助我们确定要调用哪个相应的函数。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | <!-- A "row" of our sequencer, we'll need one of these for each drum --><divclass="row"data-target-drum="snare">  <!-- This image indicates which drum the row controls -->  <imgsrc="img/snare.png">  <label><inputtype="checkbox"><div></div></label>  <label><inputtype="checkbox"><div></div></label>  <label><inputtype="checkbox"><div></div></label>  <label><inputtype="checkbox"><div></div></label>  <label><inputtype="checkbox"><div></div></label>  <label><inputtype="checkbox"><div></div></label>  <label><inputtype="checkbox"><div></div></label>  <label><inputtype="checkbox"><div></div></label></div> | 
而且一次循环“行”和“拍”的功能如下所示:
| 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 | rows = $('.row');rowLength = rows.first().children().length;labels = $('label');// Beat starts at 1 because 0 is the img for each rowbeat = 1;// Sequencerfunctionsequencer () {  labels.removeClass('active');  // Do this function for each .row  $(rows).each(function() {    // Select the child element at the "beat" index    current = $(this).children().eq(beat);    current.addClass('active');    // If the current input is checked do some stuff!    if(current.find('input').is(":checked")) {      targetDrum = (current.parent().attr('data-target-drum'));      // If there a function that shares the same name as the data attribute, do it!      fn = window[targetDrum];      if(typeoffn === "function") {        fn();      }    }  });  // If we get to the last child, start over  if( beat < (rowLength - 1) ) {    ++beat;  } else{    beat = 1;  }} | 
时机就是一切
我们有一个功能来演奏当前节拍的鼓声。但我们需要循环这些节拍。我们可以用这个.setInterval()方法来做到这一点。它基本上定义了函数应该执行的频率(以毫秒为单位)。所以我们可以用它来启动音序器并设置其速度。在音乐方面,节拍(或节奏)的频率通常被称为bpm或每分钟节拍。所以bpm可以简单地定义为一分钟内的毫秒数除以bpm。我们将bpm设置为合理的默认值150.然后我们设置点击播放按钮的时间间隔。
| 1 2 3 4 5 6 7 | sequencerOn = false;// Start Sequencer$('#sequencer-active-btn').click(function() {  intervalId = window.setInterval(sequencer, interval);  sequencerOn = true;}); | 
这很好,但是当我们需要停止音序器时呢?我们可以通过将.setInterval()方法返回的ID传递给方法来停止顺序器.clearInterval():
| 1 2 3 4 5 6 7 8 9 10 11 12 | sequencerOn = false;// Start/Stop Sequencer$('#sequencer-active-btn').click(function() {  if(sequencerOn === false) {    intervalId = window.setInterval(sequencer, interval);    sequencerOn = true;  } else{    window.clearInterval(intervalId);    sequencerOn = false;  }}); | 
如果我们可以改变我们的拍子的bpm以获得更快或更慢的循环,那将会更加酷:
| 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 | bpm = 150;interval = 60000 / bpm;// Set tempofunctionsetTempo() {  window.clearInterval(intervalId);  intervalId = window.setInterval(sequencer, interval);}// Increase tempo$('#bpm-increase-btn').click(function() {  if( bpm < 300 ) {    bpm = parseInt($('#bpm-indicator').val());    bpm += 10;    interval = 60000 / bpm;    $('#bpm-indicator').val(bpm);    if(sequencerOn === true) {      setTempo();    }  }});//Decrease tempo$('#bpm-decrease-btn').click(function() {  if( bpm > 100 ) {    bpm = parseInt($('#bpm-indicator').val());    bpm -= 10;    interval = 60000 / bpm;    $('#bpm-indicator').val(bpm);    if(sequencerOn === true) {      setTempo();    }  }}); | 
许多移动浏览器不仅忽略,preload="auto"而且实际上只会在用户触摸事件中加载音频。这基本上意味着我们的音序器不会触发任何音频,直到它已经被用户触发。所以我们需要在第一次用户交互中加载音频。这是一个黑客,但它意味着音序器将在移动设备上工作。
| 1 2 3 4 5 6 7 | // Load audio on iOS devices on the first user interaction$('#sequencer-visible-btn').one('click', function() {  $("audio").each(function(i) {    this.play();    this.pause();  });}); | 
就是这样!我们制作了一个我们可以玩的鼓乐器,我们可以编程自己玩。我希望这个教程能够激发你创建自己的交互式动画SVG。使用相同的技巧,你可以建立其他乐器,或任何东西!如果你这样做,请让我知道,我很想看看你创造了什么!
特别申明:
			本站所有资源都是由网友投稿发布,或转载各大下载站,请自行检测软件的完整性!
			本站所有资源仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您自己承担!
			如有侵权请联系我们删除下架,联系方式:lei1294551502@163.com