可视化大屏原型制作 h5
There are two approaches to making almost anything. The first is to dive in head-first, building from the top down, squirrelling into problems as they are found and hoping you’ll get everything right. The second is to create a series of simple test cases: building upwards, proving each step before using the work to generate a final, complete piece.
制作几乎所有东西的方法有两种。 首先是从头到脚地潜入,从上到下构建,在发现问题时一头雾水,希望您一切都好。 第二个步骤是创建一系列简单的测试用例: 向上构建,在使用工作生成最终的完整作品之前证明每个步骤。
There are advantages to both methods, but the second tends to yield better results. I’ll demonstrate that approach here, in building the initial prototype of the web audio player I introduced in part 1 of this series.
两种方法都有其优点,但是第二种方法往往会产生更好的结果。 在构建本系列第1部分中介绍的Web音频播放器的初始原型时,我将在此处演示该方法。
One of the advantages of hosting your own content is the ability to customize everything about it: rather than having to make do with the UI for audio files from SoundCloud, or built-in browser controls, we can make our own using customized HTML5 elements by knowing just a little JavaScript. The result won’t quite be the version shown above, which will be achieved in the articles ahead, but this code will get you significant part of the way there.
托管自己的内容的优点之一是可以自定义内容的一切:无需处理来自SoundCloud或内置浏览器控件的音频文件的UI,我们可以使用自定义HTML5元素来制作自己的内容,方法是:懂一点JavaScript 。 结果将与上面显示的版本完全不同,但是将在后面的文章中实现,但是此代码将为您提供重要的帮助。
(Initial Elements)
First, let’s ensure we can get an audio file to play on a page. Here, I’m using Track 24 from NIN’s Ghosts III, licensed under Creative Commons:
Ghosts III中的
<figure id="audioplayer">
<audio controls src="24-ghosts-III.mp3" id="audiotrack"></audio>
</figure>
Since the latest versions of Firefox now supports .mp3, along with every other modern browser, I’m using just that codec. I’ve placed a <figure>
element around the <audio>
as we’ll be adding controls within it, together with captions.
.mp3以及所有其他现代浏览器,因此我仅使用该编解码器。 我在<audio>
周围放置了一个<figure>
元素,因为我们将在其中添加控件以及字幕。
Once you’re satisfied that the audio works, the next task is to create a custom UI for the player.
当您满意音频的工作原理后,下一个任务就是为播放器创建一个自定义UI。
(Working With Progressive Enhancement )
If the user doesn’t have JavaScript running, or if the script we’re about to add fails to work, we still want them to have access to basic audio controls. Therefore, we remove the default UI only in the context of our script:
如果用户没有运行JavaScript,或者如果我们要添加的脚本无法正常工作,我们仍然希望他们能够访问基本的音频控件。 因此,我们仅在脚本上下文中删除默认UI:
var audioPlayer = document.getElementById("audioplayer"),
audioTrack = document.getElementById("audiotrack"),
playButton = document.createElement("button");
playButton.type = "button";
audioPlayer.appendChild(playButton);
audioTrack.removeAttribute("controls");
Added to the bottom of our HTML page, this script effectively reduces our audio player to a simple <button>
element. Right now, the play button doesn’t actually have any text in it. We’re going to be doing a lot of swapping text inside button elements, so it makes sense to separate that script into a function:
添加到我们HTML页面底部,此脚本有效地将音频播放器简化为一个简单的<button>
元素。 现在,“播放”按钮实际上没有任何文字。 我们将在按钮元素内进行大量交换文本,因此将脚本分成一个函数是有意义的:
function setText(el,text) {
el.innerHTML = text;
}
Now we can set the text of any HTML element easily:
现在,我们可以轻松设置任何HTML元素的文本:
setText(playButton,"Play");
Next, we have to make the button actually do something:
接下来,我们必须使按钮实际执行某些操作:
playButton.addEventListener("click", player);
function player() {
if (audioTrack.paused) {
setText(playButton,"Pause");
audioTrack.play();
} else {
setText(playButton,"Play");
audioTrack.pause();
}
}
Note that we’re not trying to make separate functions for “play” and “stop”, but thinking in terms of the activity of the button.
请注意,我们并不是要为“播放”和“停止”创建单独的功能,而是要考虑按钮的活动 。
(Making A Mute Button)
We also need to create controls for the volume of the audio. The simplest is a “Mute” button, which uses a very similar pattern to the Play/Pause button:
我们还需要为音频音量创建控件。 最简单的是“静音”按钮,其使用与“播放/暂停”按钮非常相似的模式:
var muteButton = document.createElement("button");
setText(muteButton,"Mute");
muteButton.type = "button";
audioPlayer.appendChild(muteButton);
muteButton.addEventListener("click", muter);
function muter() {
if (audioTrack.volume == 0) {
setText(this,"Mute");
audioTrack.volume = 1;
} else {
setText(this,"Unmute");
audioTrack.volume = 0;
}
}
This function is a little crude: when unmuted, it sets the volume level for the audio to its absolute maximum (within the limits of the system), but that’s acceptable for right now.
此功能有点粗糙:取消静音时,它将音频的音量级别设置为绝对最大值(在系统限制范围内),但现在是可以接受的。
(Making A Volume Control)
Next, we need a more fine-grained volume slider. The obvious candidate for this UI control is a range
element:
接下来,我们需要更细粒度的音量滑块。 此UI控件的明显候选者是range
元素:
volumeSlider = document.createElement("input");
volumeSlider.type = "range";
The range
element will need a lot of attributes set in JavaScript, which we could do in the same way I’ve just set the type for the new input… but just because we’re making a prototype, doesn’t mean that we should be doing things the long way. Ideally, at least some of our code will be ported into the final version of the media player, meaning we should be looking for efficient ways to write our code right now.
range
元素将需要在JavaScript中设置很多属性,我们可以按照为新输入设置类型的相同方式来完成此操作……但是,仅仅因为我们正在制作原型,并不意味着我们应该做事很长。 理想情况下,至少我们的某些代码将被移植到媒体播放器的最终版本中,这意味着我们现在应该寻找有效的方式来编写我们的代码。
Unfortunately, there’s no plural setAttributes
method we can use define the values of multiple attributes simultaneously. However, we can make a fairly simple function to do so:
不幸的是,没有复数的setAttributes
方法可用于同时定义多个属性的值。 但是,我们可以创建一个相当简单的函数来做到这一点:
function setAttributes(el, attrs) {
for(var key in attrs){
el.setAttribute(key, attrs[key]);
}
}
Now we can set the attributes for the range slider in a single line of code:
现在,我们可以在一行代码中设置范围滑块的属性:
setAttributes(volumeSlider, { "type": "range", "min": "0", "max": "1", "step": "any", "value": "1" });
Note that the minimum and maximum values of the slider correspond to those in the muter()
function.
请注意,滑块的最小值和最大值与muter()
函数中的最小值和最大值相对应。
Next, we add a listener to the range input, setting the volume of the audio track to the value of the slider in an anonymous function:
接下来,我们在范围输入中添加一个侦听器,在匿名函数中将音轨的音量设置为滑块的值:
volumeSlider.addEventListener("input", function(){
audioTrack.volume = volumeSlider.value;
});
Here we encounter our first real problem: functionally, lowering the volume slider to 0 is the same as clicking on Mute, so that change of state should be shown in the button. How do we make that happen?
在这里,我们遇到了第一个实际问题:从功能上讲,将音量滑块降低到0与单击“静音”相同,因此状态更改应显示在按钮中。 我们如何做到这一点?
(Syncing Controls)
My solution is to divorce the question from the buttons, and look at any changes in the volume of the <audio>
element itself:
我的解决方案是将问题与按钮分开,并查看<audio>
元素本身的音量的任何变化:
audioTrack.addEventListener('volumechange', volumizer);
function volumizer() {
if (audioTrack.volume == 0) {
setText(muteButton,"Unmute");
} else {
setText(muteButton,"Mute");
}
}
There’s just one further fix to make. When the music track finishes, the music should return to the start, and the play button should display “Play”, rather than “Pause” or “Stop”:
只有一个进一步的解决方法。 音乐曲目结束后,音乐应返回到开头,并且播放按钮应显示“播放”,而不是“暂停”或“停止”:
audioTrack.addEventListener('ended', finish);
function finish() {
audioTrack.currentTime = 0;
setText(playButton,"Play");
}
That’s it! The entire code, with a slight improvement to the muter()
function, is at the bottom of this page; I’ve also linked to the more polished version on Codepen shown the top of this article. I’ll be demonstrating how to achieve the enhancements shown in that version in the next two articles in this series.
而已! 整个代码muter()
对muter()
函数略有改进muter()
位于本页底部; 我还链接到本文顶部显示的Codepen上更精细的版本 。 在本系列的下两篇文章中,我将演示如何实现该版本中显示的增强功能。
function player() {
if (audioTrack.paused) {
setText(this, "Stop");
audioTrack.play();
} else {
setText(this,"Play");
audioTrack.pause();
}
}
function setText(el,text) {
el.innerHTML = text;
}
function finish() {
audioTrack.currentTime = 0;
setText(playButton,"Play");
}
function volumizer() {
if (audioTrack.volume == 0) {
setText(muteButton,"Unmute");
} else {
setText(muteButton,"Mute");
}
}
function muter() {
if (audioTrack.volume == 0) {
audioTrack.volume = restoreValue;
volumeSlider.value = restoreValue;
} else {
audioTrack.volume = 0;
restoreValue = volumeSlider.value;
volumeSlider.value = 0;
}
}
function setAttributes(el, attrs) {
for(var key in attrs){
el.setAttribute(key, attrs[key]);
}
}
var audioPlayer = document.getElementById("audioplayer"),
audioTrack = document.getElementById("audiotrack"),
playButton = document.createElement("button"),
muteButton = document.createElement("button"),
volumeSlider = document.createElement("input");
setText(playButton, "Play");
setText(muteButton, "Mute");
setAttributes(playButton, { "type": "button" });
setAttributes(muteButton, { "type": "button" });
setAttributes(volumeSlider, { "type": "range", "min": "0", "max": "1", "step": "any", "value": "1" });
audioPlayer.appendChild(volumeSlider);
audioPlayer.appendChild(muteButton);
audioPlayer.appendChild(playButton);
audioTrack.removeAttribute("controls");
playButton.addEventListener("click", player, false);
muteButton.addEventListener("click", muter, false);
volumeSlider.addEventListener("input", function(){
audioTrack.volume = volumeSlider.value;
}, false);
audioTrack.addEventListener('volumechange', volumizer, false);
audioTrack.addEventListener('ended', finish, false);
(Note)
This code assumes “perfect world” conditions once the JavaScript loads: that the browser supports HTML5 and the various aspects of the API we’ve used here, and that the audio track loads immediately. That won’t be true in every case: for example, Android 2 and earlier doesn’t support event.ended
for audio. There are ways around that, and many fallbacks you could add, but I won’t be concentrating on them today.
这段代码在JavaScript加载后就假定了“完美的世界”条件:浏览器支持HTML5和我们在此使用的API的各个方面,并且音轨会立即加载。 并非在所有情况下都是如此:例如,Android 2和更早的版本不支持event.ended
的音频。 有很多方法可以解决,还可以添加许多后备功能,但今天我将不再关注它们。
翻译自: https://thenewcode.com/889/Making-An-Audio-Player-With-HTML5-Part-2-Prototyping
可视化大屏原型制作 h5