Repository files navigation

ti.scroller

Description

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

  • You can create multiple scrolling views and customize them separately
  • Each scrolling view can display one or multiple messages, cycle between them or display them in random order
  • You can update its content at any time ( messages, color, position, delay, etc. )
  • Works with Android & iOS

What's new in v1.2.0

New destroy() method

Every scrolling view is kept in an internal registry so the library can pause/resume all of them when the app goes to the background. Starting with v1.2.0, call destroy() when you close the window that contains a scrolling view, so it gets released from that registry ( otherwise it stays retained for the lifetime of the app ):

win.addEventListener('close',()=>{scrollingMessage.destroy()})

New on() method: paused, resumed and complete events

You can now assign a callback for the paused, resumed and complete events. The callback receives the scrolling view instance:

scrollingMessage.on('complete',(source)=>{// Fired every time a message finishes scrolling})

play() now always plays

play() starts playback even if autoplay is set to false. The autoplay property now only controls automatic starts ( at creation and when setting new messages ).

animate() ( deprecated ) works again

In v1.1.0 the deprecated animate() method became a no-op. It now behaves like play() again, but it will still be deleted in v2.0.0, so use play() instead.

Bug fixes

  • pause() now sticks: pausing during the delay window between messages is no longer reverted by an internal timer.
  • Fixed a race condition that could start two scrolling loops at once when updating messages mid-cycle.
  • The automatic pause/resume on app background/foreground now respects manual pauses: if you paused a scrolling view yourself, it won't auto-resume when the app comes back to the foreground.
  • The | separator for multiple messages in a single string now works everywhere ( it was documented for Alloy but not implemented ).
  • Boolean attributes set from Alloy XML ( autoplay="false", random="false", debug="true" ) now work as expected.
  • Colors in #AARRGGBB format are handled correctly by the side label's darkened background ( the default #BF000000 no longer renders red ).
  • random can now be turned off with update({ random: false }), restoring the original message order.
  • update() called without arguments no longer throws, and update({ speed: 0 }) is ignored instead of freezing the scroller.
  • The messages array you pass is no longer mutated when using random.
  • Message widths are cached per text, so repeated cycles no longer re-measure the same message.
  • updateLabel() now creates the side label on the fly if the scrolling view didn't have one ( as it was always documented ).

Breaking changes in v1.1.0

Autoplaying scrolling views

Each scrolling view will start playing immediately after initialization if either message or messages properties are set.

This means that you no longer need to call the animate() method ( now deprecated ) after initialization.

They won't autoplay if there is no message set at initialization, this is useful when you need to get the data from the internet. They will start playing the moment you set a new message(s) with update() or updateMessage/Messages() methods.

If you set the message(s) property and still don't want the scrolling views to start playing immediately, set the new autoplay property to false.

Then use the play() method ( or resume() ) to start playing the scrolling view when needed. Since v1.2.0, play() starts playback even if autoplay is false. You only need to set autoplay back to true if you want new messages set with update() / updateMessage(s)() to start playing automatically.

New <ScrollingView /> Alloy element

In order to be more like a native Ti element in Alloy projects, you now create your scrolling views with the <ScrollingView> element provided by ti.scroller.js

<ScrollingViewmodule='ti.scroller' ... />

paused and resume App Events

The library listens to the Ti.App lifecycle events paused and resume, so you no longer need to handle them manually. They will pause/resume every scrolling view created in your app.

animate() method Deprecated

The animate() method is deprecated and will be deleted in the future.

Installation in Classic Apps

For Classic Apps, put ti.scroller.js file inside the Resources folder.

Basic usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller lib',backgroundColor: '#fff'})letscrollingMessage=newScrollingView({message: 'Appcelerator Titanium: Everything you need to create great, native mobile apps — All from a single JavaScript code base.'})win.add(scrollingMessage.getView())win.open()

Result

iOS Screen - Example

* low framerate gif

Advanced usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller',backgroundColor: '#fff'})letcontainer=Ti.UI.createView({layout: 'vertical',height: Ti.UI.SIZE})letfamousPeopleQuotes=newScrollingView({top: 8,speed: 7,random: true,color: '#dddfe1',label: 'Famous People:',backgroundColor: '#53606b',messages: ['The greatest glory in living lies not in never falling, but in rising every time we fall. - Nelson Mandela','The way to get started is to quit talking and begin doing. - Walt Disney','Your time is limited, so don\'t waste it living someone else\'s life. Don\'t be trapped by dogma – which is living with the results of other people\'s thinking. - Steve Jobs','If life were predictable it would cease to be life, and be without flavor. - Eleanor Roosevelt','If you look at what you have in life, you\'ll always have more. If you look at what you don\'t have in life, you\'ll never have enough. - Oprah Winfrey','If you set your goals ridiculously high and it\'s a failure, you will fail above everyone else\'s success. - James Cameron','Life is what happens when you\'re busy making other plans. - John Lennon']})letbestQuotesOfAllTimes=newScrollingView({top: 8,speed: 6,label: 'Best Quotes:',backgroundColor: '#79a342',messages: ['Whoever is happy will make others happy too. - Anne Frank','It is during our darkest moments that we must focus to see the light. - Aristotle','Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead','Spread love everywhere you go. Let no one ever come to you without leaving happier. - Mother Teresa','When you reach the end of your rope, tie a knot in it and hang on. - Franklin D. Roosevelt','Don\'t judge each day by the harvest you reap but by the seeds that you plant. - Robert Louis Stevenson','The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt','Tell me and I forget. Teach me and I remember. Involve me and I learn. - Benjamin Franklin','The best and most beautiful things in the world cannot be seen or even touched — they must be felt with the heart. - Helen Keller','Do not go where the path may lead, go instead where there is no path and leave a trail. - Ralph Waldo Emerson']})letmarketStocks=newScrollingView({top: 8,speed: 8,height: 36,debug: true,label: 'Market:',name: 'Market Stocks',message: 'Loading data...',backgroundColor: '#F3650C'})// Simulated API responsesetTimeout(()=>{// Just set the new message(s) with `updateMessages` methodmarketStocks.updateMessages('EUR/USD 1.18664 0 0% · USD/JPY 110.399 0.06 0.05% · GBP/USD 1.38902 0 0% · EUR/JPY 130.9959 0.109 0.08% · GBP/JPY 153.3323 0.116 0.08% · USD/CAD 1.24481 -0.001 -0.08% · XAU/USD 1806.7484 -0.684 -0.04% · AUD/USD 0.74878 0.001 0.13% · USD/CHF 0.91462 -0.001 -0.11% · NZD/USD 0.69921 0.001 0.14%')},3000)container.add(famousPeopleQuotes.getView())container.add(bestQuotesOfAllTimes.getView())container.add(marketStocks.getView())win.add(container)win.open()

Result

iOS Screen - Example

* low framerate gif

Installation in Alloy Apps

For Alloy projects drop ti.scroller in /app/lib folder.

app
└─ lib
└─ ti.scroller.js

In your View file, create a ScrollingView Alloy element and add a module attribute like this module="ti.scroller".

You can set any of the supported attributes directly in the ScrollingView.

IMPORTANT: For multiple messages you'll need to separate them with the | symbol like shown below.

<Alloy>
<NavigationWindow>
<Windowtitle="ti.scroller">
<ScrollingViewid="scrollingMessage"module='ti.scroller'backgroundColor="#c91326"label="Famous Quotes:"speed="4"delay="2"height="32"random="true"top="0" font.fontFamily="Gill Sans" font.fontWeight="semibold" font.fontSize="16"message="Whoever is happy will make others happy too. - Anne Frank|It is during our darkest moments that we must focus to see the light. - Aristotle|Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead" />
</Window>
</NavigationWindow>
</Alloy>

Result

iOS Screen - Example

* low framerate gif

In your controller you can call any of the available methods: update, updateLabel, updateMessage/updateMessages, updateBackground, play, pause, resume, destroy or on at anytime.

$.scrollingMessage.update({top: 48,delay: 3,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform'})

Important consideration

To prevent unexpected behaviors, the library itself listens to the following Ti.App events, so you don't need to add any listener:

  • paused event: In order to pause the scrolling effect while the app is in the background
  • resume event: To resume scrolling when in the foreground.

They will handle every scrolling view created in your app. Since v1.2.0, a scrolling view that you paused manually stays paused when the app comes back to the foreground.

Remember to call destroy() when closing a window that contains scrolling views, so they get released from the internal registry:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

Customization

You can customize the text color, background color, vertical position, font size, font weight, font family, scrolling speed, delay between messages, autoplay messages, random order display, side label text, name and debug mode with the following properties:

  • id
  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • shadow
  • autoplay
  • top/bottom
  • backgroundColor
  • message/messages
  • font object with fontSize, fontWeight, fontFamily

Content Properties

message/messages : array/string

The text to display can be set with message or messages property using an array ( for a single message you can set it using a string ).

You can also pass multiple messages in a single string by separating them with the | symbol. This is how multiple messages are set from Alloy XML, and since v1.2.0 it also works in JavaScript:

letscrollingMessage=newScrollingView({message: 'First message|Second message|Third message',
...
})
letscrollingMessage=newScrollingView({messages: ['Every moment is a fresh beginning. – T.S Eliot','Change the world by being yourself. – Amy Poehler','Love For All, Hatred For None. – Khalifatul Masih III'],
...
})

label : string

To display a left-side label set the label property.

The side label text is always bold, on a slightly darker shade of the scrolling view's backgroundColor.

Defaults to: null

letscrollingMessage=newScrollingView({label: 'Breaking News:',
...
})

Design Properties

color : string

Color for the text message(s) and side label in hex value.

Defaults to: #fff

letscrollingMessage=newScrollingView({color: '#79a342',
...
})

backgroundColor : string

Background color for the scrolling view, as a hex triplet.

Defaults to: #BF000000

letscrollingMessage=newScrollingView({backgroundColor: '#53606b',
...
})

height : number/string

ScrollingView height, in platform-specific units.

Defaults to: 28 ( platform default units )

letscrollingMessage=newScrollingView({height: 44...})

shadow : boolean

Set shadow to true to display a drop shadow under the scrolling view.

Defaults to: false

letscrollingMessage=newScrollingView({shadow: true,
...
})

Font Object

Set a font object to set the following properties:

fontFamily: string

Specifies the font family or specific font to use.

Defaults: Uses the default system font

fontSize: Number/String

Font size, in platform-dependent units.

Defaults: 14dp

fontWeight: string

Font weight. Valid values are "bold", "semibold", "normal", "thin", "light" and "ultralight".

The "semibold", "thin", "light" and "ultralight" weights are recognized on iOS only. "thin", "light" and "ultralight" are only available on iOS 8.2 and later.

Defaults: normal

letscrollingMessage=newScrollingView({font: {fontSize: 16,fontWeight: 'bold',fontFamily: 'Gill Sans'}...})

Positioning Properties

top or bottom : number/string

The scrolling view's top OR bottom position. This position is relative to the scrolling view's parent.

You can use px, % or dp values.

Defaults to: undefined

letscrollingMessage=newScrollingView({top: 44,// ORbottom: 0...})

Behavior properties

autoplay : boolean

You can turn off automatic playing by setting the autoplay property to false.

Defaults to: true

letscrollingMessage=newScrollingView({autoplay: false,
...
})

delay : number

Pause the animation between messages in seconds.

Defaults to: 0

letscrollingMessage=newScrollingView({delay: 3,
...
})

speed : number

The speed of the scrolling text, a constant speed no matter the text length, the higher the number the faster the scrolling speed.

Only values greater than 0 are accepted; 0 and negative values are ignored.

Defaults to: 5

letscrollingMessage=newScrollingView({speed: 7,
...
})

random : boolean

To display the messages in random order set random to true.

Since v1.2.0 you can turn it off at any time with update({ random: false }), which restores the original message order.

Defaults to: false

letscrollingMessage=newScrollingView({random: true,
...
})

Update Methods

There are 4 methods to update the content and properties at any time.

  • update()
  • updateLabel()
  • updateBackground()
  • updateMessage() or updateMessages()

update

Is a general purpose method to change any or all of the following properties:

  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • autoplay
  • top or bottom
  • backgroundColor
  • message or messages
  • font object with fontSize, fontWeight, fontFamily

When updating the message ( or messages ), the text will be shown after completing the currently running message.

scrollingMessage.update({top: 0,delay: 0,speed: 10,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform',font: {fontWeight: 'bold'}})

updateMessage/updateMessages

If you need to update only the message or messages, you can use the updateMessage or updateMessages methods.

You can use either of them with a string or an array. A string with | separators is split into multiple messages. Calling them with an empty string or an empty array returns false and keeps the current messages.

The updated text will be shown after completing the currently running message.

scrollingMessage.updateMessage('Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform')scrollingMessage.updateMessages(['Build: Write in JavaScript, run native on any device and OS','Connect: Get mobile-optimized access to any data source','Measure: See usage & adoption, detect crashes, tune performance'])

updateLabel

This method will instantly update the label property.

If the scrolling view does not originally contained a label, it will be add it automatically.

scrollingMessage.updateLabel('Breaking News:')

updateBackground

Use it to change the scrolling view's background color, including the label property if available.

scrollingMessage.updateBackground('#79a342')

Playback & Lifecycle Methods

play

Starts playing the scrolling view. Since v1.2.0 it works even if autoplay is set to false ( autoplay only controls automatic starts ). If a message is already scrolling, calling it again has no effect.

scrollingMessage.play()

pause

Pauses the scrolling view. The message currently on screen finishes its scroll, and no further messages are played until you call play() or resume().

scrollingMessage.pause()

resume

Resumes a paused scrolling view.

scrollingMessage.resume()

destroy

Releases the scrolling view from the library's internal registry ( used for the automatic pause/resume on app background/foreground ) and cancels any pending timers. Call it when closing the window that contains the scrolling view:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

getView

Returns the actual Ti.UI.View so you can add it to your layout ( Classic projects ):

win.add(scrollingMessage.getView())

Events

on( eventName, callback )

Assigns a callback for the paused, resumed and complete events. The callback receives the scrolling view instance as its only argument.

  • paused: fired when the scrolling view is paused ( manually or automatically when the app goes to the background )
  • resumed: fired when the scrolling view is resumed
  • complete: fired every time a message finishes scrolling
scrollingMessage.on('complete',(source)=>{console.log('A message finished scrolling')})scrollingMessage.on('paused',(source)=>{console.log('The scrolling view was paused')})

Debug Mode

name : string

In order to identify each Scrolling View while debuging, you can set the name property at initialization.

letscrollingMessage=newScrollingView({name: 'My Scrolling View',
...
})
<ScrollingViewid="scrollingMessage"module='ti.scroller'name="My Scrolling View" />

When you enable debug mode you'll see multiple outputs with the name of the Scrolling View.

[WARN] ::ti.scroller:: My Scrolling View: Add side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view’s label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view[WARN] ::ti.scroller:: My Scrolling View: Play method[WARN] ::ti.scroller:: My Scrolling View: Update messages method[WARN] ::ti.scroller:: My Scrolling View: Complete event[WARN] ::ti.scroller:: My Scrolling View: Play method

If no name is set, the output will be its id, and if none is set, it will generate an internal one.

debug : bollean

You can debug the scrolling view by setting the debug property to true at initialization or with the update() method.

Defaults to: false

letscrollingMessage=newScrollingView({debug: true,
...
})// ORscrollingMessage.update({debug: true})
<ScrollingViewid="scrollingMessage"module='ti.scroller'debug="true" />

To turn it off

scrollingMessage.update({debug: false})// OR$.scrollingMessage.update({debug: false})

License

Copyright 2021 César Estrada
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

About

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

Topics

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

ti.scroller

Description

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

  • You can create multiple scrolling views and customize them separately
  • Each scrolling view can display one or multiple messages, cycle between them or display them in random order
  • You can update its content at any time ( messages, color, position, delay, etc. )
  • Works with Android & iOS

What's new in v1.2.0

New destroy() method

Every scrolling view is kept in an internal registry so the library can pause/resume all of them when the app goes to the background. Starting with v1.2.0, call destroy() when you close the window that contains a scrolling view, so it gets released from that registry ( otherwise it stays retained for the lifetime of the app ):

win.addEventListener('close',()=>{scrollingMessage.destroy()})

New on() method: paused, resumed and complete events

You can now assign a callback for the paused, resumed and complete events. The callback receives the scrolling view instance:

scrollingMessage.on('complete',(source)=>{// Fired every time a message finishes scrolling})

play() now always plays

play() starts playback even if autoplay is set to false. The autoplay property now only controls automatic starts ( at creation and when setting new messages ).

animate() ( deprecated ) works again

In v1.1.0 the deprecated animate() method became a no-op. It now behaves like play() again, but it will still be deleted in v2.0.0, so use play() instead.

Bug fixes

  • pause() now sticks: pausing during the delay window between messages is no longer reverted by an internal timer.
  • Fixed a race condition that could start two scrolling loops at once when updating messages mid-cycle.
  • The automatic pause/resume on app background/foreground now respects manual pauses: if you paused a scrolling view yourself, it won't auto-resume when the app comes back to the foreground.
  • The | separator for multiple messages in a single string now works everywhere ( it was documented for Alloy but not implemented ).
  • Boolean attributes set from Alloy XML ( autoplay="false", random="false", debug="true" ) now work as expected.
  • Colors in #AARRGGBB format are handled correctly by the side label's darkened background ( the default #BF000000 no longer renders red ).
  • random can now be turned off with update({ random: false }), restoring the original message order.
  • update() called without arguments no longer throws, and update({ speed: 0 }) is ignored instead of freezing the scroller.
  • The messages array you pass is no longer mutated when using random.
  • Message widths are cached per text, so repeated cycles no longer re-measure the same message.
  • updateLabel() now creates the side label on the fly if the scrolling view didn't have one ( as it was always documented ).

Breaking changes in v1.1.0

Autoplaying scrolling views

Each scrolling view will start playing immediately after initialization if either message or messages properties are set.

This means that you no longer need to call the animate() method ( now deprecated ) after initialization.

They won't autoplay if there is no message set at initialization, this is useful when you need to get the data from the internet. They will start playing the moment you set a new message(s) with update() or updateMessage/Messages() methods.

If you set the message(s) property and still don't want the scrolling views to start playing immediately, set the new autoplay property to false.

Then use the play() method ( or resume() ) to start playing the scrolling view when needed. Since v1.2.0, play() starts playback even if autoplay is false. You only need to set autoplay back to true if you want new messages set with update() / updateMessage(s)() to start playing automatically.

New <ScrollingView /> Alloy element

In order to be more like a native Ti element in Alloy projects, you now create your scrolling views with the <ScrollingView> element provided by ti.scroller.js

<ScrollingViewmodule='ti.scroller' ... />

paused and resume App Events

The library listens to the Ti.App lifecycle events paused and resume, so you no longer need to handle them manually. They will pause/resume every scrolling view created in your app.

animate() method Deprecated

The animate() method is deprecated and will be deleted in the future.

Installation in Classic Apps

For Classic Apps, put ti.scroller.js file inside the Resources folder.

Basic usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller lib',backgroundColor: '#fff'})letscrollingMessage=newScrollingView({message: 'Appcelerator Titanium: Everything you need to create great, native mobile apps — All from a single JavaScript code base.'})win.add(scrollingMessage.getView())win.open()

Result

iOS Screen - Example

* low framerate gif

Advanced usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller',backgroundColor: '#fff'})letcontainer=Ti.UI.createView({layout: 'vertical',height: Ti.UI.SIZE})letfamousPeopleQuotes=newScrollingView({top: 8,speed: 7,random: true,color: '#dddfe1',label: 'Famous People:',backgroundColor: '#53606b',messages: ['The greatest glory in living lies not in never falling, but in rising every time we fall. - Nelson Mandela','The way to get started is to quit talking and begin doing. - Walt Disney','Your time is limited, so don\'t waste it living someone else\'s life. Don\'t be trapped by dogma – which is living with the results of other people\'s thinking. - Steve Jobs','If life were predictable it would cease to be life, and be without flavor. - Eleanor Roosevelt','If you look at what you have in life, you\'ll always have more. If you look at what you don\'t have in life, you\'ll never have enough. - Oprah Winfrey','If you set your goals ridiculously high and it\'s a failure, you will fail above everyone else\'s success. - James Cameron','Life is what happens when you\'re busy making other plans. - John Lennon']})letbestQuotesOfAllTimes=newScrollingView({top: 8,speed: 6,label: 'Best Quotes:',backgroundColor: '#79a342',messages: ['Whoever is happy will make others happy too. - Anne Frank','It is during our darkest moments that we must focus to see the light. - Aristotle','Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead','Spread love everywhere you go. Let no one ever come to you without leaving happier. - Mother Teresa','When you reach the end of your rope, tie a knot in it and hang on. - Franklin D. Roosevelt','Don\'t judge each day by the harvest you reap but by the seeds that you plant. - Robert Louis Stevenson','The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt','Tell me and I forget. Teach me and I remember. Involve me and I learn. - Benjamin Franklin','The best and most beautiful things in the world cannot be seen or even touched — they must be felt with the heart. - Helen Keller','Do not go where the path may lead, go instead where there is no path and leave a trail. - Ralph Waldo Emerson']})letmarketStocks=newScrollingView({top: 8,speed: 8,height: 36,debug: true,label: 'Market:',name: 'Market Stocks',message: 'Loading data...',backgroundColor: '#F3650C'})// Simulated API responsesetTimeout(()=>{// Just set the new message(s) with `updateMessages` methodmarketStocks.updateMessages('EUR/USD 1.18664 0 0% · USD/JPY 110.399 0.06 0.05% · GBP/USD 1.38902 0 0% · EUR/JPY 130.9959 0.109 0.08% · GBP/JPY 153.3323 0.116 0.08% · USD/CAD 1.24481 -0.001 -0.08% · XAU/USD 1806.7484 -0.684 -0.04% · AUD/USD 0.74878 0.001 0.13% · USD/CHF 0.91462 -0.001 -0.11% · NZD/USD 0.69921 0.001 0.14%')},3000)container.add(famousPeopleQuotes.getView())container.add(bestQuotesOfAllTimes.getView())container.add(marketStocks.getView())win.add(container)win.open()

Result

iOS Screen - Example

* low framerate gif

Installation in Alloy Apps

For Alloy projects drop ti.scroller in /app/lib folder.

app
└─ lib
└─ ti.scroller.js

In your View file, create a ScrollingView Alloy element and add a module attribute like this module="ti.scroller".

You can set any of the supported attributes directly in the ScrollingView.

IMPORTANT: For multiple messages you'll need to separate them with the | symbol like shown below.

<Alloy>
<NavigationWindow>
<Windowtitle="ti.scroller">
<ScrollingViewid="scrollingMessage"module='ti.scroller'backgroundColor="#c91326"label="Famous Quotes:"speed="4"delay="2"height="32"random="true"top="0" font.fontFamily="Gill Sans" font.fontWeight="semibold" font.fontSize="16"message="Whoever is happy will make others happy too. - Anne Frank|It is during our darkest moments that we must focus to see the light. - Aristotle|Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead" />
</Window>
</NavigationWindow>
</Alloy>

Result

iOS Screen - Example

* low framerate gif

In your controller you can call any of the available methods: update, updateLabel, updateMessage/updateMessages, updateBackground, play, pause, resume, destroy or on at anytime.

$.scrollingMessage.update({top: 48,delay: 3,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform'})

Important consideration

To prevent unexpected behaviors, the library itself listens to the following Ti.App events, so you don't need to add any listener:

  • paused event: In order to pause the scrolling effect while the app is in the background
  • resume event: To resume scrolling when in the foreground.

They will handle every scrolling view created in your app. Since v1.2.0, a scrolling view that you paused manually stays paused when the app comes back to the foreground.

Remember to call destroy() when closing a window that contains scrolling views, so they get released from the internal registry:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

Customization

You can customize the text color, background color, vertical position, font size, font weight, font family, scrolling speed, delay between messages, autoplay messages, random order display, side label text, name and debug mode with the following properties:

  • id
  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • shadow
  • autoplay
  • top/bottom
  • backgroundColor
  • message/messages
  • font object with fontSize, fontWeight, fontFamily

Content Properties

message/messages : array/string

The text to display can be set with message or messages property using an array ( for a single message you can set it using a string ).

You can also pass multiple messages in a single string by separating them with the | symbol. This is how multiple messages are set from Alloy XML, and since v1.2.0 it also works in JavaScript:

letscrollingMessage=newScrollingView({message: 'First message|Second message|Third message',
...
})
letscrollingMessage=newScrollingView({messages: ['Every moment is a fresh beginning. – T.S Eliot','Change the world by being yourself. – Amy Poehler','Love For All, Hatred For None. – Khalifatul Masih III'],
...
})

label : string

To display a left-side label set the label property.

The side label text is always bold, on a slightly darker shade of the scrolling view's backgroundColor.

Defaults to: null

letscrollingMessage=newScrollingView({label: 'Breaking News:',
...
})

Design Properties

color : string

Color for the text message(s) and side label in hex value.

Defaults to: #fff

letscrollingMessage=newScrollingView({color: '#79a342',
...
})

backgroundColor : string

Background color for the scrolling view, as a hex triplet.

Defaults to: #BF000000

letscrollingMessage=newScrollingView({backgroundColor: '#53606b',
...
})

height : number/string

ScrollingView height, in platform-specific units.

Defaults to: 28 ( platform default units )

letscrollingMessage=newScrollingView({height: 44...})

shadow : boolean

Set shadow to true to display a drop shadow under the scrolling view.

Defaults to: false

letscrollingMessage=newScrollingView({shadow: true,
...
})

Font Object

Set a font object to set the following properties:

fontFamily: string

Specifies the font family or specific font to use.

Defaults: Uses the default system font

fontSize: Number/String

Font size, in platform-dependent units.

Defaults: 14dp

fontWeight: string

Font weight. Valid values are "bold", "semibold", "normal", "thin", "light" and "ultralight".

The "semibold", "thin", "light" and "ultralight" weights are recognized on iOS only. "thin", "light" and "ultralight" are only available on iOS 8.2 and later.

Defaults: normal

letscrollingMessage=newScrollingView({font: {fontSize: 16,fontWeight: 'bold',fontFamily: 'Gill Sans'}...})

Positioning Properties

top or bottom : number/string

The scrolling view's top OR bottom position. This position is relative to the scrolling view's parent.

You can use px, % or dp values.

Defaults to: undefined

letscrollingMessage=newScrollingView({top: 44,// ORbottom: 0...})

Behavior properties

autoplay : boolean

You can turn off automatic playing by setting the autoplay property to false.

Defaults to: true

letscrollingMessage=newScrollingView({autoplay: false,
...
})

delay : number

Pause the animation between messages in seconds.

Defaults to: 0

letscrollingMessage=newScrollingView({delay: 3,
...
})

speed : number

The speed of the scrolling text, a constant speed no matter the text length, the higher the number the faster the scrolling speed.

Only values greater than 0 are accepted; 0 and negative values are ignored.

Defaults to: 5

letscrollingMessage=newScrollingView({speed: 7,
...
})

random : boolean

To display the messages in random order set random to true.

Since v1.2.0 you can turn it off at any time with update({ random: false }), which restores the original message order.

Defaults to: false

letscrollingMessage=newScrollingView({random: true,
...
})

Update Methods

There are 4 methods to update the content and properties at any time.

  • update()
  • updateLabel()
  • updateBackground()
  • updateMessage() or updateMessages()

update

Is a general purpose method to change any or all of the following properties:

  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • autoplay
  • top or bottom
  • backgroundColor
  • message or messages
  • font object with fontSize, fontWeight, fontFamily

When updating the message ( or messages ), the text will be shown after completing the currently running message.

scrollingMessage.update({top: 0,delay: 0,speed: 10,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform',font: {fontWeight: 'bold'}})

updateMessage/updateMessages

If you need to update only the message or messages, you can use the updateMessage or updateMessages methods.

You can use either of them with a string or an array. A string with | separators is split into multiple messages. Calling them with an empty string or an empty array returns false and keeps the current messages.

The updated text will be shown after completing the currently running message.

scrollingMessage.updateMessage('Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform')scrollingMessage.updateMessages(['Build: Write in JavaScript, run native on any device and OS','Connect: Get mobile-optimized access to any data source','Measure: See usage & adoption, detect crashes, tune performance'])

updateLabel

This method will instantly update the label property.

If the scrolling view does not originally contained a label, it will be add it automatically.

scrollingMessage.updateLabel('Breaking News:')

updateBackground

Use it to change the scrolling view's background color, including the label property if available.

scrollingMessage.updateBackground('#79a342')

Playback & Lifecycle Methods

play

Starts playing the scrolling view. Since v1.2.0 it works even if autoplay is set to false ( autoplay only controls automatic starts ). If a message is already scrolling, calling it again has no effect.

scrollingMessage.play()

pause

Pauses the scrolling view. The message currently on screen finishes its scroll, and no further messages are played until you call play() or resume().

scrollingMessage.pause()

resume

Resumes a paused scrolling view.

scrollingMessage.resume()

destroy

Releases the scrolling view from the library's internal registry ( used for the automatic pause/resume on app background/foreground ) and cancels any pending timers. Call it when closing the window that contains the scrolling view:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

getView

Returns the actual Ti.UI.View so you can add it to your layout ( Classic projects ):

win.add(scrollingMessage.getView())

Events

on( eventName, callback )

Assigns a callback for the paused, resumed and complete events. The callback receives the scrolling view instance as its only argument.

  • paused: fired when the scrolling view is paused ( manually or automatically when the app goes to the background )
  • resumed: fired when the scrolling view is resumed
  • complete: fired every time a message finishes scrolling
scrollingMessage.on('complete',(source)=>{console.log('A message finished scrolling')})scrollingMessage.on('paused',(source)=>{console.log('The scrolling view was paused')})

Debug Mode

name : string

In order to identify each Scrolling View while debuging, you can set the name property at initialization.

letscrollingMessage=newScrollingView({name: 'My Scrolling View',
...
})
<ScrollingViewid="scrollingMessage"module='ti.scroller'name="My Scrolling View" />

When you enable debug mode you'll see multiple outputs with the name of the Scrolling View.

[WARN] ::ti.scroller:: My Scrolling View: Add side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view’s label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view[WARN] ::ti.scroller:: My Scrolling View: Play method[WARN] ::ti.scroller:: My Scrolling View: Update messages method[WARN] ::ti.scroller:: My Scrolling View: Complete event[WARN] ::ti.scroller:: My Scrolling View: Play method

If no name is set, the output will be its id, and if none is set, it will generate an internal one.

debug : bollean

You can debug the scrolling view by setting the debug property to true at initialization or with the update() method.

Defaults to: false

letscrollingMessage=newScrollingView({debug: true,
...
})// ORscrollingMessage.update({debug: true})
<ScrollingViewid="scrollingMessage"module='ti.scroller'debug="true" />

To turn it off

scrollingMessage.update({debug: false})// OR$.scrollingMessage.update({debug: false})

License

Copyright 2021 César Estrada
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

About

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

Topics

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ti.scroller

Description

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

  • You can create multiple scrolling views and customize them separately
  • Each scrolling view can display one or multiple messages, cycle between them or display them in random order
  • You can update its content at any time ( messages, color, position, delay, etc. )
  • Works with Android & iOS

What's new in v1.2.0

New destroy() method

Every scrolling view is kept in an internal registry so the library can pause/resume all of them when the app goes to the background. Starting with v1.2.0, call destroy() when you close the window that contains a scrolling view, so it gets released from that registry ( otherwise it stays retained for the lifetime of the app ):

win.addEventListener('close',()=>{scrollingMessage.destroy()})

New on() method: paused, resumed and complete events

You can now assign a callback for the paused, resumed and complete events. The callback receives the scrolling view instance:

scrollingMessage.on('complete',(source)=>{// Fired every time a message finishes scrolling})

play() now always plays

play() starts playback even if autoplay is set to false. The autoplay property now only controls automatic starts ( at creation and when setting new messages ).

animate() ( deprecated ) works again

In v1.1.0 the deprecated animate() method became a no-op. It now behaves like play() again, but it will still be deleted in v2.0.0, so use play() instead.

Bug fixes

  • pause() now sticks: pausing during the delay window between messages is no longer reverted by an internal timer.
  • Fixed a race condition that could start two scrolling loops at once when updating messages mid-cycle.
  • The automatic pause/resume on app background/foreground now respects manual pauses: if you paused a scrolling view yourself, it won't auto-resume when the app comes back to the foreground.
  • The | separator for multiple messages in a single string now works everywhere ( it was documented for Alloy but not implemented ).
  • Boolean attributes set from Alloy XML ( autoplay="false", random="false", debug="true" ) now work as expected.
  • Colors in #AARRGGBB format are handled correctly by the side label's darkened background ( the default #BF000000 no longer renders red ).
  • random can now be turned off with update({ random: false }), restoring the original message order.
  • update() called without arguments no longer throws, and update({ speed: 0 }) is ignored instead of freezing the scroller.
  • The messages array you pass is no longer mutated when using random.
  • Message widths are cached per text, so repeated cycles no longer re-measure the same message.
  • updateLabel() now creates the side label on the fly if the scrolling view didn't have one ( as it was always documented ).

Breaking changes in v1.1.0

Autoplaying scrolling views

Each scrolling view will start playing immediately after initialization if either message or messages properties are set.

This means that you no longer need to call the animate() method ( now deprecated ) after initialization.

They won't autoplay if there is no message set at initialization, this is useful when you need to get the data from the internet. They will start playing the moment you set a new message(s) with update() or updateMessage/Messages() methods.

If you set the message(s) property and still don't want the scrolling views to start playing immediately, set the new autoplay property to false.

Then use the play() method ( or resume() ) to start playing the scrolling view when needed. Since v1.2.0, play() starts playback even if autoplay is false. You only need to set autoplay back to true if you want new messages set with update() / updateMessage(s)() to start playing automatically.

New <ScrollingView /> Alloy element

In order to be more like a native Ti element in Alloy projects, you now create your scrolling views with the <ScrollingView> element provided by ti.scroller.js

<ScrollingViewmodule='ti.scroller' ... />

paused and resume App Events

The library listens to the Ti.App lifecycle events paused and resume, so you no longer need to handle them manually. They will pause/resume every scrolling view created in your app.

animate() method Deprecated

The animate() method is deprecated and will be deleted in the future.

Installation in Classic Apps

For Classic Apps, put ti.scroller.js file inside the Resources folder.

Basic usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller lib',backgroundColor: '#fff'})letscrollingMessage=newScrollingView({message: 'Appcelerator Titanium: Everything you need to create great, native mobile apps — All from a single JavaScript code base.'})win.add(scrollingMessage.getView())win.open()

Result

iOS Screen - Example

* low framerate gif

Advanced usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller',backgroundColor: '#fff'})letcontainer=Ti.UI.createView({layout: 'vertical',height: Ti.UI.SIZE})letfamousPeopleQuotes=newScrollingView({top: 8,speed: 7,random: true,color: '#dddfe1',label: 'Famous People:',backgroundColor: '#53606b',messages: ['The greatest glory in living lies not in never falling, but in rising every time we fall. - Nelson Mandela','The way to get started is to quit talking and begin doing. - Walt Disney','Your time is limited, so don\'t waste it living someone else\'s life. Don\'t be trapped by dogma – which is living with the results of other people\'s thinking. - Steve Jobs','If life were predictable it would cease to be life, and be without flavor. - Eleanor Roosevelt','If you look at what you have in life, you\'ll always have more. If you look at what you don\'t have in life, you\'ll never have enough. - Oprah Winfrey','If you set your goals ridiculously high and it\'s a failure, you will fail above everyone else\'s success. - James Cameron','Life is what happens when you\'re busy making other plans. - John Lennon']})letbestQuotesOfAllTimes=newScrollingView({top: 8,speed: 6,label: 'Best Quotes:',backgroundColor: '#79a342',messages: ['Whoever is happy will make others happy too. - Anne Frank','It is during our darkest moments that we must focus to see the light. - Aristotle','Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead','Spread love everywhere you go. Let no one ever come to you without leaving happier. - Mother Teresa','When you reach the end of your rope, tie a knot in it and hang on. - Franklin D. Roosevelt','Don\'t judge each day by the harvest you reap but by the seeds that you plant. - Robert Louis Stevenson','The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt','Tell me and I forget. Teach me and I remember. Involve me and I learn. - Benjamin Franklin','The best and most beautiful things in the world cannot be seen or even touched — they must be felt with the heart. - Helen Keller','Do not go where the path may lead, go instead where there is no path and leave a trail. - Ralph Waldo Emerson']})letmarketStocks=newScrollingView({top: 8,speed: 8,height: 36,debug: true,label: 'Market:',name: 'Market Stocks',message: 'Loading data...',backgroundColor: '#F3650C'})// Simulated API responsesetTimeout(()=>{// Just set the new message(s) with `updateMessages` methodmarketStocks.updateMessages('EUR/USD 1.18664 0 0% · USD/JPY 110.399 0.06 0.05% · GBP/USD 1.38902 0 0% · EUR/JPY 130.9959 0.109 0.08% · GBP/JPY 153.3323 0.116 0.08% · USD/CAD 1.24481 -0.001 -0.08% · XAU/USD 1806.7484 -0.684 -0.04% · AUD/USD 0.74878 0.001 0.13% · USD/CHF 0.91462 -0.001 -0.11% · NZD/USD 0.69921 0.001 0.14%')},3000)container.add(famousPeopleQuotes.getView())container.add(bestQuotesOfAllTimes.getView())container.add(marketStocks.getView())win.add(container)win.open()

Result

iOS Screen - Example

* low framerate gif

Installation in Alloy Apps

For Alloy projects drop ti.scroller in /app/lib folder.

app
└─ lib
└─ ti.scroller.js

In your View file, create a ScrollingView Alloy element and add a module attribute like this module="ti.scroller".

You can set any of the supported attributes directly in the ScrollingView.

IMPORTANT: For multiple messages you'll need to separate them with the | symbol like shown below.

<Alloy>
<NavigationWindow>
<Windowtitle="ti.scroller">
<ScrollingViewid="scrollingMessage"module='ti.scroller'backgroundColor="#c91326"label="Famous Quotes:"speed="4"delay="2"height="32"random="true"top="0" font.fontFamily="Gill Sans" font.fontWeight="semibold" font.fontSize="16"message="Whoever is happy will make others happy too. - Anne Frank|It is during our darkest moments that we must focus to see the light. - Aristotle|Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead" />
</Window>
</NavigationWindow>
</Alloy>

Result

iOS Screen - Example

* low framerate gif

In your controller you can call any of the available methods: update, updateLabel, updateMessage/updateMessages, updateBackground, play, pause, resume, destroy or on at anytime.

$.scrollingMessage.update({top: 48,delay: 3,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform'})

Important consideration

To prevent unexpected behaviors, the library itself listens to the following Ti.App events, so you don't need to add any listener:

  • paused event: In order to pause the scrolling effect while the app is in the background
  • resume event: To resume scrolling when in the foreground.

They will handle every scrolling view created in your app. Since v1.2.0, a scrolling view that you paused manually stays paused when the app comes back to the foreground.

Remember to call destroy() when closing a window that contains scrolling views, so they get released from the internal registry:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

Customization

You can customize the text color, background color, vertical position, font size, font weight, font family, scrolling speed, delay between messages, autoplay messages, random order display, side label text, name and debug mode with the following properties:

  • id
  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • shadow
  • autoplay
  • top/bottom
  • backgroundColor
  • message/messages
  • font object with fontSize, fontWeight, fontFamily

Content Properties

message/messages : array/string

The text to display can be set with message or messages property using an array ( for a single message you can set it using a string ).

You can also pass multiple messages in a single string by separating them with the | symbol. This is how multiple messages are set from Alloy XML, and since v1.2.0 it also works in JavaScript:

letscrollingMessage=newScrollingView({message: 'First message|Second message|Third message',
...
})
letscrollingMessage=newScrollingView({messages: ['Every moment is a fresh beginning. – T.S Eliot','Change the world by being yourself. – Amy Poehler','Love For All, Hatred For None. – Khalifatul Masih III'],
...
})

label : string

To display a left-side label set the label property.

The side label text is always bold, on a slightly darker shade of the scrolling view's backgroundColor.

Defaults to: null

letscrollingMessage=newScrollingView({label: 'Breaking News:',
...
})

Design Properties

color : string

Color for the text message(s) and side label in hex value.

Defaults to: #fff

letscrollingMessage=newScrollingView({color: '#79a342',
...
})

backgroundColor : string

Background color for the scrolling view, as a hex triplet.

Defaults to: #BF000000

letscrollingMessage=newScrollingView({backgroundColor: '#53606b',
...
})

height : number/string

ScrollingView height, in platform-specific units.

Defaults to: 28 ( platform default units )

letscrollingMessage=newScrollingView({height: 44...})

shadow : boolean

Set shadow to true to display a drop shadow under the scrolling view.

Defaults to: false

letscrollingMessage=newScrollingView({shadow: true,
...
})

Font Object

Set a font object to set the following properties:

fontFamily: string

Specifies the font family or specific font to use.

Defaults: Uses the default system font

fontSize: Number/String

Font size, in platform-dependent units.

Defaults: 14dp

fontWeight: string

Font weight. Valid values are "bold", "semibold", "normal", "thin", "light" and "ultralight".

The "semibold", "thin", "light" and "ultralight" weights are recognized on iOS only. "thin", "light" and "ultralight" are only available on iOS 8.2 and later.

Defaults: normal

letscrollingMessage=newScrollingView({font: {fontSize: 16,fontWeight: 'bold',fontFamily: 'Gill Sans'}...})

Positioning Properties

top or bottom : number/string

The scrolling view's top OR bottom position. This position is relative to the scrolling view's parent.

You can use px, % or dp values.

Defaults to: undefined

letscrollingMessage=newScrollingView({top: 44,// ORbottom: 0...})

Behavior properties

autoplay : boolean

You can turn off automatic playing by setting the autoplay property to false.

Defaults to: true

letscrollingMessage=newScrollingView({autoplay: false,
...
})

delay : number

Pause the animation between messages in seconds.

Defaults to: 0

letscrollingMessage=newScrollingView({delay: 3,
...
})

speed : number

The speed of the scrolling text, a constant speed no matter the text length, the higher the number the faster the scrolling speed.

Only values greater than 0 are accepted; 0 and negative values are ignored.

Defaults to: 5

letscrollingMessage=newScrollingView({speed: 7,
...
})

random : boolean

To display the messages in random order set random to true.

Since v1.2.0 you can turn it off at any time with update({ random: false }), which restores the original message order.

Defaults to: false

letscrollingMessage=newScrollingView({random: true,
...
})

Update Methods

There are 4 methods to update the content and properties at any time.

  • update()
  • updateLabel()
  • updateBackground()
  • updateMessage() or updateMessages()

update

Is a general purpose method to change any or all of the following properties:

  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • autoplay
  • top or bottom
  • backgroundColor
  • message or messages
  • font object with fontSize, fontWeight, fontFamily

When updating the message ( or messages ), the text will be shown after completing the currently running message.

scrollingMessage.update({top: 0,delay: 0,speed: 10,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform',font: {fontWeight: 'bold'}})

updateMessage/updateMessages

If you need to update only the message or messages, you can use the updateMessage or updateMessages methods.

You can use either of them with a string or an array. A string with | separators is split into multiple messages. Calling them with an empty string or an empty array returns false and keeps the current messages.

The updated text will be shown after completing the currently running message.

scrollingMessage.updateMessage('Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform')scrollingMessage.updateMessages(['Build: Write in JavaScript, run native on any device and OS','Connect: Get mobile-optimized access to any data source','Measure: See usage & adoption, detect crashes, tune performance'])

updateLabel

This method will instantly update the label property.

If the scrolling view does not originally contained a label, it will be add it automatically.

scrollingMessage.updateLabel('Breaking News:')

updateBackground

Use it to change the scrolling view's background color, including the label property if available.

scrollingMessage.updateBackground('#79a342')

Playback & Lifecycle Methods

play

Starts playing the scrolling view. Since v1.2.0 it works even if autoplay is set to false ( autoplay only controls automatic starts ). If a message is already scrolling, calling it again has no effect.

scrollingMessage.play()

pause

Pauses the scrolling view. The message currently on screen finishes its scroll, and no further messages are played until you call play() or resume().

scrollingMessage.pause()

resume

Resumes a paused scrolling view.

scrollingMessage.resume()

destroy

Releases the scrolling view from the library's internal registry ( used for the automatic pause/resume on app background/foreground ) and cancels any pending timers. Call it when closing the window that contains the scrolling view:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

getView

Returns the actual Ti.UI.View so you can add it to your layout ( Classic projects ):

win.add(scrollingMessage.getView())

Events

on( eventName, callback )

Assigns a callback for the paused, resumed and complete events. The callback receives the scrolling view instance as its only argument.

  • paused: fired when the scrolling view is paused ( manually or automatically when the app goes to the background )
  • resumed: fired when the scrolling view is resumed
  • complete: fired every time a message finishes scrolling
scrollingMessage.on('complete',(source)=>{console.log('A message finished scrolling')})scrollingMessage.on('paused',(source)=>{console.log('The scrolling view was paused')})

Debug Mode

name : string

In order to identify each Scrolling View while debuging, you can set the name property at initialization.

letscrollingMessage=newScrollingView({name: 'My Scrolling View',
...
})
<ScrollingViewid="scrollingMessage"module='ti.scroller'name="My Scrolling View" />

When you enable debug mode you'll see multiple outputs with the name of the Scrolling View.

[WARN] ::ti.scroller:: My Scrolling View: Add side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view’s label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view[WARN] ::ti.scroller:: My Scrolling View: Play method[WARN] ::ti.scroller:: My Scrolling View: Update messages method[WARN] ::ti.scroller:: My Scrolling View: Complete event[WARN] ::ti.scroller:: My Scrolling View: Play method

If no name is set, the output will be its id, and if none is set, it will generate an internal one.

debug : bollean

You can debug the scrolling view by setting the debug property to true at initialization or with the update() method.

Defaults to: false

letscrollingMessage=newScrollingView({debug: true,
...
})// ORscrollingMessage.update({debug: true})
<ScrollingViewid="scrollingMessage"module='ti.scroller'debug="true" />

To turn it off

scrollingMessage.update({debug: false})// OR$.scrollingMessage.update({debug: false})

License

Copyright 2021 César Estrada
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

About

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

Topics

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ti.scroller

Description

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

  • You can create multiple scrolling views and customize them separately
  • Each scrolling view can display one or multiple messages, cycle between them or display them in random order
  • You can update its content at any time ( messages, color, position, delay, etc. )
  • Works with Android & iOS

What's new in v1.2.0

New destroy() method

Every scrolling view is kept in an internal registry so the library can pause/resume all of them when the app goes to the background. Starting with v1.2.0, call destroy() when you close the window that contains a scrolling view, so it gets released from that registry ( otherwise it stays retained for the lifetime of the app ):

win.addEventListener('close',()=>{scrollingMessage.destroy()})

New on() method: paused, resumed and complete events

You can now assign a callback for the paused, resumed and complete events. The callback receives the scrolling view instance:

scrollingMessage.on('complete',(source)=>{// Fired every time a message finishes scrolling})

play() now always plays

play() starts playback even if autoplay is set to false. The autoplay property now only controls automatic starts ( at creation and when setting new messages ).

animate() ( deprecated ) works again

In v1.1.0 the deprecated animate() method became a no-op. It now behaves like play() again, but it will still be deleted in v2.0.0, so use play() instead.

Bug fixes

  • pause() now sticks: pausing during the delay window between messages is no longer reverted by an internal timer.
  • Fixed a race condition that could start two scrolling loops at once when updating messages mid-cycle.
  • The automatic pause/resume on app background/foreground now respects manual pauses: if you paused a scrolling view yourself, it won't auto-resume when the app comes back to the foreground.
  • The | separator for multiple messages in a single string now works everywhere ( it was documented for Alloy but not implemented ).
  • Boolean attributes set from Alloy XML ( autoplay="false", random="false", debug="true" ) now work as expected.
  • Colors in #AARRGGBB format are handled correctly by the side label's darkened background ( the default #BF000000 no longer renders red ).
  • random can now be turned off with update({ random: false }), restoring the original message order.
  • update() called without arguments no longer throws, and update({ speed: 0 }) is ignored instead of freezing the scroller.
  • The messages array you pass is no longer mutated when using random.
  • Message widths are cached per text, so repeated cycles no longer re-measure the same message.
  • updateLabel() now creates the side label on the fly if the scrolling view didn't have one ( as it was always documented ).

Breaking changes in v1.1.0

Autoplaying scrolling views

Each scrolling view will start playing immediately after initialization if either message or messages properties are set.

This means that you no longer need to call the animate() method ( now deprecated ) after initialization.

They won't autoplay if there is no message set at initialization, this is useful when you need to get the data from the internet. They will start playing the moment you set a new message(s) with update() or updateMessage/Messages() methods.

If you set the message(s) property and still don't want the scrolling views to start playing immediately, set the new autoplay property to false.

Then use the play() method ( or resume() ) to start playing the scrolling view when needed. Since v1.2.0, play() starts playback even if autoplay is false. You only need to set autoplay back to true if you want new messages set with update() / updateMessage(s)() to start playing automatically.

New <ScrollingView /> Alloy element

In order to be more like a native Ti element in Alloy projects, you now create your scrolling views with the <ScrollingView> element provided by ti.scroller.js

<ScrollingViewmodule='ti.scroller' ... />

paused and resume App Events

The library listens to the Ti.App lifecycle events paused and resume, so you no longer need to handle them manually. They will pause/resume every scrolling view created in your app.

animate() method Deprecated

The animate() method is deprecated and will be deleted in the future.

Installation in Classic Apps

For Classic Apps, put ti.scroller.js file inside the Resources folder.

Basic usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller lib',backgroundColor: '#fff'})letscrollingMessage=newScrollingView({message: 'Appcelerator Titanium: Everything you need to create great, native mobile apps — All from a single JavaScript code base.'})win.add(scrollingMessage.getView())win.open()

Result

iOS Screen - Example

* low framerate gif

Advanced usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller',backgroundColor: '#fff'})letcontainer=Ti.UI.createView({layout: 'vertical',height: Ti.UI.SIZE})letfamousPeopleQuotes=newScrollingView({top: 8,speed: 7,random: true,color: '#dddfe1',label: 'Famous People:',backgroundColor: '#53606b',messages: ['The greatest glory in living lies not in never falling, but in rising every time we fall. - Nelson Mandela','The way to get started is to quit talking and begin doing. - Walt Disney','Your time is limited, so don\'t waste it living someone else\'s life. Don\'t be trapped by dogma – which is living with the results of other people\'s thinking. - Steve Jobs','If life were predictable it would cease to be life, and be without flavor. - Eleanor Roosevelt','If you look at what you have in life, you\'ll always have more. If you look at what you don\'t have in life, you\'ll never have enough. - Oprah Winfrey','If you set your goals ridiculously high and it\'s a failure, you will fail above everyone else\'s success. - James Cameron','Life is what happens when you\'re busy making other plans. - John Lennon']})letbestQuotesOfAllTimes=newScrollingView({top: 8,speed: 6,label: 'Best Quotes:',backgroundColor: '#79a342',messages: ['Whoever is happy will make others happy too. - Anne Frank','It is during our darkest moments that we must focus to see the light. - Aristotle','Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead','Spread love everywhere you go. Let no one ever come to you without leaving happier. - Mother Teresa','When you reach the end of your rope, tie a knot in it and hang on. - Franklin D. Roosevelt','Don\'t judge each day by the harvest you reap but by the seeds that you plant. - Robert Louis Stevenson','The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt','Tell me and I forget. Teach me and I remember. Involve me and I learn. - Benjamin Franklin','The best and most beautiful things in the world cannot be seen or even touched — they must be felt with the heart. - Helen Keller','Do not go where the path may lead, go instead where there is no path and leave a trail. - Ralph Waldo Emerson']})letmarketStocks=newScrollingView({top: 8,speed: 8,height: 36,debug: true,label: 'Market:',name: 'Market Stocks',message: 'Loading data...',backgroundColor: '#F3650C'})// Simulated API responsesetTimeout(()=>{// Just set the new message(s) with `updateMessages` methodmarketStocks.updateMessages('EUR/USD 1.18664 0 0% · USD/JPY 110.399 0.06 0.05% · GBP/USD 1.38902 0 0% · EUR/JPY 130.9959 0.109 0.08% · GBP/JPY 153.3323 0.116 0.08% · USD/CAD 1.24481 -0.001 -0.08% · XAU/USD 1806.7484 -0.684 -0.04% · AUD/USD 0.74878 0.001 0.13% · USD/CHF 0.91462 -0.001 -0.11% · NZD/USD 0.69921 0.001 0.14%')},3000)container.add(famousPeopleQuotes.getView())container.add(bestQuotesOfAllTimes.getView())container.add(marketStocks.getView())win.add(container)win.open()

Result

iOS Screen - Example

* low framerate gif

Installation in Alloy Apps

For Alloy projects drop ti.scroller in /app/lib folder.

app
└─ lib
└─ ti.scroller.js

In your View file, create a ScrollingView Alloy element and add a module attribute like this module="ti.scroller".

You can set any of the supported attributes directly in the ScrollingView.

IMPORTANT: For multiple messages you'll need to separate them with the | symbol like shown below.

<Alloy>
<NavigationWindow>
<Windowtitle="ti.scroller">
<ScrollingViewid="scrollingMessage"module='ti.scroller'backgroundColor="#c91326"label="Famous Quotes:"speed="4"delay="2"height="32"random="true"top="0" font.fontFamily="Gill Sans" font.fontWeight="semibold" font.fontSize="16"message="Whoever is happy will make others happy too. - Anne Frank|It is during our darkest moments that we must focus to see the light. - Aristotle|Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead" />
</Window>
</NavigationWindow>
</Alloy>

Result

iOS Screen - Example

* low framerate gif

In your controller you can call any of the available methods: update, updateLabel, updateMessage/updateMessages, updateBackground, play, pause, resume, destroy or on at anytime.

$.scrollingMessage.update({top: 48,delay: 3,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform'})

Important consideration

To prevent unexpected behaviors, the library itself listens to the following Ti.App events, so you don't need to add any listener:

  • paused event: In order to pause the scrolling effect while the app is in the background
  • resume event: To resume scrolling when in the foreground.

They will handle every scrolling view created in your app. Since v1.2.0, a scrolling view that you paused manually stays paused when the app comes back to the foreground.

Remember to call destroy() when closing a window that contains scrolling views, so they get released from the internal registry:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

Customization

You can customize the text color, background color, vertical position, font size, font weight, font family, scrolling speed, delay between messages, autoplay messages, random order display, side label text, name and debug mode with the following properties:

  • id
  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • shadow
  • autoplay
  • top/bottom
  • backgroundColor
  • message/messages
  • font object with fontSize, fontWeight, fontFamily

Content Properties

message/messages : array/string

The text to display can be set with message or messages property using an array ( for a single message you can set it using a string ).

You can also pass multiple messages in a single string by separating them with the | symbol. This is how multiple messages are set from Alloy XML, and since v1.2.0 it also works in JavaScript:

letscrollingMessage=newScrollingView({message: 'First message|Second message|Third message',
...
})
letscrollingMessage=newScrollingView({messages: ['Every moment is a fresh beginning. – T.S Eliot','Change the world by being yourself. – Amy Poehler','Love For All, Hatred For None. – Khalifatul Masih III'],
...
})

label : string

To display a left-side label set the label property.

The side label text is always bold, on a slightly darker shade of the scrolling view's backgroundColor.

Defaults to: null

letscrollingMessage=newScrollingView({label: 'Breaking News:',
...
})

Design Properties

color : string

Color for the text message(s) and side label in hex value.

Defaults to: #fff

letscrollingMessage=newScrollingView({color: '#79a342',
...
})

backgroundColor : string

Background color for the scrolling view, as a hex triplet.

Defaults to: #BF000000

letscrollingMessage=newScrollingView({backgroundColor: '#53606b',
...
})

height : number/string

ScrollingView height, in platform-specific units.

Defaults to: 28 ( platform default units )

letscrollingMessage=newScrollingView({height: 44...})

shadow : boolean

Set shadow to true to display a drop shadow under the scrolling view.

Defaults to: false

letscrollingMessage=newScrollingView({shadow: true,
...
})

Font Object

Set a font object to set the following properties:

fontFamily: string

Specifies the font family or specific font to use.

Defaults: Uses the default system font

fontSize: Number/String

Font size, in platform-dependent units.

Defaults: 14dp

fontWeight: string

Font weight. Valid values are "bold", "semibold", "normal", "thin", "light" and "ultralight".

The "semibold", "thin", "light" and "ultralight" weights are recognized on iOS only. "thin", "light" and "ultralight" are only available on iOS 8.2 and later.

Defaults: normal

letscrollingMessage=newScrollingView({font: {fontSize: 16,fontWeight: 'bold',fontFamily: 'Gill Sans'}...})

Positioning Properties

top or bottom : number/string

The scrolling view's top OR bottom position. This position is relative to the scrolling view's parent.

You can use px, % or dp values.

Defaults to: undefined

letscrollingMessage=newScrollingView({top: 44,// ORbottom: 0...})

Behavior properties

autoplay : boolean

You can turn off automatic playing by setting the autoplay property to false.

Defaults to: true

letscrollingMessage=newScrollingView({autoplay: false,
...
})

delay : number

Pause the animation between messages in seconds.

Defaults to: 0

letscrollingMessage=newScrollingView({delay: 3,
...
})

speed : number

The speed of the scrolling text, a constant speed no matter the text length, the higher the number the faster the scrolling speed.

Only values greater than 0 are accepted; 0 and negative values are ignored.

Defaults to: 5

letscrollingMessage=newScrollingView({speed: 7,
...
})

random : boolean

To display the messages in random order set random to true.

Since v1.2.0 you can turn it off at any time with update({ random: false }), which restores the original message order.

Defaults to: false

letscrollingMessage=newScrollingView({random: true,
...
})

Update Methods

There are 4 methods to update the content and properties at any time.

  • update()
  • updateLabel()
  • updateBackground()
  • updateMessage() or updateMessages()

update

Is a general purpose method to change any or all of the following properties:

  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • autoplay
  • top or bottom
  • backgroundColor
  • message or messages
  • font object with fontSize, fontWeight, fontFamily

When updating the message ( or messages ), the text will be shown after completing the currently running message.

scrollingMessage.update({top: 0,delay: 0,speed: 10,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform',font: {fontWeight: 'bold'}})

updateMessage/updateMessages

If you need to update only the message or messages, you can use the updateMessage or updateMessages methods.

You can use either of them with a string or an array. A string with | separators is split into multiple messages. Calling them with an empty string or an empty array returns false and keeps the current messages.

The updated text will be shown after completing the currently running message.

scrollingMessage.updateMessage('Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform')scrollingMessage.updateMessages(['Build: Write in JavaScript, run native on any device and OS','Connect: Get mobile-optimized access to any data source','Measure: See usage & adoption, detect crashes, tune performance'])

updateLabel

This method will instantly update the label property.

If the scrolling view does not originally contained a label, it will be add it automatically.

scrollingMessage.updateLabel('Breaking News:')

updateBackground

Use it to change the scrolling view's background color, including the label property if available.

scrollingMessage.updateBackground('#79a342')

Playback & Lifecycle Methods

play

Starts playing the scrolling view. Since v1.2.0 it works even if autoplay is set to false ( autoplay only controls automatic starts ). If a message is already scrolling, calling it again has no effect.

scrollingMessage.play()

pause

Pauses the scrolling view. The message currently on screen finishes its scroll, and no further messages are played until you call play() or resume().

scrollingMessage.pause()

resume

Resumes a paused scrolling view.

scrollingMessage.resume()

destroy

Releases the scrolling view from the library's internal registry ( used for the automatic pause/resume on app background/foreground ) and cancels any pending timers. Call it when closing the window that contains the scrolling view:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

getView

Returns the actual Ti.UI.View so you can add it to your layout ( Classic projects ):

win.add(scrollingMessage.getView())

Events

on( eventName, callback )

Assigns a callback for the paused, resumed and complete events. The callback receives the scrolling view instance as its only argument.

  • paused: fired when the scrolling view is paused ( manually or automatically when the app goes to the background )
  • resumed: fired when the scrolling view is resumed
  • complete: fired every time a message finishes scrolling
scrollingMessage.on('complete',(source)=>{console.log('A message finished scrolling')})scrollingMessage.on('paused',(source)=>{console.log('The scrolling view was paused')})

Debug Mode

name : string

In order to identify each Scrolling View while debuging, you can set the name property at initialization.

letscrollingMessage=newScrollingView({name: 'My Scrolling View',
...
})
<ScrollingViewid="scrollingMessage"module='ti.scroller'name="My Scrolling View" />

When you enable debug mode you'll see multiple outputs with the name of the Scrolling View.

[WARN] ::ti.scroller:: My Scrolling View: Add side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view’s label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view[WARN] ::ti.scroller:: My Scrolling View: Play method[WARN] ::ti.scroller:: My Scrolling View: Update messages method[WARN] ::ti.scroller:: My Scrolling View: Complete event[WARN] ::ti.scroller:: My Scrolling View: Play method

If no name is set, the output will be its id, and if none is set, it will generate an internal one.

debug : bollean

You can debug the scrolling view by setting the debug property to true at initialization or with the update() method.

Defaults to: false

letscrollingMessage=newScrollingView({debug: true,
...
})// ORscrollingMessage.update({debug: true})
<ScrollingViewid="scrollingMessage"module='ti.scroller'debug="true" />

To turn it off

scrollingMessage.update({debug: false})// OR$.scrollingMessage.update({debug: false})

License

Copyright 2021 César Estrada
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

About

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

Topics

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

ti.scroller

Description

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

  • You can create multiple scrolling views and customize them separately
  • Each scrolling view can display one or multiple messages, cycle between them or display them in random order
  • You can update its content at any time ( messages, color, position, delay, etc. )
  • Works with Android & iOS

What's new in v1.2.0

New destroy() method

Every scrolling view is kept in an internal registry so the library can pause/resume all of them when the app goes to the background. Starting with v1.2.0, call destroy() when you close the window that contains a scrolling view, so it gets released from that registry ( otherwise it stays retained for the lifetime of the app ):

win.addEventListener('close',()=>{scrollingMessage.destroy()})

New on() method: paused, resumed and complete events

You can now assign a callback for the paused, resumed and complete events. The callback receives the scrolling view instance:

scrollingMessage.on('complete',(source)=>{// Fired every time a message finishes scrolling})

play() now always plays

play() starts playback even if autoplay is set to false. The autoplay property now only controls automatic starts ( at creation and when setting new messages ).

animate() ( deprecated ) works again

In v1.1.0 the deprecated animate() method became a no-op. It now behaves like play() again, but it will still be deleted in v2.0.0, so use play() instead.

Bug fixes

  • pause() now sticks: pausing during the delay window between messages is no longer reverted by an internal timer.
  • Fixed a race condition that could start two scrolling loops at once when updating messages mid-cycle.
  • The automatic pause/resume on app background/foreground now respects manual pauses: if you paused a scrolling view yourself, it won't auto-resume when the app comes back to the foreground.
  • The | separator for multiple messages in a single string now works everywhere ( it was documented for Alloy but not implemented ).
  • Boolean attributes set from Alloy XML ( autoplay="false", random="false", debug="true" ) now work as expected.
  • Colors in #AARRGGBB format are handled correctly by the side label's darkened background ( the default #BF000000 no longer renders red ).
  • random can now be turned off with update({ random: false }), restoring the original message order.
  • update() called without arguments no longer throws, and update({ speed: 0 }) is ignored instead of freezing the scroller.
  • The messages array you pass is no longer mutated when using random.
  • Message widths are cached per text, so repeated cycles no longer re-measure the same message.
  • updateLabel() now creates the side label on the fly if the scrolling view didn't have one ( as it was always documented ).

Breaking changes in v1.1.0

Autoplaying scrolling views

Each scrolling view will start playing immediately after initialization if either message or messages properties are set.

This means that you no longer need to call the animate() method ( now deprecated ) after initialization.

They won't autoplay if there is no message set at initialization, this is useful when you need to get the data from the internet. They will start playing the moment you set a new message(s) with update() or updateMessage/Messages() methods.

If you set the message(s) property and still don't want the scrolling views to start playing immediately, set the new autoplay property to false.

Then use the play() method ( or resume() ) to start playing the scrolling view when needed. Since v1.2.0, play() starts playback even if autoplay is false. You only need to set autoplay back to true if you want new messages set with update() / updateMessage(s)() to start playing automatically.

New <ScrollingView /> Alloy element

In order to be more like a native Ti element in Alloy projects, you now create your scrolling views with the <ScrollingView> element provided by ti.scroller.js

<ScrollingViewmodule='ti.scroller' ... />

paused and resume App Events

The library listens to the Ti.App lifecycle events paused and resume, so you no longer need to handle them manually. They will pause/resume every scrolling view created in your app.

animate() method Deprecated

The animate() method is deprecated and will be deleted in the future.

Installation in Classic Apps

For Classic Apps, put ti.scroller.js file inside the Resources folder.

Basic usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller lib',backgroundColor: '#fff'})letscrollingMessage=newScrollingView({message: 'Appcelerator Titanium: Everything you need to create great, native mobile apps — All from a single JavaScript code base.'})win.add(scrollingMessage.getView())win.open()

Result

iOS Screen - Example

* low framerate gif

Advanced usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller',backgroundColor: '#fff'})letcontainer=Ti.UI.createView({layout: 'vertical',height: Ti.UI.SIZE})letfamousPeopleQuotes=newScrollingView({top: 8,speed: 7,random: true,color: '#dddfe1',label: 'Famous People:',backgroundColor: '#53606b',messages: ['The greatest glory in living lies not in never falling, but in rising every time we fall. - Nelson Mandela','The way to get started is to quit talking and begin doing. - Walt Disney','Your time is limited, so don\'t waste it living someone else\'s life. Don\'t be trapped by dogma – which is living with the results of other people\'s thinking. - Steve Jobs','If life were predictable it would cease to be life, and be without flavor. - Eleanor Roosevelt','If you look at what you have in life, you\'ll always have more. If you look at what you don\'t have in life, you\'ll never have enough. - Oprah Winfrey','If you set your goals ridiculously high and it\'s a failure, you will fail above everyone else\'s success. - James Cameron','Life is what happens when you\'re busy making other plans. - John Lennon']})letbestQuotesOfAllTimes=newScrollingView({top: 8,speed: 6,label: 'Best Quotes:',backgroundColor: '#79a342',messages: ['Whoever is happy will make others happy too. - Anne Frank','It is during our darkest moments that we must focus to see the light. - Aristotle','Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead','Spread love everywhere you go. Let no one ever come to you without leaving happier. - Mother Teresa','When you reach the end of your rope, tie a knot in it and hang on. - Franklin D. Roosevelt','Don\'t judge each day by the harvest you reap but by the seeds that you plant. - Robert Louis Stevenson','The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt','Tell me and I forget. Teach me and I remember. Involve me and I learn. - Benjamin Franklin','The best and most beautiful things in the world cannot be seen or even touched — they must be felt with the heart. - Helen Keller','Do not go where the path may lead, go instead where there is no path and leave a trail. - Ralph Waldo Emerson']})letmarketStocks=newScrollingView({top: 8,speed: 8,height: 36,debug: true,label: 'Market:',name: 'Market Stocks',message: 'Loading data...',backgroundColor: '#F3650C'})// Simulated API responsesetTimeout(()=>{// Just set the new message(s) with `updateMessages` methodmarketStocks.updateMessages('EUR/USD 1.18664 0 0% · USD/JPY 110.399 0.06 0.05% · GBP/USD 1.38902 0 0% · EUR/JPY 130.9959 0.109 0.08% · GBP/JPY 153.3323 0.116 0.08% · USD/CAD 1.24481 -0.001 -0.08% · XAU/USD 1806.7484 -0.684 -0.04% · AUD/USD 0.74878 0.001 0.13% · USD/CHF 0.91462 -0.001 -0.11% · NZD/USD 0.69921 0.001 0.14%')},3000)container.add(famousPeopleQuotes.getView())container.add(bestQuotesOfAllTimes.getView())container.add(marketStocks.getView())win.add(container)win.open()

Result

iOS Screen - Example

* low framerate gif

Installation in Alloy Apps

For Alloy projects drop ti.scroller in /app/lib folder.

app
└─ lib
└─ ti.scroller.js

In your View file, create a ScrollingView Alloy element and add a module attribute like this module="ti.scroller".

You can set any of the supported attributes directly in the ScrollingView.

IMPORTANT: For multiple messages you'll need to separate them with the | symbol like shown below.

<Alloy>
<NavigationWindow>
<Windowtitle="ti.scroller">
<ScrollingViewid="scrollingMessage"module='ti.scroller'backgroundColor="#c91326"label="Famous Quotes:"speed="4"delay="2"height="32"random="true"top="0" font.fontFamily="Gill Sans" font.fontWeight="semibold" font.fontSize="16"message="Whoever is happy will make others happy too. - Anne Frank|It is during our darkest moments that we must focus to see the light. - Aristotle|Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead" />
</Window>
</NavigationWindow>
</Alloy>

Result

iOS Screen - Example

* low framerate gif

In your controller you can call any of the available methods: update, updateLabel, updateMessage/updateMessages, updateBackground, play, pause, resume, destroy or on at anytime.

$.scrollingMessage.update({top: 48,delay: 3,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform'})

Important consideration

To prevent unexpected behaviors, the library itself listens to the following Ti.App events, so you don't need to add any listener:

  • paused event: In order to pause the scrolling effect while the app is in the background
  • resume event: To resume scrolling when in the foreground.

They will handle every scrolling view created in your app. Since v1.2.0, a scrolling view that you paused manually stays paused when the app comes back to the foreground.

Remember to call destroy() when closing a window that contains scrolling views, so they get released from the internal registry:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

Customization

You can customize the text color, background color, vertical position, font size, font weight, font family, scrolling speed, delay between messages, autoplay messages, random order display, side label text, name and debug mode with the following properties:

  • id
  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • shadow
  • autoplay
  • top/bottom
  • backgroundColor
  • message/messages
  • font object with fontSize, fontWeight, fontFamily

Content Properties

message/messages : array/string

The text to display can be set with message or messages property using an array ( for a single message you can set it using a string ).

You can also pass multiple messages in a single string by separating them with the | symbol. This is how multiple messages are set from Alloy XML, and since v1.2.0 it also works in JavaScript:

letscrollingMessage=newScrollingView({message: 'First message|Second message|Third message',
...
})
letscrollingMessage=newScrollingView({messages: ['Every moment is a fresh beginning. – T.S Eliot','Change the world by being yourself. – Amy Poehler','Love For All, Hatred For None. – Khalifatul Masih III'],
...
})

label : string

To display a left-side label set the label property.

The side label text is always bold, on a slightly darker shade of the scrolling view's backgroundColor.

Defaults to: null

letscrollingMessage=newScrollingView({label: 'Breaking News:',
...
})

Design Properties

color : string

Color for the text message(s) and side label in hex value.

Defaults to: #fff

letscrollingMessage=newScrollingView({color: '#79a342',
...
})

backgroundColor : string

Background color for the scrolling view, as a hex triplet.

Defaults to: #BF000000

letscrollingMessage=newScrollingView({backgroundColor: '#53606b',
...
})

height : number/string

ScrollingView height, in platform-specific units.

Defaults to: 28 ( platform default units )

letscrollingMessage=newScrollingView({height: 44...})

shadow : boolean

Set shadow to true to display a drop shadow under the scrolling view.

Defaults to: false

letscrollingMessage=newScrollingView({shadow: true,
...
})

Font Object

Set a font object to set the following properties:

fontFamily: string

Specifies the font family or specific font to use.

Defaults: Uses the default system font

fontSize: Number/String

Font size, in platform-dependent units.

Defaults: 14dp

fontWeight: string

Font weight. Valid values are "bold", "semibold", "normal", "thin", "light" and "ultralight".

The "semibold", "thin", "light" and "ultralight" weights are recognized on iOS only. "thin", "light" and "ultralight" are only available on iOS 8.2 and later.

Defaults: normal

letscrollingMessage=newScrollingView({font: {fontSize: 16,fontWeight: 'bold',fontFamily: 'Gill Sans'}...})

Positioning Properties

top or bottom : number/string

The scrolling view's top OR bottom position. This position is relative to the scrolling view's parent.

You can use px, % or dp values.

Defaults to: undefined

letscrollingMessage=newScrollingView({top: 44,// ORbottom: 0...})

Behavior properties

autoplay : boolean

You can turn off automatic playing by setting the autoplay property to false.

Defaults to: true

letscrollingMessage=newScrollingView({autoplay: false,
...
})

delay : number

Pause the animation between messages in seconds.

Defaults to: 0

letscrollingMessage=newScrollingView({delay: 3,
...
})

speed : number

The speed of the scrolling text, a constant speed no matter the text length, the higher the number the faster the scrolling speed.

Only values greater than 0 are accepted; 0 and negative values are ignored.

Defaults to: 5

letscrollingMessage=newScrollingView({speed: 7,
...
})

random : boolean

To display the messages in random order set random to true.

Since v1.2.0 you can turn it off at any time with update({ random: false }), which restores the original message order.

Defaults to: false

letscrollingMessage=newScrollingView({random: true,
...
})

Update Methods

There are 4 methods to update the content and properties at any time.

  • update()
  • updateLabel()
  • updateBackground()
  • updateMessage() or updateMessages()

update

Is a general purpose method to change any or all of the following properties:

  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • autoplay
  • top or bottom
  • backgroundColor
  • message or messages
  • font object with fontSize, fontWeight, fontFamily

When updating the message ( or messages ), the text will be shown after completing the currently running message.

scrollingMessage.update({top: 0,delay: 0,speed: 10,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform',font: {fontWeight: 'bold'}})

updateMessage/updateMessages

If you need to update only the message or messages, you can use the updateMessage or updateMessages methods.

You can use either of them with a string or an array. A string with | separators is split into multiple messages. Calling them with an empty string or an empty array returns false and keeps the current messages.

The updated text will be shown after completing the currently running message.

scrollingMessage.updateMessage('Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform')scrollingMessage.updateMessages(['Build: Write in JavaScript, run native on any device and OS','Connect: Get mobile-optimized access to any data source','Measure: See usage & adoption, detect crashes, tune performance'])

updateLabel

This method will instantly update the label property.

If the scrolling view does not originally contained a label, it will be add it automatically.

scrollingMessage.updateLabel('Breaking News:')

updateBackground

Use it to change the scrolling view's background color, including the label property if available.

scrollingMessage.updateBackground('#79a342')

Playback & Lifecycle Methods

play

Starts playing the scrolling view. Since v1.2.0 it works even if autoplay is set to false ( autoplay only controls automatic starts ). If a message is already scrolling, calling it again has no effect.

scrollingMessage.play()

pause

Pauses the scrolling view. The message currently on screen finishes its scroll, and no further messages are played until you call play() or resume().

scrollingMessage.pause()

resume

Resumes a paused scrolling view.

scrollingMessage.resume()

destroy

Releases the scrolling view from the library's internal registry ( used for the automatic pause/resume on app background/foreground ) and cancels any pending timers. Call it when closing the window that contains the scrolling view:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

getView

Returns the actual Ti.UI.View so you can add it to your layout ( Classic projects ):

win.add(scrollingMessage.getView())

Events

on( eventName, callback )

Assigns a callback for the paused, resumed and complete events. The callback receives the scrolling view instance as its only argument.

  • paused: fired when the scrolling view is paused ( manually or automatically when the app goes to the background )
  • resumed: fired when the scrolling view is resumed
  • complete: fired every time a message finishes scrolling
scrollingMessage.on('complete',(source)=>{console.log('A message finished scrolling')})scrollingMessage.on('paused',(source)=>{console.log('The scrolling view was paused')})

Debug Mode

name : string

In order to identify each Scrolling View while debuging, you can set the name property at initialization.

letscrollingMessage=newScrollingView({name: 'My Scrolling View',
...
})
<ScrollingViewid="scrollingMessage"module='ti.scroller'name="My Scrolling View" />

When you enable debug mode you'll see multiple outputs with the name of the Scrolling View.

[WARN] ::ti.scroller:: My Scrolling View: Add side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view’s label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view[WARN] ::ti.scroller:: My Scrolling View: Play method[WARN] ::ti.scroller:: My Scrolling View: Update messages method[WARN] ::ti.scroller:: My Scrolling View: Complete event[WARN] ::ti.scroller:: My Scrolling View: Play method

If no name is set, the output will be its id, and if none is set, it will generate an internal one.

debug : bollean

You can debug the scrolling view by setting the debug property to true at initialization or with the update() method.

Defaults to: false

letscrollingMessage=newScrollingView({debug: true,
...
})// ORscrollingMessage.update({debug: true})
<ScrollingViewid="scrollingMessage"module='ti.scroller'debug="true" />

To turn it off

scrollingMessage.update({debug: false})// OR$.scrollingMessage.update({debug: false})

License

Copyright 2021 César Estrada
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

About

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

Topics

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ti.scroller

Description

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

  • You can create multiple scrolling views and customize them separately
  • Each scrolling view can display one or multiple messages, cycle between them or display them in random order
  • You can update its content at any time ( messages, color, position, delay, etc. )
  • Works with Android & iOS

What's new in v1.2.0

New destroy() method

Every scrolling view is kept in an internal registry so the library can pause/resume all of them when the app goes to the background. Starting with v1.2.0, call destroy() when you close the window that contains a scrolling view, so it gets released from that registry ( otherwise it stays retained for the lifetime of the app ):

win.addEventListener('close',()=>{scrollingMessage.destroy()})

New on() method: paused, resumed and complete events

You can now assign a callback for the paused, resumed and complete events. The callback receives the scrolling view instance:

scrollingMessage.on('complete',(source)=>{// Fired every time a message finishes scrolling})

play() now always plays

play() starts playback even if autoplay is set to false. The autoplay property now only controls automatic starts ( at creation and when setting new messages ).

animate() ( deprecated ) works again

In v1.1.0 the deprecated animate() method became a no-op. It now behaves like play() again, but it will still be deleted in v2.0.0, so use play() instead.

Bug fixes

  • pause() now sticks: pausing during the delay window between messages is no longer reverted by an internal timer.
  • Fixed a race condition that could start two scrolling loops at once when updating messages mid-cycle.
  • The automatic pause/resume on app background/foreground now respects manual pauses: if you paused a scrolling view yourself, it won't auto-resume when the app comes back to the foreground.
  • The | separator for multiple messages in a single string now works everywhere ( it was documented for Alloy but not implemented ).
  • Boolean attributes set from Alloy XML ( autoplay="false", random="false", debug="true" ) now work as expected.
  • Colors in #AARRGGBB format are handled correctly by the side label's darkened background ( the default #BF000000 no longer renders red ).
  • random can now be turned off with update({ random: false }), restoring the original message order.
  • update() called without arguments no longer throws, and update({ speed: 0 }) is ignored instead of freezing the scroller.
  • The messages array you pass is no longer mutated when using random.
  • Message widths are cached per text, so repeated cycles no longer re-measure the same message.
  • updateLabel() now creates the side label on the fly if the scrolling view didn't have one ( as it was always documented ).

Breaking changes in v1.1.0

Autoplaying scrolling views

Each scrolling view will start playing immediately after initialization if either message or messages properties are set.

This means that you no longer need to call the animate() method ( now deprecated ) after initialization.

They won't autoplay if there is no message set at initialization, this is useful when you need to get the data from the internet. They will start playing the moment you set a new message(s) with update() or updateMessage/Messages() methods.

If you set the message(s) property and still don't want the scrolling views to start playing immediately, set the new autoplay property to false.

Then use the play() method ( or resume() ) to start playing the scrolling view when needed. Since v1.2.0, play() starts playback even if autoplay is false. You only need to set autoplay back to true if you want new messages set with update() / updateMessage(s)() to start playing automatically.

New <ScrollingView /> Alloy element

In order to be more like a native Ti element in Alloy projects, you now create your scrolling views with the <ScrollingView> element provided by ti.scroller.js

<ScrollingViewmodule='ti.scroller' ... />

paused and resume App Events

The library listens to the Ti.App lifecycle events paused and resume, so you no longer need to handle them manually. They will pause/resume every scrolling view created in your app.

animate() method Deprecated

The animate() method is deprecated and will be deleted in the future.

Installation in Classic Apps

For Classic Apps, put ti.scroller.js file inside the Resources folder.

Basic usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller lib',backgroundColor: '#fff'})letscrollingMessage=newScrollingView({message: 'Appcelerator Titanium: Everything you need to create great, native mobile apps — All from a single JavaScript code base.'})win.add(scrollingMessage.getView())win.open()

Result

iOS Screen - Example

* low framerate gif

Advanced usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller',backgroundColor: '#fff'})letcontainer=Ti.UI.createView({layout: 'vertical',height: Ti.UI.SIZE})letfamousPeopleQuotes=newScrollingView({top: 8,speed: 7,random: true,color: '#dddfe1',label: 'Famous People:',backgroundColor: '#53606b',messages: ['The greatest glory in living lies not in never falling, but in rising every time we fall. - Nelson Mandela','The way to get started is to quit talking and begin doing. - Walt Disney','Your time is limited, so don\'t waste it living someone else\'s life. Don\'t be trapped by dogma – which is living with the results of other people\'s thinking. - Steve Jobs','If life were predictable it would cease to be life, and be without flavor. - Eleanor Roosevelt','If you look at what you have in life, you\'ll always have more. If you look at what you don\'t have in life, you\'ll never have enough. - Oprah Winfrey','If you set your goals ridiculously high and it\'s a failure, you will fail above everyone else\'s success. - James Cameron','Life is what happens when you\'re busy making other plans. - John Lennon']})letbestQuotesOfAllTimes=newScrollingView({top: 8,speed: 6,label: 'Best Quotes:',backgroundColor: '#79a342',messages: ['Whoever is happy will make others happy too. - Anne Frank','It is during our darkest moments that we must focus to see the light. - Aristotle','Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead','Spread love everywhere you go. Let no one ever come to you without leaving happier. - Mother Teresa','When you reach the end of your rope, tie a knot in it and hang on. - Franklin D. Roosevelt','Don\'t judge each day by the harvest you reap but by the seeds that you plant. - Robert Louis Stevenson','The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt','Tell me and I forget. Teach me and I remember. Involve me and I learn. - Benjamin Franklin','The best and most beautiful things in the world cannot be seen or even touched — they must be felt with the heart. - Helen Keller','Do not go where the path may lead, go instead where there is no path and leave a trail. - Ralph Waldo Emerson']})letmarketStocks=newScrollingView({top: 8,speed: 8,height: 36,debug: true,label: 'Market:',name: 'Market Stocks',message: 'Loading data...',backgroundColor: '#F3650C'})// Simulated API responsesetTimeout(()=>{// Just set the new message(s) with `updateMessages` methodmarketStocks.updateMessages('EUR/USD 1.18664 0 0% · USD/JPY 110.399 0.06 0.05% · GBP/USD 1.38902 0 0% · EUR/JPY 130.9959 0.109 0.08% · GBP/JPY 153.3323 0.116 0.08% · USD/CAD 1.24481 -0.001 -0.08% · XAU/USD 1806.7484 -0.684 -0.04% · AUD/USD 0.74878 0.001 0.13% · USD/CHF 0.91462 -0.001 -0.11% · NZD/USD 0.69921 0.001 0.14%')},3000)container.add(famousPeopleQuotes.getView())container.add(bestQuotesOfAllTimes.getView())container.add(marketStocks.getView())win.add(container)win.open()

Result

iOS Screen - Example

* low framerate gif

Installation in Alloy Apps

For Alloy projects drop ti.scroller in /app/lib folder.

app
└─ lib
└─ ti.scroller.js

In your View file, create a ScrollingView Alloy element and add a module attribute like this module="ti.scroller".

You can set any of the supported attributes directly in the ScrollingView.

IMPORTANT: For multiple messages you'll need to separate them with the | symbol like shown below.

<Alloy>
<NavigationWindow>
<Windowtitle="ti.scroller">
<ScrollingViewid="scrollingMessage"module='ti.scroller'backgroundColor="#c91326"label="Famous Quotes:"speed="4"delay="2"height="32"random="true"top="0" font.fontFamily="Gill Sans" font.fontWeight="semibold" font.fontSize="16"message="Whoever is happy will make others happy too. - Anne Frank|It is during our darkest moments that we must focus to see the light. - Aristotle|Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead" />
</Window>
</NavigationWindow>
</Alloy>

Result

iOS Screen - Example

* low framerate gif

In your controller you can call any of the available methods: update, updateLabel, updateMessage/updateMessages, updateBackground, play, pause, resume, destroy or on at anytime.

$.scrollingMessage.update({top: 48,delay: 3,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform'})

Important consideration

To prevent unexpected behaviors, the library itself listens to the following Ti.App events, so you don't need to add any listener:

  • paused event: In order to pause the scrolling effect while the app is in the background
  • resume event: To resume scrolling when in the foreground.

They will handle every scrolling view created in your app. Since v1.2.0, a scrolling view that you paused manually stays paused when the app comes back to the foreground.

Remember to call destroy() when closing a window that contains scrolling views, so they get released from the internal registry:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

Customization

You can customize the text color, background color, vertical position, font size, font weight, font family, scrolling speed, delay between messages, autoplay messages, random order display, side label text, name and debug mode with the following properties:

  • id
  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • shadow
  • autoplay
  • top/bottom
  • backgroundColor
  • message/messages
  • font object with fontSize, fontWeight, fontFamily

Content Properties

message/messages : array/string

The text to display can be set with message or messages property using an array ( for a single message you can set it using a string ).

You can also pass multiple messages in a single string by separating them with the | symbol. This is how multiple messages are set from Alloy XML, and since v1.2.0 it also works in JavaScript:

letscrollingMessage=newScrollingView({message: 'First message|Second message|Third message',
...
})
letscrollingMessage=newScrollingView({messages: ['Every moment is a fresh beginning. – T.S Eliot','Change the world by being yourself. – Amy Poehler','Love For All, Hatred For None. – Khalifatul Masih III'],
...
})

label : string

To display a left-side label set the label property.

The side label text is always bold, on a slightly darker shade of the scrolling view's backgroundColor.

Defaults to: null

letscrollingMessage=newScrollingView({label: 'Breaking News:',
...
})

Design Properties

color : string

Color for the text message(s) and side label in hex value.

Defaults to: #fff

letscrollingMessage=newScrollingView({color: '#79a342',
...
})

backgroundColor : string

Background color for the scrolling view, as a hex triplet.

Defaults to: #BF000000

letscrollingMessage=newScrollingView({backgroundColor: '#53606b',
...
})

height : number/string

ScrollingView height, in platform-specific units.

Defaults to: 28 ( platform default units )

letscrollingMessage=newScrollingView({height: 44...})

shadow : boolean

Set shadow to true to display a drop shadow under the scrolling view.

Defaults to: false

letscrollingMessage=newScrollingView({shadow: true,
...
})

Font Object

Set a font object to set the following properties:

fontFamily: string

Specifies the font family or specific font to use.

Defaults: Uses the default system font

fontSize: Number/String

Font size, in platform-dependent units.

Defaults: 14dp

fontWeight: string

Font weight. Valid values are "bold", "semibold", "normal", "thin", "light" and "ultralight".

The "semibold", "thin", "light" and "ultralight" weights are recognized on iOS only. "thin", "light" and "ultralight" are only available on iOS 8.2 and later.

Defaults: normal

letscrollingMessage=newScrollingView({font: {fontSize: 16,fontWeight: 'bold',fontFamily: 'Gill Sans'}...})

Positioning Properties

top or bottom : number/string

The scrolling view's top OR bottom position. This position is relative to the scrolling view's parent.

You can use px, % or dp values.

Defaults to: undefined

letscrollingMessage=newScrollingView({top: 44,// ORbottom: 0...})

Behavior properties

autoplay : boolean

You can turn off automatic playing by setting the autoplay property to false.

Defaults to: true

letscrollingMessage=newScrollingView({autoplay: false,
...
})

delay : number

Pause the animation between messages in seconds.

Defaults to: 0

letscrollingMessage=newScrollingView({delay: 3,
...
})

speed : number

The speed of the scrolling text, a constant speed no matter the text length, the higher the number the faster the scrolling speed.

Only values greater than 0 are accepted; 0 and negative values are ignored.

Defaults to: 5

letscrollingMessage=newScrollingView({speed: 7,
...
})

random : boolean

To display the messages in random order set random to true.

Since v1.2.0 you can turn it off at any time with update({ random: false }), which restores the original message order.

Defaults to: false

letscrollingMessage=newScrollingView({random: true,
...
})

Update Methods

There are 4 methods to update the content and properties at any time.

  • update()
  • updateLabel()
  • updateBackground()
  • updateMessage() or updateMessages()

update

Is a general purpose method to change any or all of the following properties:

  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • autoplay
  • top or bottom
  • backgroundColor
  • message or messages
  • font object with fontSize, fontWeight, fontFamily

When updating the message ( or messages ), the text will be shown after completing the currently running message.

scrollingMessage.update({top: 0,delay: 0,speed: 10,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform',font: {fontWeight: 'bold'}})

updateMessage/updateMessages

If you need to update only the message or messages, you can use the updateMessage or updateMessages methods.

You can use either of them with a string or an array. A string with | separators is split into multiple messages. Calling them with an empty string or an empty array returns false and keeps the current messages.

The updated text will be shown after completing the currently running message.

scrollingMessage.updateMessage('Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform')scrollingMessage.updateMessages(['Build: Write in JavaScript, run native on any device and OS','Connect: Get mobile-optimized access to any data source','Measure: See usage & adoption, detect crashes, tune performance'])

updateLabel

This method will instantly update the label property.

If the scrolling view does not originally contained a label, it will be add it automatically.

scrollingMessage.updateLabel('Breaking News:')

updateBackground

Use it to change the scrolling view's background color, including the label property if available.

scrollingMessage.updateBackground('#79a342')

Playback & Lifecycle Methods

play

Starts playing the scrolling view. Since v1.2.0 it works even if autoplay is set to false ( autoplay only controls automatic starts ). If a message is already scrolling, calling it again has no effect.

scrollingMessage.play()

pause

Pauses the scrolling view. The message currently on screen finishes its scroll, and no further messages are played until you call play() or resume().

scrollingMessage.pause()

resume

Resumes a paused scrolling view.

scrollingMessage.resume()

destroy

Releases the scrolling view from the library's internal registry ( used for the automatic pause/resume on app background/foreground ) and cancels any pending timers. Call it when closing the window that contains the scrolling view:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

getView

Returns the actual Ti.UI.View so you can add it to your layout ( Classic projects ):

win.add(scrollingMessage.getView())

Events

on( eventName, callback )

Assigns a callback for the paused, resumed and complete events. The callback receives the scrolling view instance as its only argument.

  • paused: fired when the scrolling view is paused ( manually or automatically when the app goes to the background )
  • resumed: fired when the scrolling view is resumed
  • complete: fired every time a message finishes scrolling
scrollingMessage.on('complete',(source)=>{console.log('A message finished scrolling')})scrollingMessage.on('paused',(source)=>{console.log('The scrolling view was paused')})

Debug Mode

name : string

In order to identify each Scrolling View while debuging, you can set the name property at initialization.

letscrollingMessage=newScrollingView({name: 'My Scrolling View',
...
})
<ScrollingViewid="scrollingMessage"module='ti.scroller'name="My Scrolling View" />

When you enable debug mode you'll see multiple outputs with the name of the Scrolling View.

[WARN] ::ti.scroller:: My Scrolling View: Add side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view’s label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view[WARN] ::ti.scroller:: My Scrolling View: Play method[WARN] ::ti.scroller:: My Scrolling View: Update messages method[WARN] ::ti.scroller:: My Scrolling View: Complete event[WARN] ::ti.scroller:: My Scrolling View: Play method

If no name is set, the output will be its id, and if none is set, it will generate an internal one.

debug : bollean

You can debug the scrolling view by setting the debug property to true at initialization or with the update() method.

Defaults to: false

letscrollingMessage=newScrollingView({debug: true,
...
})// ORscrollingMessage.update({debug: true})
<ScrollingViewid="scrollingMessage"module='ti.scroller'debug="true" />

To turn it off

scrollingMessage.update({debug: false})// OR$.scrollingMessage.update({debug: false})

License

Copyright 2021 César Estrada
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

About

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

Topics

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ti.scroller

Description

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

  • You can create multiple scrolling views and customize them separately
  • Each scrolling view can display one or multiple messages, cycle between them or display them in random order
  • You can update its content at any time ( messages, color, position, delay, etc. )
  • Works with Android & iOS

What's new in v1.2.0

New destroy() method

Every scrolling view is kept in an internal registry so the library can pause/resume all of them when the app goes to the background. Starting with v1.2.0, call destroy() when you close the window that contains a scrolling view, so it gets released from that registry ( otherwise it stays retained for the lifetime of the app ):

win.addEventListener('close',()=>{scrollingMessage.destroy()})

New on() method: paused, resumed and complete events

You can now assign a callback for the paused, resumed and complete events. The callback receives the scrolling view instance:

scrollingMessage.on('complete',(source)=>{// Fired every time a message finishes scrolling})

play() now always plays

play() starts playback even if autoplay is set to false. The autoplay property now only controls automatic starts ( at creation and when setting new messages ).

animate() ( deprecated ) works again

In v1.1.0 the deprecated animate() method became a no-op. It now behaves like play() again, but it will still be deleted in v2.0.0, so use play() instead.

Bug fixes

  • pause() now sticks: pausing during the delay window between messages is no longer reverted by an internal timer.
  • Fixed a race condition that could start two scrolling loops at once when updating messages mid-cycle.
  • The automatic pause/resume on app background/foreground now respects manual pauses: if you paused a scrolling view yourself, it won't auto-resume when the app comes back to the foreground.
  • The | separator for multiple messages in a single string now works everywhere ( it was documented for Alloy but not implemented ).
  • Boolean attributes set from Alloy XML ( autoplay="false", random="false", debug="true" ) now work as expected.
  • Colors in #AARRGGBB format are handled correctly by the side label's darkened background ( the default #BF000000 no longer renders red ).
  • random can now be turned off with update({ random: false }), restoring the original message order.
  • update() called without arguments no longer throws, and update({ speed: 0 }) is ignored instead of freezing the scroller.
  • The messages array you pass is no longer mutated when using random.
  • Message widths are cached per text, so repeated cycles no longer re-measure the same message.
  • updateLabel() now creates the side label on the fly if the scrolling view didn't have one ( as it was always documented ).

Breaking changes in v1.1.0

Autoplaying scrolling views

Each scrolling view will start playing immediately after initialization if either message or messages properties are set.

This means that you no longer need to call the animate() method ( now deprecated ) after initialization.

They won't autoplay if there is no message set at initialization, this is useful when you need to get the data from the internet. They will start playing the moment you set a new message(s) with update() or updateMessage/Messages() methods.

If you set the message(s) property and still don't want the scrolling views to start playing immediately, set the new autoplay property to false.

Then use the play() method ( or resume() ) to start playing the scrolling view when needed. Since v1.2.0, play() starts playback even if autoplay is false. You only need to set autoplay back to true if you want new messages set with update() / updateMessage(s)() to start playing automatically.

New <ScrollingView /> Alloy element

In order to be more like a native Ti element in Alloy projects, you now create your scrolling views with the <ScrollingView> element provided by ti.scroller.js

<ScrollingViewmodule='ti.scroller' ... />

paused and resume App Events

The library listens to the Ti.App lifecycle events paused and resume, so you no longer need to handle them manually. They will pause/resume every scrolling view created in your app.

animate() method Deprecated

The animate() method is deprecated and will be deleted in the future.

Installation in Classic Apps

For Classic Apps, put ti.scroller.js file inside the Resources folder.

Basic usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller lib',backgroundColor: '#fff'})letscrollingMessage=newScrollingView({message: 'Appcelerator Titanium: Everything you need to create great, native mobile apps — All from a single JavaScript code base.'})win.add(scrollingMessage.getView())win.open()

Result

iOS Screen - Example

* low framerate gif

Advanced usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller',backgroundColor: '#fff'})letcontainer=Ti.UI.createView({layout: 'vertical',height: Ti.UI.SIZE})letfamousPeopleQuotes=newScrollingView({top: 8,speed: 7,random: true,color: '#dddfe1',label: 'Famous People:',backgroundColor: '#53606b',messages: ['The greatest glory in living lies not in never falling, but in rising every time we fall. - Nelson Mandela','The way to get started is to quit talking and begin doing. - Walt Disney','Your time is limited, so don\'t waste it living someone else\'s life. Don\'t be trapped by dogma – which is living with the results of other people\'s thinking. - Steve Jobs','If life were predictable it would cease to be life, and be without flavor. - Eleanor Roosevelt','If you look at what you have in life, you\'ll always have more. If you look at what you don\'t have in life, you\'ll never have enough. - Oprah Winfrey','If you set your goals ridiculously high and it\'s a failure, you will fail above everyone else\'s success. - James Cameron','Life is what happens when you\'re busy making other plans. - John Lennon']})letbestQuotesOfAllTimes=newScrollingView({top: 8,speed: 6,label: 'Best Quotes:',backgroundColor: '#79a342',messages: ['Whoever is happy will make others happy too. - Anne Frank','It is during our darkest moments that we must focus to see the light. - Aristotle','Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead','Spread love everywhere you go. Let no one ever come to you without leaving happier. - Mother Teresa','When you reach the end of your rope, tie a knot in it and hang on. - Franklin D. Roosevelt','Don\'t judge each day by the harvest you reap but by the seeds that you plant. - Robert Louis Stevenson','The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt','Tell me and I forget. Teach me and I remember. Involve me and I learn. - Benjamin Franklin','The best and most beautiful things in the world cannot be seen or even touched — they must be felt with the heart. - Helen Keller','Do not go where the path may lead, go instead where there is no path and leave a trail. - Ralph Waldo Emerson']})letmarketStocks=newScrollingView({top: 8,speed: 8,height: 36,debug: true,label: 'Market:',name: 'Market Stocks',message: 'Loading data...',backgroundColor: '#F3650C'})// Simulated API responsesetTimeout(()=>{// Just set the new message(s) with `updateMessages` methodmarketStocks.updateMessages('EUR/USD 1.18664 0 0% · USD/JPY 110.399 0.06 0.05% · GBP/USD 1.38902 0 0% · EUR/JPY 130.9959 0.109 0.08% · GBP/JPY 153.3323 0.116 0.08% · USD/CAD 1.24481 -0.001 -0.08% · XAU/USD 1806.7484 -0.684 -0.04% · AUD/USD 0.74878 0.001 0.13% · USD/CHF 0.91462 -0.001 -0.11% · NZD/USD 0.69921 0.001 0.14%')},3000)container.add(famousPeopleQuotes.getView())container.add(bestQuotesOfAllTimes.getView())container.add(marketStocks.getView())win.add(container)win.open()

Result

iOS Screen - Example

* low framerate gif

Installation in Alloy Apps

For Alloy projects drop ti.scroller in /app/lib folder.

app
└─ lib
└─ ti.scroller.js

In your View file, create a ScrollingView Alloy element and add a module attribute like this module="ti.scroller".

You can set any of the supported attributes directly in the ScrollingView.

IMPORTANT: For multiple messages you'll need to separate them with the | symbol like shown below.

<Alloy>
<NavigationWindow>
<Windowtitle="ti.scroller">
<ScrollingViewid="scrollingMessage"module='ti.scroller'backgroundColor="#c91326"label="Famous Quotes:"speed="4"delay="2"height="32"random="true"top="0" font.fontFamily="Gill Sans" font.fontWeight="semibold" font.fontSize="16"message="Whoever is happy will make others happy too. - Anne Frank|It is during our darkest moments that we must focus to see the light. - Aristotle|Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead" />
</Window>
</NavigationWindow>
</Alloy>

Result

iOS Screen - Example

* low framerate gif

In your controller you can call any of the available methods: update, updateLabel, updateMessage/updateMessages, updateBackground, play, pause, resume, destroy or on at anytime.

$.scrollingMessage.update({top: 48,delay: 3,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform'})

Important consideration

To prevent unexpected behaviors, the library itself listens to the following Ti.App events, so you don't need to add any listener:

  • paused event: In order to pause the scrolling effect while the app is in the background
  • resume event: To resume scrolling when in the foreground.

They will handle every scrolling view created in your app. Since v1.2.0, a scrolling view that you paused manually stays paused when the app comes back to the foreground.

Remember to call destroy() when closing a window that contains scrolling views, so they get released from the internal registry:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

Customization

You can customize the text color, background color, vertical position, font size, font weight, font family, scrolling speed, delay between messages, autoplay messages, random order display, side label text, name and debug mode with the following properties:

  • id
  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • shadow
  • autoplay
  • top/bottom
  • backgroundColor
  • message/messages
  • font object with fontSize, fontWeight, fontFamily

Content Properties

message/messages : array/string

The text to display can be set with message or messages property using an array ( for a single message you can set it using a string ).

You can also pass multiple messages in a single string by separating them with the | symbol. This is how multiple messages are set from Alloy XML, and since v1.2.0 it also works in JavaScript:

letscrollingMessage=newScrollingView({message: 'First message|Second message|Third message',
...
})
letscrollingMessage=newScrollingView({messages: ['Every moment is a fresh beginning. – T.S Eliot','Change the world by being yourself. – Amy Poehler','Love For All, Hatred For None. – Khalifatul Masih III'],
...
})

label : string

To display a left-side label set the label property.

The side label text is always bold, on a slightly darker shade of the scrolling view's backgroundColor.

Defaults to: null

letscrollingMessage=newScrollingView({label: 'Breaking News:',
...
})

Design Properties

color : string

Color for the text message(s) and side label in hex value.

Defaults to: #fff

letscrollingMessage=newScrollingView({color: '#79a342',
...
})

backgroundColor : string

Background color for the scrolling view, as a hex triplet.

Defaults to: #BF000000

letscrollingMessage=newScrollingView({backgroundColor: '#53606b',
...
})

height : number/string

ScrollingView height, in platform-specific units.

Defaults to: 28 ( platform default units )

letscrollingMessage=newScrollingView({height: 44...})

shadow : boolean

Set shadow to true to display a drop shadow under the scrolling view.

Defaults to: false

letscrollingMessage=newScrollingView({shadow: true,
...
})

Font Object

Set a font object to set the following properties:

fontFamily: string

Specifies the font family or specific font to use.

Defaults: Uses the default system font

fontSize: Number/String

Font size, in platform-dependent units.

Defaults: 14dp

fontWeight: string

Font weight. Valid values are "bold", "semibold", "normal", "thin", "light" and "ultralight".

The "semibold", "thin", "light" and "ultralight" weights are recognized on iOS only. "thin", "light" and "ultralight" are only available on iOS 8.2 and later.

Defaults: normal

letscrollingMessage=newScrollingView({font: {fontSize: 16,fontWeight: 'bold',fontFamily: 'Gill Sans'}...})

Positioning Properties

top or bottom : number/string

The scrolling view's top OR bottom position. This position is relative to the scrolling view's parent.

You can use px, % or dp values.

Defaults to: undefined

letscrollingMessage=newScrollingView({top: 44,// ORbottom: 0...})

Behavior properties

autoplay : boolean

You can turn off automatic playing by setting the autoplay property to false.

Defaults to: true

letscrollingMessage=newScrollingView({autoplay: false,
...
})

delay : number

Pause the animation between messages in seconds.

Defaults to: 0

letscrollingMessage=newScrollingView({delay: 3,
...
})

speed : number

The speed of the scrolling text, a constant speed no matter the text length, the higher the number the faster the scrolling speed.

Only values greater than 0 are accepted; 0 and negative values are ignored.

Defaults to: 5

letscrollingMessage=newScrollingView({speed: 7,
...
})

random : boolean

To display the messages in random order set random to true.

Since v1.2.0 you can turn it off at any time with update({ random: false }), which restores the original message order.

Defaults to: false

letscrollingMessage=newScrollingView({random: true,
...
})

Update Methods

There are 4 methods to update the content and properties at any time.

  • update()
  • updateLabel()
  • updateBackground()
  • updateMessage() or updateMessages()

update

Is a general purpose method to change any or all of the following properties:

  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • autoplay
  • top or bottom
  • backgroundColor
  • message or messages
  • font object with fontSize, fontWeight, fontFamily

When updating the message ( or messages ), the text will be shown after completing the currently running message.

scrollingMessage.update({top: 0,delay: 0,speed: 10,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform',font: {fontWeight: 'bold'}})

updateMessage/updateMessages

If you need to update only the message or messages, you can use the updateMessage or updateMessages methods.

You can use either of them with a string or an array. A string with | separators is split into multiple messages. Calling them with an empty string or an empty array returns false and keeps the current messages.

The updated text will be shown after completing the currently running message.

scrollingMessage.updateMessage('Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform')scrollingMessage.updateMessages(['Build: Write in JavaScript, run native on any device and OS','Connect: Get mobile-optimized access to any data source','Measure: See usage & adoption, detect crashes, tune performance'])

updateLabel

This method will instantly update the label property.

If the scrolling view does not originally contained a label, it will be add it automatically.

scrollingMessage.updateLabel('Breaking News:')

updateBackground

Use it to change the scrolling view's background color, including the label property if available.

scrollingMessage.updateBackground('#79a342')

Playback & Lifecycle Methods

play

Starts playing the scrolling view. Since v1.2.0 it works even if autoplay is set to false ( autoplay only controls automatic starts ). If a message is already scrolling, calling it again has no effect.

scrollingMessage.play()

pause

Pauses the scrolling view. The message currently on screen finishes its scroll, and no further messages are played until you call play() or resume().

scrollingMessage.pause()

resume

Resumes a paused scrolling view.

scrollingMessage.resume()

destroy

Releases the scrolling view from the library's internal registry ( used for the automatic pause/resume on app background/foreground ) and cancels any pending timers. Call it when closing the window that contains the scrolling view:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

getView

Returns the actual Ti.UI.View so you can add it to your layout ( Classic projects ):

win.add(scrollingMessage.getView())

Events

on( eventName, callback )

Assigns a callback for the paused, resumed and complete events. The callback receives the scrolling view instance as its only argument.

  • paused: fired when the scrolling view is paused ( manually or automatically when the app goes to the background )
  • resumed: fired when the scrolling view is resumed
  • complete: fired every time a message finishes scrolling
scrollingMessage.on('complete',(source)=>{console.log('A message finished scrolling')})scrollingMessage.on('paused',(source)=>{console.log('The scrolling view was paused')})

Debug Mode

name : string

In order to identify each Scrolling View while debuging, you can set the name property at initialization.

letscrollingMessage=newScrollingView({name: 'My Scrolling View',
...
})
<ScrollingViewid="scrollingMessage"module='ti.scroller'name="My Scrolling View" />

When you enable debug mode you'll see multiple outputs with the name of the Scrolling View.

[WARN] ::ti.scroller:: My Scrolling View: Add side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view’s label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view[WARN] ::ti.scroller:: My Scrolling View: Play method[WARN] ::ti.scroller:: My Scrolling View: Update messages method[WARN] ::ti.scroller:: My Scrolling View: Complete event[WARN] ::ti.scroller:: My Scrolling View: Play method

If no name is set, the output will be its id, and if none is set, it will generate an internal one.

debug : bollean

You can debug the scrolling view by setting the debug property to true at initialization or with the update() method.

Defaults to: false

letscrollingMessage=newScrollingView({debug: true,
...
})// ORscrollingMessage.update({debug: true})
<ScrollingViewid="scrollingMessage"module='ti.scroller'debug="true" />

To turn it off

scrollingMessage.update({debug: false})// OR$.scrollingMessage.update({debug: false})

License

Copyright 2021 César Estrada
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

About

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

Topics

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

ti.scroller

Description

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

  • You can create multiple scrolling views and customize them separately
  • Each scrolling view can display one or multiple messages, cycle between them or display them in random order
  • You can update its content at any time ( messages, color, position, delay, etc. )
  • Works with Android & iOS

What's new in v1.2.0

New destroy() method

Every scrolling view is kept in an internal registry so the library can pause/resume all of them when the app goes to the background. Starting with v1.2.0, call destroy() when you close the window that contains a scrolling view, so it gets released from that registry ( otherwise it stays retained for the lifetime of the app ):

win.addEventListener('close',()=>{scrollingMessage.destroy()})

New on() method: paused, resumed and complete events

You can now assign a callback for the paused, resumed and complete events. The callback receives the scrolling view instance:

scrollingMessage.on('complete',(source)=>{// Fired every time a message finishes scrolling})

play() now always plays

play() starts playback even if autoplay is set to false. The autoplay property now only controls automatic starts ( at creation and when setting new messages ).

animate() ( deprecated ) works again

In v1.1.0 the deprecated animate() method became a no-op. It now behaves like play() again, but it will still be deleted in v2.0.0, so use play() instead.

Bug fixes

  • pause() now sticks: pausing during the delay window between messages is no longer reverted by an internal timer.
  • Fixed a race condition that could start two scrolling loops at once when updating messages mid-cycle.
  • The automatic pause/resume on app background/foreground now respects manual pauses: if you paused a scrolling view yourself, it won't auto-resume when the app comes back to the foreground.
  • The | separator for multiple messages in a single string now works everywhere ( it was documented for Alloy but not implemented ).
  • Boolean attributes set from Alloy XML ( autoplay="false", random="false", debug="true" ) now work as expected.
  • Colors in #AARRGGBB format are handled correctly by the side label's darkened background ( the default #BF000000 no longer renders red ).
  • random can now be turned off with update({ random: false }), restoring the original message order.
  • update() called without arguments no longer throws, and update({ speed: 0 }) is ignored instead of freezing the scroller.
  • The messages array you pass is no longer mutated when using random.
  • Message widths are cached per text, so repeated cycles no longer re-measure the same message.
  • updateLabel() now creates the side label on the fly if the scrolling view didn't have one ( as it was always documented ).

Breaking changes in v1.1.0

Autoplaying scrolling views

Each scrolling view will start playing immediately after initialization if either message or messages properties are set.

This means that you no longer need to call the animate() method ( now deprecated ) after initialization.

They won't autoplay if there is no message set at initialization, this is useful when you need to get the data from the internet. They will start playing the moment you set a new message(s) with update() or updateMessage/Messages() methods.

If you set the message(s) property and still don't want the scrolling views to start playing immediately, set the new autoplay property to false.

Then use the play() method ( or resume() ) to start playing the scrolling view when needed. Since v1.2.0, play() starts playback even if autoplay is false. You only need to set autoplay back to true if you want new messages set with update() / updateMessage(s)() to start playing automatically.

New <ScrollingView /> Alloy element

In order to be more like a native Ti element in Alloy projects, you now create your scrolling views with the <ScrollingView> element provided by ti.scroller.js

<ScrollingViewmodule='ti.scroller' ... />

paused and resume App Events

The library listens to the Ti.App lifecycle events paused and resume, so you no longer need to handle them manually. They will pause/resume every scrolling view created in your app.

animate() method Deprecated

The animate() method is deprecated and will be deleted in the future.

Installation in Classic Apps

For Classic Apps, put ti.scroller.js file inside the Resources folder.

Basic usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller lib',backgroundColor: '#fff'})letscrollingMessage=newScrollingView({message: 'Appcelerator Titanium: Everything you need to create great, native mobile apps — All from a single JavaScript code base.'})win.add(scrollingMessage.getView())win.open()

Result

iOS Screen - Example

* low framerate gif

Advanced usage

letScrollingView=require('ti.scroller')letwin=Ti.UI.createWindow({title: 'ti.scroller',backgroundColor: '#fff'})letcontainer=Ti.UI.createView({layout: 'vertical',height: Ti.UI.SIZE})letfamousPeopleQuotes=newScrollingView({top: 8,speed: 7,random: true,color: '#dddfe1',label: 'Famous People:',backgroundColor: '#53606b',messages: ['The greatest glory in living lies not in never falling, but in rising every time we fall. - Nelson Mandela','The way to get started is to quit talking and begin doing. - Walt Disney','Your time is limited, so don\'t waste it living someone else\'s life. Don\'t be trapped by dogma – which is living with the results of other people\'s thinking. - Steve Jobs','If life were predictable it would cease to be life, and be without flavor. - Eleanor Roosevelt','If you look at what you have in life, you\'ll always have more. If you look at what you don\'t have in life, you\'ll never have enough. - Oprah Winfrey','If you set your goals ridiculously high and it\'s a failure, you will fail above everyone else\'s success. - James Cameron','Life is what happens when you\'re busy making other plans. - John Lennon']})letbestQuotesOfAllTimes=newScrollingView({top: 8,speed: 6,label: 'Best Quotes:',backgroundColor: '#79a342',messages: ['Whoever is happy will make others happy too. - Anne Frank','It is during our darkest moments that we must focus to see the light. - Aristotle','Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead','Spread love everywhere you go. Let no one ever come to you without leaving happier. - Mother Teresa','When you reach the end of your rope, tie a knot in it and hang on. - Franklin D. Roosevelt','Don\'t judge each day by the harvest you reap but by the seeds that you plant. - Robert Louis Stevenson','The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt','Tell me and I forget. Teach me and I remember. Involve me and I learn. - Benjamin Franklin','The best and most beautiful things in the world cannot be seen or even touched — they must be felt with the heart. - Helen Keller','Do not go where the path may lead, go instead where there is no path and leave a trail. - Ralph Waldo Emerson']})letmarketStocks=newScrollingView({top: 8,speed: 8,height: 36,debug: true,label: 'Market:',name: 'Market Stocks',message: 'Loading data...',backgroundColor: '#F3650C'})// Simulated API responsesetTimeout(()=>{// Just set the new message(s) with `updateMessages` methodmarketStocks.updateMessages('EUR/USD 1.18664 0 0% · USD/JPY 110.399 0.06 0.05% · GBP/USD 1.38902 0 0% · EUR/JPY 130.9959 0.109 0.08% · GBP/JPY 153.3323 0.116 0.08% · USD/CAD 1.24481 -0.001 -0.08% · XAU/USD 1806.7484 -0.684 -0.04% · AUD/USD 0.74878 0.001 0.13% · USD/CHF 0.91462 -0.001 -0.11% · NZD/USD 0.69921 0.001 0.14%')},3000)container.add(famousPeopleQuotes.getView())container.add(bestQuotesOfAllTimes.getView())container.add(marketStocks.getView())win.add(container)win.open()

Result

iOS Screen - Example

* low framerate gif

Installation in Alloy Apps

For Alloy projects drop ti.scroller in /app/lib folder.

app
└─ lib
└─ ti.scroller.js

In your View file, create a ScrollingView Alloy element and add a module attribute like this module="ti.scroller".

You can set any of the supported attributes directly in the ScrollingView.

IMPORTANT: For multiple messages you'll need to separate them with the | symbol like shown below.

<Alloy>
<NavigationWindow>
<Windowtitle="ti.scroller">
<ScrollingViewid="scrollingMessage"module='ti.scroller'backgroundColor="#c91326"label="Famous Quotes:"speed="4"delay="2"height="32"random="true"top="0" font.fontFamily="Gill Sans" font.fontWeight="semibold" font.fontSize="16"message="Whoever is happy will make others happy too. - Anne Frank|It is during our darkest moments that we must focus to see the light. - Aristotle|Always remember that you are absolutely unique. Just like everyone else. - Margaret Mead" />
</Window>
</NavigationWindow>
</Alloy>

Result

iOS Screen - Example

* low framerate gif

In your controller you can call any of the available methods: update, updateLabel, updateMessage/updateMessages, updateBackground, play, pause, resume, destroy or on at anytime.

$.scrollingMessage.update({top: 48,delay: 3,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform'})

Important consideration

To prevent unexpected behaviors, the library itself listens to the following Ti.App events, so you don't need to add any listener:

  • paused event: In order to pause the scrolling effect while the app is in the background
  • resume event: To resume scrolling when in the foreground.

They will handle every scrolling view created in your app. Since v1.2.0, a scrolling view that you paused manually stays paused when the app comes back to the foreground.

Remember to call destroy() when closing a window that contains scrolling views, so they get released from the internal registry:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

Customization

You can customize the text color, background color, vertical position, font size, font weight, font family, scrolling speed, delay between messages, autoplay messages, random order display, side label text, name and debug mode with the following properties:

  • id
  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • shadow
  • autoplay
  • top/bottom
  • backgroundColor
  • message/messages
  • font object with fontSize, fontWeight, fontFamily

Content Properties

message/messages : array/string

The text to display can be set with message or messages property using an array ( for a single message you can set it using a string ).

You can also pass multiple messages in a single string by separating them with the | symbol. This is how multiple messages are set from Alloy XML, and since v1.2.0 it also works in JavaScript:

letscrollingMessage=newScrollingView({message: 'First message|Second message|Third message',
...
})
letscrollingMessage=newScrollingView({messages: ['Every moment is a fresh beginning. – T.S Eliot','Change the world by being yourself. – Amy Poehler','Love For All, Hatred For None. – Khalifatul Masih III'],
...
})

label : string

To display a left-side label set the label property.

The side label text is always bold, on a slightly darker shade of the scrolling view's backgroundColor.

Defaults to: null

letscrollingMessage=newScrollingView({label: 'Breaking News:',
...
})

Design Properties

color : string

Color for the text message(s) and side label in hex value.

Defaults to: #fff

letscrollingMessage=newScrollingView({color: '#79a342',
...
})

backgroundColor : string

Background color for the scrolling view, as a hex triplet.

Defaults to: #BF000000

letscrollingMessage=newScrollingView({backgroundColor: '#53606b',
...
})

height : number/string

ScrollingView height, in platform-specific units.

Defaults to: 28 ( platform default units )

letscrollingMessage=newScrollingView({height: 44...})

shadow : boolean

Set shadow to true to display a drop shadow under the scrolling view.

Defaults to: false

letscrollingMessage=newScrollingView({shadow: true,
...
})

Font Object

Set a font object to set the following properties:

fontFamily: string

Specifies the font family or specific font to use.

Defaults: Uses the default system font

fontSize: Number/String

Font size, in platform-dependent units.

Defaults: 14dp

fontWeight: string

Font weight. Valid values are "bold", "semibold", "normal", "thin", "light" and "ultralight".

The "semibold", "thin", "light" and "ultralight" weights are recognized on iOS only. "thin", "light" and "ultralight" are only available on iOS 8.2 and later.

Defaults: normal

letscrollingMessage=newScrollingView({font: {fontSize: 16,fontWeight: 'bold',fontFamily: 'Gill Sans'}...})

Positioning Properties

top or bottom : number/string

The scrolling view's top OR bottom position. This position is relative to the scrolling view's parent.

You can use px, % or dp values.

Defaults to: undefined

letscrollingMessage=newScrollingView({top: 44,// ORbottom: 0...})

Behavior properties

autoplay : boolean

You can turn off automatic playing by setting the autoplay property to false.

Defaults to: true

letscrollingMessage=newScrollingView({autoplay: false,
...
})

delay : number

Pause the animation between messages in seconds.

Defaults to: 0

letscrollingMessage=newScrollingView({delay: 3,
...
})

speed : number

The speed of the scrolling text, a constant speed no matter the text length, the higher the number the faster the scrolling speed.

Only values greater than 0 are accepted; 0 and negative values are ignored.

Defaults to: 5

letscrollingMessage=newScrollingView({speed: 7,
...
})

random : boolean

To display the messages in random order set random to true.

Since v1.2.0 you can turn it off at any time with update({ random: false }), which restores the original message order.

Defaults to: false

letscrollingMessage=newScrollingView({random: true,
...
})

Update Methods

There are 4 methods to update the content and properties at any time.

  • update()
  • updateLabel()
  • updateBackground()
  • updateMessage() or updateMessages()

update

Is a general purpose method to change any or all of the following properties:

  • name
  • color
  • label
  • delay
  • speed
  • debug
  • height
  • random
  • autoplay
  • top or bottom
  • backgroundColor
  • message or messages
  • font object with fontSize, fontWeight, fontFamily

When updating the message ( or messages ), the text will be shown after completing the currently running message.

scrollingMessage.update({top: 0,delay: 0,speed: 10,label: 'Appcelerator:',message: 'Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform',font: {fontWeight: 'bold'}})

updateMessage/updateMessages

If you need to update only the message or messages, you can use the updateMessage or updateMessages methods.

You can use either of them with a string or an array. A string with | separators is split into multiple messages. Calling them with an empty string or an empty array returns false and keeps the current messages.

The updated text will be shown after completing the currently running message.

scrollingMessage.updateMessage('Build great mobile experiences faster - Native apps. Mobile APIs. Real-time analytics. One Platform')scrollingMessage.updateMessages(['Build: Write in JavaScript, run native on any device and OS','Connect: Get mobile-optimized access to any data source','Measure: See usage & adoption, detect crashes, tune performance'])

updateLabel

This method will instantly update the label property.

If the scrolling view does not originally contained a label, it will be add it automatically.

scrollingMessage.updateLabel('Breaking News:')

updateBackground

Use it to change the scrolling view's background color, including the label property if available.

scrollingMessage.updateBackground('#79a342')

Playback & Lifecycle Methods

play

Starts playing the scrolling view. Since v1.2.0 it works even if autoplay is set to false ( autoplay only controls automatic starts ). If a message is already scrolling, calling it again has no effect.

scrollingMessage.play()

pause

Pauses the scrolling view. The message currently on screen finishes its scroll, and no further messages are played until you call play() or resume().

scrollingMessage.pause()

resume

Resumes a paused scrolling view.

scrollingMessage.resume()

destroy

Releases the scrolling view from the library's internal registry ( used for the automatic pause/resume on app background/foreground ) and cancels any pending timers. Call it when closing the window that contains the scrolling view:

win.addEventListener('close',()=>{scrollingMessage.destroy()})

getView

Returns the actual Ti.UI.View so you can add it to your layout ( Classic projects ):

win.add(scrollingMessage.getView())

Events

on( eventName, callback )

Assigns a callback for the paused, resumed and complete events. The callback receives the scrolling view instance as its only argument.

  • paused: fired when the scrolling view is paused ( manually or automatically when the app goes to the background )
  • resumed: fired when the scrolling view is resumed
  • complete: fired every time a message finishes scrolling
scrollingMessage.on('complete',(source)=>{console.log('A message finished scrolling')})scrollingMessage.on('paused',(source)=>{console.log('The scrolling view was paused')})

Debug Mode

name : string

In order to identify each Scrolling View while debuging, you can set the name property at initialization.

letscrollingMessage=newScrollingView({name: 'My Scrolling View',
...
})
<ScrollingViewid="scrollingMessage"module='ti.scroller'name="My Scrolling View" />

When you enable debug mode you'll see multiple outputs with the name of the Scrolling View.

[WARN] ::ti.scroller:: My Scrolling View: Add side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to side label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view’s label[WARN] ::ti.scroller:: My Scrolling View: Apply properties to scrolling view[WARN] ::ti.scroller:: My Scrolling View: Play method[WARN] ::ti.scroller:: My Scrolling View: Update messages method[WARN] ::ti.scroller:: My Scrolling View: Complete event[WARN] ::ti.scroller:: My Scrolling View: Play method

If no name is set, the output will be its id, and if none is set, it will generate an internal one.

debug : bollean

You can debug the scrolling view by setting the debug property to true at initialization or with the update() method.

Defaults to: false

letscrollingMessage=newScrollingView({debug: true,
...
})// ORscrollingMessage.update({debug: true})
<ScrollingViewid="scrollingMessage"module='ti.scroller'debug="true" />

To turn it off

scrollingMessage.update({debug: false})// OR$.scrollingMessage.update({debug: false})

License

Copyright 2021 César Estrada
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.

About

A simple library to create a marquee-like elements in your Appcelerator Titanium Apps for both Classic and Alloy projects.

Topics

Resources

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages