21 апреля 2011 г.

coffee-script на html страничке

Coffee-script Кофи скрипт Кофе скрипт — в общем не знаю как написать вступление. Тем кому приходится прилично кодить на javascript е неверное про coffee script  уже слышали. Любые попытки создать что-нибудь приличное по масштабам на javascript  заканчивались созданием или приводили к использованию какого нибудь фреймворка (Jquery, prototype & etc.). Причина — код на javascript довольно громоздкий и трудно читаемый.
Coffee script ruby style язык транслируемый в javascript, т. е. Транслятор Вы можете скачать на сайте проекта: http://jashkenas.github.com/coffee-script/
там же небольшое руководство по использованию.
Все.

Coffee script — это такая вещь которая позволяет нудные выкладки на javascript представить в синтаксисе похожем на ruby — гораздо удобном и понятном. Сам Coffee-script браузерами не поддерживается (надеюсь, что пока, ну или хотя бы в виде плагина к браузеру). Поэтому нам нужен транслятор на javascript он может быть инсталлируемым или в виде подключаемого javascript скрипта.
Coffee script не одинок существует к примеру Objective-J (Читайте на wikipedia).

Главное что я хочу показать в этом посте — это то как запустить coffee-script на страничке. Как ни странно, когда я искал информацию как «готовить» скрипты на coffeescriptе, нигде не было примера того. как прикрутить скрипт к обычной html страничке без предварительной трансляции в javascript. Такая возможность позволит протестировать код и посмотреть кофе скрипт в действии. Для production он может быть тяжеловат — транслятор у меня весил 160 Kb.
В общем, смотрите
<!DOCTYPE html>
<html lang="ru">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>CoffeeScript</title>
<!-- Указываем транслятор coffee: -->
<!--<script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>-->
<script src="coffee-script.js"></script>
<!-- Демонстрация возможности запуска coffee скрипта + взаимодействие с объектами DOM -->
<script type="text/coffeescript">
# coffee class:
class Demo1
  constructor: (@name) ->
  show1: (param1) ->
    console.log "#1: "+@name + " &&& " + param1
  show2: (param1) ->
    console.log "#2: "+@name + " &&& " + param1
# object:
math =
  cube: (x) -> x * x * x
  square: (x) -> x * x
# coffee function
demo_function = () -> alert "You click on test node"
# глобальные объекты javascript доступны и из coffee-script
window.onload = () -> console.log "Welcome"
# добавляем обработчик события onclick
document.getElementById('testNode1').onclick= demo_function
document.getElementById('testNode2').onclick= ()-> alert "Hello 2"
# autostart as window.onload :
(() ->
demo= new Demo1 "xxx"
demo.show1 "yyy"
demo.show2 "www"
)
# end without '()' at the end, because no input's!
# Look on next ... on load:
((x) -> console.log "input value: "+x )(2)
</script>
</head>
<body>
<h1>hello <span id="message"></span></h1>
<p id="testNode1">Test Node 1</p>
<p id="testNode2">Test Node 2</p>
</body>
</html>

* This source code was highlighted with Source Code Highlighter.

Так же можете почитать http://blog.w3orme.com/2011/04/coffeescript.html

6 апреля 2011 г.

MSI Wind работаем с вебкамерой

На своем нетбуке MSI Wind u90X поставил вновь OpenSuse 11.4.
Все работает пока без нареканий (кроме WI-FI, не удалось настроить).

