T.M. SoftStudio

feci quod potui, faciant meliora potentes

GAE-приложение: Галерея фотографий

В данной статье рассматривается создание на JSP-странице GAE-приложения галереи фотографий, наполняемой с помощью Entity-сущностей, хранящихся в Datastore-хранилище, а также самих изображений, хранящихся в Blobstore-хранилище платформы Google App Engine.

В JSP-странице приложения создадим блок:

<%@ page import="com.google.appengine.api.datastore.*" %>

<%@ page import="com.google.appengine.api.datastore.Query.*" %>

<%@ page import="com.google.appengine.api.blobstore.*" %>

<%@ page import="com.google.appengine.api.images.*" %>

<%@page import="java.util.*"%>

<div id="all_img">

<div id="all_img_count"></div>

<div id="btn_all_img_list_prev" >&#60;&#60;</div>

<div id="all_img_content" >

<%

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

ImagesService imagesService = ImagesServiceFactory.getImagesService();

Query qUsersImage = new Query("UsersImage");

PreparedQuery pq = datastore.prepare(qUsersImage);

List<Entity> list = pq.asList(FetchOptions.Builder.withDefaults());

if(!list.isEmpty()){

for (Entity result : list) {

String album = (String)result.getProperty("album");

BlobKey blobkey=(BlobKey) result.getProperty("blobKey");

String blobkeyToString=blobkey.getKeyString();

String url = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(blobkey).imageSize(400));

String name=(String)result.getProperty("name");

%>

<figure class="all_img" >

<label class="all_img_label"><%=album %></label>

<div><img src="<%=url %>" alt=""/></div>

<figcaption class="all_img_label"><%=name %></figcaption>

<label class="blobkeyToString" style="display:none;"><%=blobkeyToString %></label>

</figure>

<%

}

%>

</div>

<div id="btn_all_img_list_next">&#62;&#62;</div>

</div>

<%

}

%>

В вышеприведенном коде блок «all_img_content» окружен справа и слева стрелками «<<» и «>>», при клике на которые изображения будут перелистываться.

В блоке «all_img_content» динамически с помощью запроса к Datastore-хранилищу GAE-платформы формируются блоки «figure», содержащие название альбома изображения, само изображение и название изображения.

Entity-сущности типа «UsersImage», хранящиеся в Datastore-хранилище, содержат BlobKey-ключ изображения, в свою очередь хранящегося в Blobstore-хранилище GAE-платформы, название альбома изображения и название самого изображения.

После извлечения BlobKey-ключа изображения из UsersImage-сущности, с помощью GAE-сервиса Images создается URL-адрес изображения, размер которого уменьшается до 400 пикселей.

CSS-стиль созданного блока «all_img»:

figure {

display: none;

float: left;

margin: 0px 10px 10px 0px;

text-align: center;

}

figcaption {

color: #8B0000;

font-weight:bold;

width:150px;

}

#all_img{

text-align:right;

border-color:#972509;

border-width:2px;

border-style:solid;

background-color:#000;

width:500px;

height:500px;

margin-left:75px;

padding-bottom:20px;

}

#all_img_count {

color:#fff;

font-size:16px;

margin-left:20px;

text-align: left;

padding-top:10px;

}

#all_img_content{

float:left;

}

#btn_all_img_list_prev{

color:#fff;

float:left;

cursor:pointer;

font-size:20px;

height:50px;

}

#btn_all_img_list_next{

color:#fff;

cursor:pointer;

font-size:20px;

height:50px;

}

.all_img{

margin-left:26px;

cursor:pointer;

}

.all_img_label{

color:#fff;

width:400px;

overflow: hidden;

text-align: center;

}

CSS-стиль определяет наличие рамки вокруг всего блока «all_img», а также расположение блоков «btn_all_img_list_prev», «all_img_content» и «btn_all_img_list_next» в один ряд с помощью свойства float:left.

Первоначально все блоки «figure» скрыты.

При отображении блока «all_img» запускается JQuery-код:

var length=$('.all_img').length;

$('#all_img_count').html('1/'+length);

$('.all_img').hide();

$('.all_img').first().show();

var heightFoto=[];

$('.all_img').each(function(index) {

var height=$(this).height();

heightFoto[index]=height;

});

var j=0;

for(var i=0;i<heightFoto.length;i++)

{

if(heightFoto[i]>heightFoto[j])

j=i;

}

var height=heightFoto[j];

var heightContent=$('#content').height();

if(heightContent<500){

$('#content').css('height','500px');

}

$('#all_img').css('height',height+20+'px');

$('#btn_all_img_list_prev').css('padding-top',(height-50)/2+'px');

$('#btn_all_img_list_next').css('padding-top',(height-50)/2+'px');

В вышеприведенном коде вычисляется количество блоков «figure», затем полученная цифра передается в блок «all_img_count» для отображения.

Первый блок «figure» отображается и вычисляется максимальная высота всех блоков «figure», чтобы затем подогнать высоту блока «all_img» и высоту его родительского блока «content» под полученную максимальную высоту.

Стрелки «<<» и «>>» выравниваются на середину блока «all_img».

Перелистывание изображений обеспечивает следующий JQuery-код:

$("#btn_all_img_list_prev").click(function() {

var i='';

var j='';

var el=[];

$('.all_img').each(function(index) {

el[index]=$(this);

if($(this).css('display')!='none'){

i=index;

}

});

if(i!=0){

el[i].hide('slow');

j=i-1;

$('#btn_all_img_list_prev').hide('slow');

el[j].show('slow');

$('#btn_all_img_list_prev').show('slow');

var length=$('.all_img').length;

$('#all_img_count').html((j+1)+'/'+length);

}

});

$("#btn_all_img_list_next").click(function() {

var i='';

var j='';

var el=[];

$('.all_img').each(function(index) {

el[index]=$(this);

if($(this).css('display')!='none'){

i=index;

}

});

if(i!=(el.length-1)){

el[i].hide('slow');

j=i+1;

$('#btn_all_img_list_next').hide('slow');

el[i+1].show('slow');

$('#btn_all_img_list_next').show('slow');

var length=$('.all_img').length;

$('#all_img_count').html((j+1)+'/'+length);

}

});

В вышеприведенном коде вычисляется индекс отображаемого блока «figure», затем данный блок «figure» скрывается, а отображается блок «figure» с предыдущим или следующим индексом.