Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .markdownlint.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"MD002": false,
"MD033": false
"MD033": false,
"line-length": {
"line_length": 120,
"code_blocks": false
}
}
5 changes: 0 additions & 5 deletions _includes/filter.html

This file was deleted.

6 changes: 5 additions & 1 deletion _includes/header.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<header class="header header_background header_glass txt-xs-center">
{% include filter.html %}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<filter id="glass-filter">
<feGaussianBlur stdDeviation="5"></feGaussianBlur>
</filter>
</svg>
<div class="avatar avatar_center">
<img class="avatar__img" src="/images/avatar.jpg" alt="deeppines">
</div>
Expand Down
221 changes: 156 additions & 65 deletions _posts/2016-10-03-youtube-video-in-modal-window.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,67 +9,141 @@ categories: js

## Разметка модального окна

В качестве модального окна для примера возьмем стандартное модальное окно
Bootstrap 3, но слегка изменим его убрав некоторые лишние части.
Для разметки будем использовать шаблонизатор [Pug][pug]
и напишем небольшой миксин для кнопки, а в качестве модального окна для примера
будем использовать стандартный компонент [Bootstrap 4][bootstrap4].

На случай если нет времени разбираться с использованием шаблонизатора
я продублирую код на HTML.

### Pug mixin

Итак, наш миксин будет состоять из кнопки и превью картинки внутри.
Превью мы будем брать непосредственно из видео с помощью ссылки -
`src="https://img.youtube.com/vi/#id/maxresdefault.jpg`.

Вместо `#id` необходимо подставить код видео Youtube формата - `c7nRTF2SowQ`.
Так же данная ссылка имеет несколько вариантов изображений:

* `default.jpg` - 120x90px
* `mqdefault.jpg` - 320x180px
* `hqdefault.jpg` - 480x360px
* `sddefault.jpg` - 640x480px
* `maxresdefault.jpg` - максимальное качество.

Для удобства демонстрации я немного отформатирую код:

{% highlight pug %}
mixin videoButton(modal, src, title)
button(
type="button"
data-toggle="modal"
data-target=`#${modal}`
data-src=`${src}`
data-title=`${title}`
class="js-play"
).btn.p-0
img(
src=`https://img.youtube.com/vi/${src}/maxresdefault.jpg`
alt=`${title}`
).card-img-top
{% endhighlight %}

В миксин будет передаваться три параметра:

* `modal` - `id` модального окна в котором будет выводиться видео.
* `src` - `id` Youtube видео.
* `title` - Название видео.

Так же необходим специальный класс `js-play` который будет использовать наш скрипт.
При желании его можно сделать параметром, если вам это необходимо.
Остальные классы в примере используются только для визуального отображения и
могут быть заменены или неиспользоваться вовсе.

Вызов миксина будет выглядеть так:

{% highlight pug %}
+videoButton(
'modalVideo',
'c7nRTF2SowQ',
'Официальный анонс-трейлер Battlefield 1'
)
{% endhighlight %}

Для удобства чтения я немного отформатирую получившийся HTML код кнопки
и в итоге он будет выглядеть так:

{% highlight html %}
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary playYoutube" data-toggle="modal"
data-target="#video" data-src="c7nRTF2SowQ">
Launch video 1
</button>
<button type="button" class="btn btn-primary playYoutube" data-toggle="modal"
data-target="#video" data-src="Sr-DKyAVU34">
Launch video 2
<button
class="btn p-0 js-play"
type="button"
data-toggle="modal"
data-target="#modalVideo"
data-src="c7nRTF2SowQ"
data-title="Официальный анонс-трейлер Battlefield 1">
<img
class="card-img-top"
src="https://img.youtube.com/vi/c7nRTF2SowQ/maxresdefault.jpg"
alt="Официальный анонс-трейлер Battlefield 1"/>
</button>
{% endhighlight %}

### Модальное окно

Разметка на Pug будет выглядеть так:

{% highlight pug %}
div(tabindex="-1" role="dialog" aria-hidden="true")#modalVideo.modal.fade
div(role="document").modal-dialog.modal-lg.modal-dialog-centered
.modal-content
.modal-header
h5.modal-title.js-title-insert
button(type="button" data-dismiss="modal" aria-label="Close").close.js-pause
span(aria-hidden="true") &times;
.modal-body.px-0.py-0
.embed-responsive.embed-responsive-16by9
#youTubeIframe.embed-responsive-item
{% endhighlight %}

Тут нас интересует всего четыре вещи:

* `#modalVideo` - `id` модального окна, оно должно совпадать с тем что вы
передаете в миксин или указываете в параметре `data-target`.
* `js-title-insert` - класс для вставки названия видео в шапку модального окна.
* `js-pause` - класс для кнопки закрытия модального окна.
* `#youTubeIframe` - `id` контейнера который будет преобразован в `iframe`.

Для того, что бы видео было адаптивным так же будет полезно
добавить обертку `.embed-responsive.embed-responsive-16by9`
и класс `.embed-responsive-item`, если вы используете Bootstrap,
или написать свои классы.

Сгенерированный HTML будет выглядеть так:

<!-- Video Modal -->
<!-- Modal -->
<div class="modal fade modal-video" id="video" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
{% highlight html %}
<div class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" id="modalVideo">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body">
<!-- 16:9 aspect ratio -->
<div class="modal-header">
<h5 class="modal-title js-title-insert"></h5>
<button class="close js-pause" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body px-0 py-0">
<div class="embed-responsive embed-responsive-16by9">
<div id="Youtube" class="embed-responsive-item"></div>
<div class="embed-responsive-item" id="youTubeIframe"></div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="close pauseYoutube" data-dismiss="modal"
aria-label="Close"><span aria-hidden="true">&times;</span></button>
</div>
</div>
</div>
</div>
<!-- /Video Modal -->
{% endhighlight %}

В данном коде нас интересует шесть пунктов:

* класс для кнопки открытия модального окна - <code>class="playYoutube"</code>
* дата атрибут - <code>data-src</code>
* дата атрибут - <code>data-target</code>
* id модального окна - <code>id="video"</code>
* id контейнера для видео - <code>id="Youtube"</code>
* класс кнопки закрытия модальки - <code>class="pauseYoutube"</code>

<code>class="playYoutube"</code> - необходим для того что бы по клику на кнопку
видео загружалось в модаль.

<code>data-src</code> - содержит код видео с youtube, которое будет загружаться
по нажатию кнопки.

<code>data-target</code> - должен совпадать с id модального окна.

<code>id="Youtube"</code> - указывает на элемент который превратиться
в iframe с видео. Для его адаптивности добавлена обертка и класс embed-responsive-item.

<code>class="pauseYoutube"</code> - указывает на кнопку при нажатии на которую
модальное окно закроется, а видео встанет на паузу.

## Подключение скрипта

Для того что бы скрипт заработал для начала нужно подключить скрипт YoutubeAPI.
Для того что бы скрипт заработал для начала
нужно подключить [YouTube Player API][youtubeapi].
Для этого достаточно вставить внизу страницы строчку:

{% highlight html %}
Expand All @@ -78,36 +152,48 @@ Launch video 2
{% endhighlight %}

После этого можно размещать основной скрипт:

{% highlight js %}
var player,
youtube = 'Youtube', //iframe id
btnPlay = '.playYoutube', // btn id or class
btnPause = '.pauseYoutube', // pause btn id or class
modalId = '#video', // Modal id
lastButton = '';
var player;
var lastButton = '';
const youtube = 'youTubeIframe';
const titleInsert = '.js-title-insert';
const btnPlay = '.js-play';
const btnPause = '.js-pause';
const modalId = '#modalVideo';
const videoQuality = 'hd720';

function onYouTubePlayerAPIReady() {
player = new YT.Player(youtube, {
controls: 2,
iv_load_policy: 3,
rel: 0,
events: {
'onReady': onPlayerReady
onReady: onPlayerReady
}
});
}