Относительно легко нашел на форуме (http://unixforum.org/index.php?showtopic=83408) как можно пробудить к жизни встроенную веб камеру.
Решение для ubuntu, но на OpenSuse можно и своим ходом установить пакет 'luvcview' (через Yast к примеру):

sudo apt-get install luvcview 
dmesg |grep -i "uvc"
luvcview -f yuv

Так же можно почитать: ещё одну статью по настройке системы (Описанные проблемы пока не встретил).

5 апреля 2011 г.

Сдаем лампу Аладина в утиль

Сделаем Санкт-Петербург чище будем сдавать отработавшие люминесцентные - галогенные - энергосберегающие лампы на утилизацию, а не в мусорный бак, как обычно.
ГУП "ЭКОСТРОЙ" в городе Санкт-Петербург по адресу  В.О. 13-я линия д. 22 принимает на утилизацию отработанные энергосберегающие лампы.
Так же туда можно сдать:

  1. градусники;
  2. таблетки - лекарства (кому уже не нужно).

Подробнее по ссылке на оф. сайт
Так же http://www.infoeco.ru/

16 марта 2011 г.

Размещаем номер телефона на странице

Продолжаю исследование возможностей браузеров на Webkit (предыдущая заметка про gps). На этот раз в поле зрения попала полезная вещь  - мобильный браузер (опыты ставились на Androidе) способен распознавать и преобразовывать в активную ссылку номера телефонов на странице.
Коммерческому сайту это может помочь в выколачивании денег повышении юзабилити сайта.
Как оформить номер телефона, так чтоб он светился, когда к нему подводили палец -
элементарно, просто грамотно его записать:
(904)620 2095 или 962-6182095 или 904-618-2094 и или (904) 618 2094

Чтобы отключить авто распознавание номера телефона на странице в браузере в хедере страницы нужно указать:
<meta name="format-detection" content="telephone=no">Syhi-подсветка кода
П. С. Подключить к делу можно и гипперссылки:
<a href="tel:1234567">XXX</a>
<a href="sms:1232334">XXX</a>Syhi-подсветка кода

11 марта 2011 г.

Пишем Web App c использованием html5 под Android

И так оглянемся и посмотрим что в наличие - Android аппарат: LG Optimus One (P500)  с Android 2.2 на борту.
И мы хотим нетолько быть потребителем чужих программок для имеющегося Android аппарата, но и творцом. Для этого у нас есть
Потенциальная возможность кодить на Java
Теоретическая (на данный момент теоретическая) возможность кодить на ruby (Ruboto) и др.
Возможность сверстать страничку для браузера с использованием html5.

В данном посте будет сверстана страница, которая будет представлять собой одностраничнное веб приложение позволяющее определять положение по сигналам gps. Данное приложение будет полностью построено на html5+css3+javascript и продемонстрирует возможность создания клиентских приложений для android на веб технологиях.
Почему я указал модель телефона — во первых только на этом телефоне проверялась работоспособность  и потому что возможности приложений будут дрейфовать от модели к модели телефона (хотя можно и найти компромисс между ними).

План мероприятий:
Особенность запуска страницы с SD карты
Принимаем сигнал gps на странице
Верстаем итоговую страницу


Особенность запуска страницы с SD карты
Стоить отметить, что этот пункт встанет ребром, когда понадобится запустить созданное приложение на аппарате. Страницу можно загрузить на хостинг, но можно разместить в папке  в корне SD-карты и потом  просто сделать закладку в браузере на эту страницу.
Допустим мы создаем в корне SD карты папку html5 а в нем файл index.html (html5/index.html)
Тогда, чтобы запустить эту страницу в адресной строке необходимо набрать: content://com.android.htmlfileprovider/sdcard/html5/index.html

Принимаем сигнал gps на странице
Одна из возможностей html5 — определять текущие координаты при помощи gps приемника.  Работоспособность проверялась только на LG Optimus One/ Android 2.2.
 Привожу пример реализующий функционал (gpsListener.js):

function gpsListener(){
       if(navigator.geolocation==undefined) return false;//
        else return true;//Браузер поддерживает работу с gps
}
with(gpsListener){
        //получаем сигнал
        prototype.turnOn= function(successCallback, errorCallback){
                if (this.watchId==undefined){
                        successCallback = successCallback || function(){};
                        errorCallback = errorCallback || function(){};
                        try {
                                function handleSuccess(position) {
                                successCallback(position);
                                }
                                this.watchId=navigator.geolocation.watchPosition(handleSuccess, errorCallback, {
                                        enableHighAccuracy: true,
                                        maximumAge: 10000, // 10 сек.
                                        timeout:1000
                                });
                       
                        }catch(err){
                                errorCallback(err);
                        }
                }
        }
        prototype.turnOff=function(endCallback){
                endCallback=endCallback||function(){};
                if (this.watchId > 0) {
                        navigator.geolocation.clearWatch(this.watchId);
                        endCallback();
                        this.watchId=undefined;
                }
               

        }
}

//Получаем размер доступной области экрана
function androidWindowSize(){
        if(screen){
                var landscapeOrPortrait
                //landscape=true; portrait=false;
                if (screen.width>screen.height) landscapeOrPortrait=true;
                else landscapeOrPortrait=false;
                return {width:screen.width, height:screen.height, orientation:landscapeOrPortrait };
        }
        else return undefined;// машинка видимо не андроид
}Syhi-подсветка кода

Верстаем итоговую страницу.
Ключевые моменты на которые следует обратить внимание будут отмечены в коде комментариями.
Код представлен на github в папке simple-gps

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

14 февраля 2011 г.

Silverlght: Бадания с Canvas

Простая задача. Необходимо на странице разместить в экземпляре ScrollViewer разместить  Canavas, а в нем уже изображение, TextBox или что-то еще. Делалось с той целью, чтобы получился такой объект в него можно было добавлять новые компоненты (помимо Image или TextBox), а он при этом растягивался и оставлял для доступа «ползунок” . Зараза Canvas, совсем не так работает как предполагалось. Скриншот тогда не сделал, поэтому не могу продемонстрировать — все содержимое обрезалось по фактическому размеру ScrollViewer (полоса прокрутки не потребовалась).
Озарение: Canvas не определяет свой размер по размеру дочернего элемента.
Второй целью этой задачи было создать компонент, который сможет не только справится с выше озвученной проблемой, но и сможет принимать новые параметры. Понятным языком — необходимо сделать доступным в xaml разметке компонента пользовательские свойства, через которые можно передавать параметры новому компоненту.
Озарение: Для создания пользовательских свойств компонента, доступных в xaml разметки необходимо использовать объект   свойств зависимостей public static readonly DependencyProperty.
 И так, постановка задачи:
1) Любой ценой разместить Canvas в ScrollViewer;
2) Реализовать эту задачу, как чисто в xaml так и чисто в C# (создав компонент)
3) Привести пример использование DependencyProperty

