Ванильный привкус с использованием API Instagram и котят

в 7:32, , рубрики: Instagram API, iOS, разработка

Мы познакомились с ней десятого октября 2013 год. Сегодня у нас 264 дня. Волей случайностей такая уж завелась у нас традиция — отмечать не круглые даты отношений. Мы покупаем вино на 99 день, устраивали фуршет на 111, а про 123-й рассказывать неприлично. Во всяком случае это уже вошло в хорошую традицию и мы её очень ценим.
Это пост о том, как я сделал довольно милое приложение с фоточками и котятами.

Немного входных данных. У меня нет аккаунта разработчика Apple, потому это будет псевдо-приложение под iPhone (кто не понимает о чем я прочтете дальше). У меня имеется пара часов свободного времени, два аккаунта в инстаграме (её и мой) знания хорошие знания html, js, css, лишние 100 рублей, и её безграничная любовь к котятам.

У неё iPhone 5s потому писаться и верстаться всё будет под конкретную модель, что облегчит задачу.
Для начала я пошел и зарегистрировал за 99 руб домен отношенияэтоад.рф на котором всё действо и будет происходить. Цель приложения — автоматически при открытии подсчитывать и отображать сегодняшний день. Идея навеяна одним из моих любимых фильмов «500 дней лета».

Написать скрипт отсчета дней от определенной даты до сегодняшнего дня совершенно не сложно и в сети подобных полно. Дабы не заморачиваться, взял один из таких за основу и подогнал под свои непосредственные нужды.

Скрипт подсчёта дней от даты до даты

<SCRIPT LANGUAGE="JavaScript">
<!--
	
function GoodYear (year) {
 return (year<1900 ? year+1900 : year);
}

function LeapYear (year) {
 if ((year%4==0) && (year%100!=0) || (year%400==0)) return true;
 else return false;
}

function KolDays (d1,m1,d2,m2,y) {
 var i,s;
 var mondays= new Array (31,28,31,30,31,30,31,31,30,31,30,31);
 if (LeapYear (y)==true) mondays[1]=29;
 if (m1==m2) s=d2-d1;
 else {
  s=mondays[m1-1]-d1+1;
  for (i=m1+1;i<m2;i++) s+=mondays[i-1];
  s+=(d2-1);
 }
 return s;
}

function DaysBetween (day1,mon1,year1,day2,mon2,year2) {
 var i,f;
 if (year1==year2) f=KolDays (day1,mon1,day2,mon2,year1);
 else {
  f=KolDays (day1,mon1,31,12,year1)+1;
  for (i=year1+1; i<year2; i++) {
   f+=365;
   if (LeapYear (i)) f++;
  }
  f+=(KolDays(1,1,day2,mon2,year2));
 }
 return f;
}

function WeekDay (day,month,year) {
 if (month<3) month+=10; else month-=2;
 if (month>10) year--;
 var cent=Math.floor(year/100);
 year %= 100;
 var dday= Math.floor(2.6*month-0.2)+day+year+Math.floor(year/4)+Math.floor(cent/4)-2*cent;
 dday= Math.floor((dday+777)%7);
 return ((dday==0) ? 7 : dday); 
}

function PutInForm (d) {
 if ( ((d%100) > 9) && ((d%100) < 21) ) s="";
 else if ((d % 10) ==1) s="";
 else if (((d % 10) >1) && ((d % 10)<5)) s="";
 else s="";
 document.getElementById("life").innerHTML  = '('+ d + ')'+''+s;;
}

function InitForm() {
  var wkd= new Array ("Пн","Вт","Ср","Чт","Пт","Сб","Вс");
  var today = new Date();
  d=today.getDate();
  m=today.getMonth();
  y=GoodYear(today.getYear());
 
  m++;
  t=DaysBetween (24,10,2013,d,m,y);
  PutInForm (t);
  w=WeekDay(d,m,y);
  document.Q.wk2.value=wkd[w-1]; 
  First=true;
}


function CorrectDate (d,m,y) {
 var mondays= new Array (31,28,31,30,31,30,31,31,30,31,30,31);
 if (y<1) {
  return false;
 }
 if (LeapYear (y)==true) mondays[1]=29;
 if ((d<1) || (d>mondays[m-1])) {
  return false;
 }
 return true;
}