function onPlayerReady(event) {
$(btnPlay).on("click", function() {
var videoId = $(this).attr("data-src");
'use strict';
$(btnPlay).on('click', function() {
var videoId = $(this).attr('data-src');

if (lastButton == videoId) {
player.playVideo(videoId);
$(titleInsert).text($(this).attr('data-title'));
player.playVideo(videoId, 0, videoQuality);
} else {
player.loadVideoById(videoId);
$(titleInsert).text($(this).attr('data-title'));
player.loadVideoById(videoId, 0, videoQuality);
lastButton = videoId;
}
});
$(btnPause).on("click", function() {

$(btnPause).on('click', function() {
player.pauseVideo();
});
$(modalId).on("click", function() {

$(modalId).on('click', function() {
player.pauseVideo();
});
}
Expand All @@ -118,12 +204,17 @@ function onPlayerReady(event) {
Небольшой пример с двумя кнопками. При нажатии на первую кнопку видео
загружается, жмем на крестик - видео встает на паузу и при повторном нажатии
на первую кнопку воспроизведение продолжается с того места на котором было
закрыто окно, а при нажатии на кнопку два грузится новое видео.
закрыто окно, а при нажатии на вторую кнопку грузится новое видео.

<p data-height="485" data-theme-id="0" data-slug-hash="KgvGpN"
data-default-tab="html,result" data-user="lucaskane" data-embed-version="2"
class="codepen">See the Pen <a href="http://codepen.io/lucaskane/pen/KgvGpN/">
data-default-tab="result" data-user="deeppines" data-embed-version="2"
data-pen-title="Youtube video on modal popup." class="codepen">
See the Pen <a href="https://codepen.io/deeppines/pen/KgvGpN/">
Youtube video on modal popup.</a> by Lucas Kane
(<a href="http://codepen.io/lucaskane">@lucaskane</a>) on
<a href="http://codepen.io">CodePen</a>.</p>
<script async src="//assets.codepen.io/assets/embed/ei.js"></script>
(<a href="https://codepen.io/deeppines">@deeppines</a>) on
<a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

[pug]: https://pugjs.org/api/getting-started.html
[bootstrap4]: https://getbootstrap.com/docs/4.0/components/modal/
[youtubeapi]: https://developers.google.com/youtube/iframe_api_reference
9 changes: 1 addition & 8 deletions _sass/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,13 @@ body {
max-width: 960px;
min-height: calc(100% - 50px);
margin: 25px auto;
background: transparent;
background-color: $background-body;
box-shadow: 0 5px 15px 1px transparentize($black, .7);

// Large devices (desktops, less than 1200px)
@media (max-width: 1199px) {
transition: max-width .4s;
max-width: 960px;
}

// Medium devices (tablets, less than 992px)
@media (max-width: 991px) {
transition: max-width .4s;
max-width: 720px;
margin: 30px auto;
}

// Small devices (landscape phones, less than 768px)
Expand Down
14 changes: 13 additions & 1 deletion _sass/core/_colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,23 @@ $wight: #fff;
$black: #000;

//== Brand colors
//
//## Brand colors for use on website

$gunmetal: #293241;
$light-red-ochre: #EE6C4D;
$purple-navy: #3D5A80;
$pale-cerulian: #98C1D9;
$light-cyan: #E0FBFC;

// Other colors

$background-body: #ebebeb;

// Pines color

$pines-red: #962d3e;
$pines-blue: #118ab2;
$pines-green: #589b71;
$pines-yellow: #f0c808;


13 changes: 10 additions & 3 deletions _sass/core/type/_setting.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ html {

// Small devices (landscape phones, less than 768px)
@media (max-width: 767px) {
font-size: 88%;
font-size: 87.5%;
}

}
Expand Down Expand Up @@ -87,9 +87,16 @@ p {

// Code setting

code, kbd, samp {
code,
kbd,
samp,
var {
font-family: $font-code;
font-size: .9rem;
font-size: 87.5%;
}

code {
color: $pines-green;
}

// Link setting
Expand Down