Замечание: Добавлять Canvas в ScrollViewer напрямую не удастся, вместо этого в ScrollViewer будет вложен Grid, в нем что угодно, в том числе Canvas. Все прочее что необходимо будет добавить добавляем в Grid:
Реализация на xaml:
<ScrollViewer HorizontalScrollBarVisibility="Auto"  Width="auto" Height="auto" Grid.Column="0" Grid.Row="1">
    <ScrollViewer.Content>
        <!-- Объект Canvas вложенный В объект ScrollViewer примет размер Scroll viewer и не будет учитывать
        рамер объектов размещенных в  Canvasе!! - поэтому используется Grid, а в нем Canvas -->

        <Grid Width="auto" Height="auto" >
            <!-- Смастерим просмотрщик: Размер Gridа будет под размер изображения-->
            <Image x:Name="loadedImage" Width="auto" Height="auto">
               <Image.RenderTransform>
               <CompositeTransform ScaleX="1" ScaleY="1"/><!-- Задел для масштабирования-->
               </Image.RenderTransform>
               </Image>
            <!-- Если не все дочерние эл-ты в Grid разместить в одной ячейки то они могут идти как два слоя  -->
               <Canvas Background="Transparent" >
               <!-- Поверх Image будет прозрачный Холст, а на нем кнопка (можно заменить на что, нибудь другое) -->
                <Button Content="It s Canvas" Canvas.Left="100" Canvas.Top="100"/>
              <!-- Вообщим Canvas будет такого-же размера как и  Image -->
            </Canvas>
        </Grid>
    </ScrollViewer.Content>
</ScrollViewer>Syhi-подсветка кода
Реализация компонента на C#:
// Небольшой класс реализующий возможность простых манипуляций изображений
// В данном случае возможность просмотра изображения превышающего размер окна
public class ImageManipulate : ContentControl
{
    // Добавляем произвольное свойство к создаваемому компоненту - исходное изображение
    public static readonly DependencyProperty SourceProperty =
        DependencyProperty.Register("Source", typeof(Image),typeof(ImageManipulate), null);
    //Дополнительное свойство позволяющее принимать canvas как параметр в xaml разметке
    public static readonly DependencyProperty CanvasInsideProperty =
        DependencyProperty.Register("CanvasInside", typeof(Canvas), typeof(ImageManipulate), null);
    private double _imageWidth;     // Ширина оригинального изображения
    private double _imageHeight;    // Высота оригинального изображения
    private Image _image;           // Изображение для возможных манипуляций
    private ScrollViewer viewerBox;
    private Grid mainGridContainer;
        //Свойство которое и осуществляет прием  и передачу изображения
    public Image Source
    {
                get { return (Image)GetValue(SourceProperty); }
        set
            {
            SetValue(SourceProperty, value);
            _image = value;//Кэшируем изображение
            _imageWidth = _image.Width;
            _imageHeight = _image.Height;
            this.mainGridContainer.Children.Add(this._image);//Добавляем изображение в Grid
            }
    }
    public Canvas CanvasInside
    {
        get { return (Canvas)GetValue(CanvasInsideProperty); }
        set
        {
            SetValue(CanvasInsideProperty, value);
            this.mainGridContainer.Children.Add(value);
        }
    }
    public ImageManipulate()
    {
        this.mainGridContainer = new Grid();
        viewerBox = new ScrollViewer() { HorizontalScrollBarVisibility = ScrollBarVisibility.Auto };
        viewerBox.Content = this.mainGridContainer;// Создаем объект контейнера с "ползунками" и добаляем в него Грид
        this.Content = viewerBox;
    }
}Syhi-подсветка кода
Его ре инкарнация в xaml разметке:
<!-- xmlns:local="clr-namespace:FotoDocDemo1;assembly=FotoDocDemo1" - ссылаемся на пространство имен
в котором находится класс ImageManipulate-->