function Validate () {
 var wkd= new Array ("Пн","Вт","Ср","Чт","Пт","Сб","Вс");
 var d1,m1,y1,d2,m2,y2,t,d,w;
 d1=parseInt(document.Q.day1.value);
 m1=document.Q.month1.selectedIndex+1;
 y1=parseInt(document.Q.year1.value);
 d2=parseInt(document.Q.day2.value);
 m2=document.Q.month2.selectedIndex+1;
 y2=parseInt(document.Q.year2.value);
 if ( (isNaN (d1)==true) || (isNaN (d2)==true) || (isNaN (y1)==true) || (isNaN (y2)==true)) {
  window.alert ("Введен недопустимый день или год! Пожалуйста, исправьте данные в форме.");
  return false;
 }
 t=CorrectDate(d1,m1,y1);
 if (t==false) {
  window.alert ("Введена недопустимая начальная дата! Пожалуйста, исправьте данные в форме.");
  return false;
 }
 t=CorrectDate(d2,m2,y2);
 if (t==false) {
  window.alert ("Введена недопустимая конечная дата! Пожалуйста, исправьте данные в форме.");
  return false;
 }
 if ( (y1>y2) || (y1==y2) && ((m1>m2)||(m1==m2)&&(d1>d2)) ) {
  window.alert ("Начальная дата больше конечной! Пожалуйста, исправьте данные в форме.");
  return false;
 }
 d=DaysBetween (d1,m1,y1,d2,m2,y2);
 PutInForm(d);
 w=WeekDay(d1,m1,y1);
 document.Q.wk1.value=wkd[w-1];
 w=WeekDay(d2,m2,y2);
 document.Q.wk2.value=wkd[w-1];
 return true;
}
// -->
</SCRIPT>

Дальше я хочу что б количество дней отображалось на фоне случайно фотографии из моего и ее инстаграма. API у них не особенно сложный, но для удобства я пользуюсь очень удобной библиотекой instafeedjs.com. Подключил библиотеку к документу, добавил в тело

<div class="feed" id="instafeed"></div>

Пользоваться библиотекой, еще раз, очень удобно. Допустим если мы хотим вывести поток фоток с тегом #love:

<script type="text/javascript">
    var feed = new Instafeed({
        get: 'tagged',
        tagName: 'love',
        clientId: 'YOUR_CLIENT_ID'
    });
    feed.run();
</script>

На странице instafeedjs есть ёмкое, но достаточное описание. CLIENT_ID можно получить в девелоп-разделе инстаграма. Нужно будет создать (зарегистрировать) новую программу и сервис выдаст все необходимые вам ключи.

Я решил, что мне нужно подключиться к аккаунту и выбрать случайным образом одну из, скажем, 11 последних снимков. Мой скрипт выглядит вот так:

  var feed = new Instafeed({
        get: 'user',
        userId: 30922527, 
        clientId: '445c6ebabb324139a654630c0d2ed008d9076',
		accessToken: '30922527.467ede5.6af64d56d9f34762a33535f349db5fbd7096',
		resolution: 'standard_resolution',
		sortBy: 'random',
		links:'false',
		limit:'11',
		template: '<img class="front" src="{{image}}" />'
		
    });
    feed.run();

get: 'user', — запрос к юзеру. userId: 30922527, — к какому конкретно. resolution: 'standard_resolution', — это размер выдаваемых изображений. Инстаграм предлагает три варианта:
thumbnail 150x150
low_resolution 306x306
standard_resolution 612x612

clientId нам уже известен, а accessToken предварительно залогиневшись, можно получить на сайте того же instafeedjs (внизу есть ссылка).
С помощью links:'false', отключаем залинковывание снимков, ведущих в аккаунт.
sortBy: 'random', и limit:'11', вот здесь загвоздка произошла. Мне бы хотелось выводить каждый раз случайный снимок и здесь работает sortBy: 'random',, но для этого их сначала нужно прогрузить limit:'11',, иначе, установив лимит загрузок единичку — он и сортировать будет только среди одного единственного снимка. Все в общем то и логично, но покопаться в коде библиотеки мне моя лень к сожалению пока не позволила. Кстати говоря, максимум можно загружать 60 снимков этим параметром.
т.к. мне нужен всего один а не целая лента, я наложил снимки один на другой и выровнял по центру страницы таким css:

.feed{
width:912px;
height:912px;
position:absolute;
left:40%;
top:40%;
margin:-345px 0 0 -345px;
}

.front{
width:912px;
height:912px;
z-index:0;position:absolute;
}

Вот такой костыль, дико извиняюсь.
Хочу здесь заметить что открывать это предполагалось на конкретном устройстве, а в данном случае iPhone 5s, потому были заранее известны размеры и оставалось подогнать всю конструкцию под них с помощью CSS. С десктопа, верстка скорее всего повалится, но это подправить и адаптировать при необходимости всего лишь дело техники.

Поверх изображения накладываем результат выполнения нашего скрипта, высчитывающее часы, которые некоторые счастливые все-таки наблюдают.

.life{
position:absolute;
left:50%;
top:50%;
margin:-150 0 0 -190;
text-shadow: 1px 1px 2px black, 0 0 1em black;
font: Georgia;
font-size: 210px;
color: #f5f5f5;
}

А теперь то, чего вы так долго ждали — котята.
Ванильный привкус с использованием API Instagram и котят
По одному котенку мы посадим на верхний край загруженного снимка

.cat{
position:absolute;
left:50%;
top:50%;
margin:-635 0 0 170;
text-shadow: 1px 1px 2px black, 0 0 1em black;
font: Georgia;
font-size: 210px;
color: #f5f5f5;
}

И будем выводить каждый раз разного

function rand(min, max){
return (max-min)*Math.random()+min
}
var r=Math.round(rand(1,14));
document.write('<div class="cat"><a href=><img id="cat" src="cats/'+r+'.png "/></a></div>')

К тому же, котенок-кнопка обновляет страницу перегружая следующий случайный рисунок.

Теперь всё готово для сборки псевдо-приложения под iPhone.
Заливаем все это на сервер, заходим с мобильного браузера Safari на делегированный к этому моменту домен отношенияэтоад.рф видим то, что мы получили:
Ванильный привкус с использованием API Instagram и котят
Теперь, пользуясь возможностями мобильного Safari помещаем иконку сайта на экран домой. Это делается в меню шаринга:
Ванильный привкус с использованием API Instagram и котят

Теперь у нас на домашнем экране среди приложений присутствует ничем не отличающийся от остальных ярлычок нашего псевдо-апп.
Тут я должен рассказать про создание иконки. Есть некоторая спецификация у компании Apple, т.к. иконку, поддерживаемую iOs можно сделать для любого сайта, достаточно прописать:

<meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="apple-touch-icon" href="touch-icon-iphone.png">
<link rel="apple-touch-icon" sizes="76x76" href="touch-icon-ipad.png">
<link rel="apple-touch-icon" sizes="120x120" href="touch-icon-iphone-retina.png">
<link rel="apple-touch-icon" sizes="152x152" href="touch-icon-ipad-retina.png">

Здесь, по названию файлов понятно для каких устройств они предназначены и каких размеров должны быть. Остается лишь залить соответствующие пиктограммы.
И ещё один важный момент. Пропишите в самом начале

<meta name="apple-mobile-web-app-capable" content="yes" />

Этот код избавит нас от юзер-бара снизу и строки ввода адреса вверху, сделав страницу более «приложение-похожее».
Что в итоге:
Ванильный привкус с использованием API Instagram и котят

Маше эта штука очень понравилась. Ну и я рад.
Должен сказать, что несложно было бы модернизировать и показывать не сколько дней прошло а сколько дней прошло на момент снятого фото (в api можно вытянуть дату снимка) получится забавное приложение для любителей понастольгировать например. Да и инстаграм использовать необязательно. Куда больше фотоархивы хранятся у людей на других сервисах. Тут уж вопрос цели.

Исходники: прилагаются

Автор: heroino

Источник


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js