DataLife Engine > Версия для печати > Разрабатываем экран загрузки на подобии iOS с помощью CoffeeScript

Сегодня мы расскажем вам о создании экрана загрузки на подобии iOS с помощью CoffeeScript – новая jQuery-библиотека, основанная на javascript. CoffeeScript предлагает вам понятный синтаксис, напоминающий нечто вроде Ruby и Python. Если вы не знакомы с данными языками, не беспокойтесь – эти знания вам не потребуются. Тем не менее, вы должны быть знакомы с javascript, вам следовало бы понимать принцип работы.Мы также воспользуемся плагином Touchable, чтобы иметь возможность определять события от прикосновений.

Что такое CoffeeScript?

CoffeeScript – это удобный язык программирования, который поможет вам расширить основу javascript. Библиотека значительно облегчает объектно-ориентированное программирование, предлагает множество полезных дополнений и некоторые небольшие улучшения.

CoffeeScript работает во всех браузерах, и совместима с любым существующим кодом javascript (включая библиотеки типа jQuery и плагины). Но как же она будет работать, если язык отличается? Просто – CoffeeScript компилирует его в javascript, поэтому и работает во всех браузерах и поддерживает их.Перед началом ознакомления, мы рекомендуем вам ознакомиться с примерами на сайте CoffeeScript (не забудьте посетить вкладку «Try CoffeeScript»), а также возьмите на приметку издание «The Little Book on CoffeeScript», чтобы немного познакомиться с языком.

HTML-код

Давайте начнем с верстки HTML для нашего экрана загрузки. Как обычно, будем использовать документ HTML5 с таблицами стилей в шапке, и включенным JS перед закрывающим тегом body.

Index.html





        iOS Home Screen with CoffeeScript | Tutorialzine Demo
















            
    
    
    
    
    
    
    
    
    
    
    
    
    
                # Our Code Goes Here
    
    
    
    
    

    У нас есть раздел #homeScreen, который и будет основным контейнером для нашего эксперимента. Внутри будет #mask, где используется overflow:hidden, чтобы в тот момент был отображен только экран загрузки. Div #allScreens внутри него (как видно по названию) будет содержать все динамически сгенерированные div’ы .screen с иконками.

    1369382137_1321264131_cs-03-4352950

    Далее идут ul’ы #indicators, которые отображают нам маленькие точки с на данный момент отображенным краном, а также div #dock.

    Как ранее было сказано, CoffeeScript требует дополнительного этапа компиляции, который позволит вам конвертировать исходный код в javascript. Вы сможете делать это посредством coffeescript для node.js (как указано на сайте), либо посредством coffeescript.exe для Windows, который отлично работает отдельно. Что касается маленьких скриптов, вы также можете включить компилятор напрямую в страницу, и вписывать нужный код в тег «script» (который мы и будем использовать сегодня.В нижней части страницы вы можете видеть наши включенные скрипты. Это у нас библиотека jQuery, плагин Touchable, что позволяет нам работать с событиям при касаниях, а также компилятор CoffeeScript – coffee-script.js. Компилятор будет исследовать страницу на наличие «script type="text/coffeescript"», где мы будем вписывать наш код.

    Код CoffeeScript

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

    # The Icon class.
    
    class Icon
    
        # The constructor. The -> arrow signifies
        # a function definition.
    
        constructor: (@id, @title) ->
            # @ is synonymous for "this". The id and title parameters
            # of the constructor are automatically added as this.id and this.title
    
            # @markup holds the HTML of the icon. It is
            # transformed to this.markup behind the scenes.
    
            @markup = ""

    Объекты данного класса будут представлять иконки на экране загрузки. Каждая иконка будет обозначена параметром, содержащим HTML-код, нужный для ее отображения. Вы можете видеть, что функции в CoffeeScript определяются стрелками (->), а параметры функции указаны в левой части, в скобках. Учтите, что здесь комментарии начинают с символа #. Вы можете использовать три ### для определения многострочных комментариев.Теперь давайте определим класс для иконок панели. Он будет очень похожим на класс icon, мы просто расширим его:

    # The DockIcon class inherits from Icon
    
    class DockIcon extends Icon
        constructor: (id, title)->
    
            # This calls the constructor if Icon
    
            super(id, title)
    
            # Changing the class name of the generated HTML
            @markup = @markup.replace("class='icon'","class='dockicon'")

    Используя super() мы можем вызвать конструктор иконок и инициализировать параметры верстки. Нам можно нужно заменить имя класса.Мы разделим экран загрузки на отдельные div’ы .screen, и у каждого из них будет собственный набор иконок. Давайте рассмотрим его класс:

    # The Screen Class
    
    class Screen
    
        # Function arguments can have default values
        constructor: (icons = [])->
            @icons = icons
    
        attachIcons: (icons = [])->
            Array.prototype.push.apply(@icons, icons)
    
        generate: ->
            markup = []
    
            # Looping through the @icons array
            markup.push(icon.markup) for icon in @icons
    
            # The last line of every function is implicitly returned
            "#{markup.join('')}"

    Вместо параметров верстки, мы будем использовать метод generate(), который вернет нам HTML-код. Учтите то, как мы зацикливаем массив, такой метод называется включение. Часть перед 4 ключевиком выполняется в каждом элементе в массиве иконок. 1369382252_1321264109_cs-04-2236735 Теперь нам нужен класс, который соберет все вместе, а также будет контролировать переходы между экранами. Вот так это всё должно выглядеть:

    class Stage
    
        # The width of our "device" screen. This is
        # basically the width of the #mask div.
    
        screenWidth: 332
    
        constructor: (icons)->
    
            @currentScreen = 0
            @screens = []
    
            # Calculating the number of screens
            # necessary to display all the icons
    
            num = Math.ceil(icons.length / 9)
            i = 0
    
            while num--
                # we pass a slice of the icons array
                s = new Screen(icons[i...i+9])
    
                # adding the screen to the local screens array
                @screens.push(s)
    
                i+=9
    
        # This method populates the passed element with HTML
        addScreensTo: (element)->
    
                    # We are using the jQuery library from within CS:
            @element = $(element)
            @element.width(@screens.length*@screenWidth)
    
            for screen in @screens
                @element.append(screen.generate())
    
        addIndicatorsTo: (elem)->
    
            # This method creates the small circular
            # indicators. Also using jQuery
    
            @ul = $(elem)
    
            for screen in @screens
                @ul.append('
  • ') @ul.find('li:first').addClass('active'); # ... More methods go here ... Stage берёт массив иконок в конструкторе. Далее производится вычисление, сколько потребуется экранов, и создается объект для каждого из них, заполняя его частью массива иконок.Теперь у нас есть разметка для всех элементов на странице, но все еще отсутствуют методы контроля переходов между отрезками. Вы можете видеть их ниже (оставшийся код класса Stage):
    goTo: (screenNum)->
    
        # This method animates the allScreen div in
        # order to expose the needed screen in #mask
    
        if @element.is(':animated')
            return false
    
        # if this is the first or last screen,
        # run the end of scroll animation
    
        if @currentScreen == screenNum
    
            # Parallel assignment:
            [from, to] = ['+=15','-=15']
    
            if @currentScreen != 0
                [from, to] = [to, from]
    
                           # Tell the user there aren't any more screens:
            @element.animate( { marginLeft : from }, 150 )
                    .animate( { marginLeft : to }, 150 )
        else
            # If everything is ok, animate the transition between the screens.
            # The fat arrow => is a function that preserves the context of "this"
    
            @element.animate( { marginLeft:-screenNum*@screenWidth }, => @currentScreen = screenNum )
            @ul.find('li').removeClass('active').eq(screenNum).addClass('active');
    
    next: ->
        toShow = @currentScreen+1
    
        # If there is no next screen, show
        # the last one
    
        if toShow == @screens.length
            toShow = @screens.length - 1
    
        @goTo(toShow)
    
    previous: ->
        toShow = @currentScreen-1
    
        # If there is no previous screen,
        # show the first one
    
        if toShow == -1
            toShow = 0
    
        @goTo(toShow)

    Как метод next(), так и previous() вызывают goTo() внутренне, проводя номер экрана (начиная от 0). Метод goTo() анимирует div #allScreen для отображения нужного экрана. Нам осталось лишь закрепить функцию к событию document.ready. Для этого мы воспользуемся jQuery.

    # This is equivalent to $(function(){}):
    
    $ ->
    
            # You can skip the comma if it's on the end of a line:
        allIcons = [
            new Icon('Photos', 'Photo Gallery'), new Icon('Maps', 'Google Maps')
            new Icon('Chuzzle', 'Chuzzle'), new Icon('Safari', 'Safari')
            new Icon('Weather', 'Weather'), new Icon('nes', 'NES Emulator')
            new Icon('Calendar', 'Calendar'), new Icon('Clock', 'Clock')
            new Icon('BossPrefs', 'Boss Prefs'), new Icon('Chess', 'Chess')
            new Icon('Mail', 'Mail'), new Icon('Phone', 'Phone')
            new Icon('SMS', 'SMS Center'), new Icon('Camera', 'Camera')
            new Icon('iPod', 'iPod'), new Icon('Calculator', 'Calculator')
            new Icon('Music', 'Music'), new Icon('Poof', 'Poof')
            new Icon('Settings', 'Settings'), new Icon('YouTube', 'Youtube')
            new Icon('psx4all', 'PSx4All'), new Icon('VideoRecorder', 'Record Video')
            new Icon('Installer', 'Installer'), new Icon('Notes', 'Notes')
            new Icon('RagingThunder', 'RagingThunder'), new Icon('Stocks', 'Stocks')
            new Icon('genesis4iphone', 'Genesis'), new Icon('snes4iphone', 'SNES Emulator')
            new Icon('Calendar', 'Calendar'), new Icon('Clock', 'Clock')
            new Icon('Photos', 'Photo Gallery'), new Icon('Maps', 'Google Maps')
        ]
    
        dockIcons = [
            new DockIcon('Camera', 'Camera')
            new DockIcon('iPod', 'iPod')
            new DockIcon('Calculator', 'Calculator')
        ]
    
        allScreens = $('#allScreens')
    
        # Using the Touchable plugin to listen for
        # touch based events:
    
        allScreens.Touchable();
    
        # Creating a new stage object
        stage = new Stage(allIcons)
    
        stage.addScreensTo(allScreens)
        stage.addIndicatorsTo('#indicators')
    
        # Listening for the touchablemove event.
        # Notice the callback function. Braces on
            # function calls are optional
        allScreens.bind 'touchablemove', (e,touch)->
            stage.next() if touch.currentDelta.x < -5
            stage.previous() if touch.currentDelta.x > 5
    
        # Adding the dock icons:
    
        dock = $('#dock')
    
        for icon in dockIcons
            dock.append(icon.markup)

    Вызывая метод Touchable, мы расширяем элемент до поддержки нескольких событий, вызванный касаниями. Среди них можно выделить touchablemove, который выполняет когда пользователь двигает пальцем по экрану. Он также запускается, когда мы перетаскиваем курсор мыши. Далее, когда мы закрепляем этот жест к событию, у нас в качестве второго аргумента функции обратного вызова получается touch-объект. Он удерживает фигуру, либо разность от самого начала движения.На этом наш экран загрузки на подобии iOS готов!

    Вывод

    CoffeeScript – интересный язык, который может сделать разработку для браузера легче. Можете рассчитывать на то, что кода придется писать на 50% меньше, чем в чистом javascript.Хотя вряд ли можно сказать, что CoffeeScript вскоре может заменить javascript, так как данная система жертвует возможностями в целях облегчения кода. CS вероятно не подойдет для всех ваших проектов.CoffeeScript также предлагает вам дополнительный этап компиляции, который оградит вас от кода, но это можно решить с помощью веб-платформ, которые скомпилируют для вас код в rails, где CS идет по умолчанию.

    Исходники, как всегда в архиве!