<local:ImageManipulate Grid.Row="1" Width="auto" Height="auto">
        <!-- Свойство Source: -->
    <local:ImageManipulate.Source>
        <Image Source="img/avstria.jpg" Width="auto" Height="auto"/>
    </local:ImageManipulate.Source>
        <!-- Свойство CanvasInside-->
    <local:ImageManipulate.CanvasInside>
        <Canvas Width="auto" Height="auto">
            <Button Content="Click" Canvas.Left="200" Canvas.Top="200"/>
        </Canvas>
</local:ImageManipulate.CanvasInside>
</local:ImageManipulate>Syhi-подсветка кода

10 февраля 2011 г.

Задача "Восемь Ферзей"

Matraska продолжает изучать алгоритмические задачи. На этот раз задача будет о Восьми ферзях (см. WikiPedia).
Эта задача, да и все подобные полезны тем, что позволяют отточить навыки кодинга, здорово поломать голову, и конечно научится новому.
Так на примере этой задачи небезызвестный автор этого труда познал приемы работы с двумерными массивами (до этого как то не доходили руки), почесал репу и не смог найти другого  алгоритма решения этой задачи, кроме как метода подбора... И в правду задача немного сложнее, а написанный на ruby код немного объемнее, чем реализации этой задачи  других авторов на C, Basic и прочих языках, которые удалось найти при не продолжительном поиске по Гуглю.
class Eight_ferz
  attr_reader :chease_board
  def initialize()
    #Создаем многомерный массив
    @chease_board = Array.new(8)
    @chease_board.map! { Array.new(8,0) }# Инициализируем массив 0-ми
  end
 #Метод демонстрирующий всю доску
  def show_board
    @chease_board.each do |row|
      p row
    end
  end
  # Метод устанавливающий фигуру на шахматной доске
  # n- номер строки, m - номер столбца
  def set_figure(n,m)
    # Устанавливаем 1 (замораживаем точки) по ортогональным линиям шахмотной доски
    (0..7).each{|index| @chease_board[n][index]=@chease_board[index][m]=1}
    # Рассматриваем 4 ю четверть СК(центр СК точка n,m)
    n4,m4=n,m
    #puts("n: #{n4}, m: #{m4}")
    while (n4<8&&m4<8)
      @chease_board[n4][m4]=1
      n4+=1;
      m4+=1
      #puts("n: #{n4}, m: #{m4}")
    end
    n1,m1=n,m
    while(n1>=0&&m1<8)
      @chease_board[n1][m1]=1
      n1-=1;
      m1+=1
    end
    n2,m2=n,m
    while(n2>=0&&m2>=0)
      @chease_board[n2][m2]=1
      n2-=1
      m2-=1
    end
    n3,m3=n,m
    while(n3<8&&m3>=0)
      @chease_board[n3][m3]=1
      n3+=1
      m3-=1
    end
    @chease_board[n][m]=2;
  end
  def free_positions()
    free_pos=Array.new()
    # Перебираем все позиции, если равен 0 в массив
    (0..7).each do|n|
      (0..7).each do |m|
        if @chease_board[n][m]==0
          #puts("N[#{n}], M[#{m}]")
          free_pos<<[n,m]
        end
      end
    end
    # В качестве ответа метода выводим координаты выбранной точки и кол-во свободных позиций
    if free_pos.size>0
      free_pos[rand(free_pos.size-1)]<<free_pos.size
    else
      nil
    end
   
  end
  # Решение методом перебора(может заполнить доску 5-8 ферзями!)
  def start
  count=0
  current_position=self.free_positions()# получаем координаты позицию на которую можно поставить ферзя
    while (!current_position.nil?)
      self.set_figure(current_position[0],current_position[1]) # устанавливаем ферзя
      current_position=self.free_positions() #
      count+=1
    end
  puts("Count #{count}")
  end
endSyhi-подсветка кода
Пример вызова (может быть от 5-до 8 ферзей!):

obj1=Eight_ferz.new()
obj1.start
obj1.show_board