Corona newScrollView hideScrollBar still displays scroll bar - android

I declare Scroll View like this:
sv = widget.newScrollView{
top = properties.y,
left = properties.x,
width = properties.moreGamesPanelWidth,
height = properties.height,
scrollWidth = properties.moreGamesPanelWidth,
scrollHeight = lg.contentHeight,
hideBackground = true,
isBounceEnabled = false,
horizontalScrollDisabled = true,
isLocked = lock,
listener = widgetTouchListener,
hideScrollBar = true,
}
Unfortunately scroll bar is still visible, no matter what I set in "hideScrollBar".
Is there any possibility to hide the scroll bar?

I found an issue!
It happens when you declare two or more scrollViews. The last of them overrides the "hideScrollBar" setting. So there is no option to have two scrollViews, one with and one without scrollBar.
Here is the code which proves the issue
properties.lua
local properties = {}
--device dimensions
properties.width = display.contentWidth + display.screenOriginX * -2
properties.height = display.contentHeight + display.screenOriginY * -2
properties.x = display.screenOriginX
properties.y = display.screenOriginY
properties.center = { x = properties.x + properties.width / 2, y = properties.y + properties.height / 2 }
return properties
main.lua
display.setStatusBar( display.HiddenStatusBar )
local properties = require("properties")
local widget = require("widget")
local sceneGroup = display.newGroup()
local lg = display.newGroup()
local lg2 = display.newGroup()
local bg = display.newRect(properties.center.x, properties.center.y, properties.width, properties.height)
bg:setFillColor(0.2, 0.2, 0.1)
sceneGroup:insert(bg)
local menuRect1 = display.newRect(100, 50, 200, 100)
menuRect1:setFillColor(0.8, 0.1, 0.1)
lg:insert(menuRect1)
local menuRect2 = display.newRect(100, 160, 200, 100)
menuRect2:setFillColor(0.1, 0.1, 0.9)
lg:insert(menuRect2)
local menuRect11 = display.newRect(100, 50, 200, 100)
menuRect11:setFillColor(0.8, 0.1, 0.1)
lg2:insert(menuRect11)
local menuRect22 = display.newRect(100, 160, 200, 100)
menuRect22:setFillColor(0.1, 0.1, 0.9)
lg2:insert(menuRect22)
local sv
local sv2
sv = widget.newScrollView{
top = properties.center.y - lg.contentHeight * 0.5 - 100,
left = properties.center.x - lg.contentWidth * 0.5,
width = lg.contentWidth +20,
height = lg.contentHeight -80 ,
scrollHeight = lg.contentHeight,
hideBackground = true,
isBounceEnabled = false,
hideScrollBar = true,
horizontalScrollDisabled = true,
isLocked = false,
}
sv2 = widget.newScrollView{
top = properties.center.y - lg.contentHeight * 0.5 + 100,
left = properties.center.x - lg.contentWidth * 0.5 ,
width = lg.contentWidth +20,
height = lg.contentHeight -80 ,
scrollHeight = lg.contentHeight,
hideBackground = true,
isBounceEnabled = false,
hideScrollBar = false,
horizontalScrollDisabled = true,
isLocked = false,
}
sv:insert(lg)
sv2:insert(lg2)
sceneGroup:insert(sv)
sceneGroup:insert(sv2)

The issue is that corona's documentation is wrong, the property to set scroll bar visibility is not hideScrollBar = false it is autoHideScrollBar = false.
Had me stuck for days!

Related

pytorch KAIR example on Android

I stuck trying to trace/scipt ffdnet KAIR's model to android. Model's forward looks like:
def forward(self, x): #, paddingBottom, paddingRight): #, sigma):
noise_level_model = 15
sigma = torch.full((1, 1, 1, 1), noise_level_model / 255.).type_as(x)
h, w = x.size()[-2:]
paddingBottom = int(np.ceil(h/2)*2-h)
paddingRight = int(np.ceil(w/2)*2-w)
x = torch.nn.ReplicationPad2d((0, paddingRight, 0, paddingBottom))(x)
x = self.m_down(x)
# m = torch.ones(sigma.size()[0], sigma.size()[1], x.size()[-2], x.size()[-1]).type_as(x).mul(sigma)
m = sigma.repeat(1, 1, x.size()[-2], x.size()[-1])
x = torch.cat((x, m), 1)
x = self.model(x)
x = self.m_up(x)
x = x[..., :h, :w]
return x
If I trace that I get some warnings about padding arguments but model works on Android. Problem is that it isn't work with input of different sizes, only size same as 'test1.jpeg':
model_name = 'ffdnet_color'
model_pool = 'model_zoo'
model_path = os.path.join(model_pool, model_name + '.pth')
n_channels = 3
nc = 96
nb = 12
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = net(in_nc=n_channels, out_nc=n_channels, nc=nc, nb=nb, act_mode='R')
model.load_state_dict(torch.load(model_path), strict=True)
model.eval()
for k, v in model.named_parameters():
v.requires_grad = False
model = model.to(device)
img = 'testsets/myset/test1.jpeg'
img_name, ext = os.path.splitext(os.path.basename(img))
img_L = util.imread_uint(img, n_channels=n_channels)
img_L = util.uint2single(img_L)
noise_level_model = 15
img_L = util.single2tensor4(img_L)
img_L = img_L.to(device)
sigma_ = torch.full((1, 1, 1, 1), noise_level_model / 255)
sigma = torch.full((1, 1, 1, 1), noise_level_model / 255.).type_as(img_L)
traced_model = torch.jit.trace(model, img_L)
traced_optimized = optimize_for_mobile(traced_model)
save_path = os.path.splitext(os.path.basename(model_path))[0] + '-mobile.pth'
traced_optimized.save(save_path)
I've tried to script model with traced_model = torch.jit.script(model) but got errors:
TypeError: cannot create weak reference to 'numpy.ufunc' object
What should I do to achieve model works with different input size on mobile?
I encountered a similar issue. It was due to my model using numpy math operations (which are numpy.ufunc). I fixed the issue by replacing all of numpy ufuncs (i.e. np.add, np.ceil, and +, - etc on ndarrays) with corresponding torch versions (i.e. torch.add, torch.sub etc).

storyboard.removeScene("scene name") is not working

I am new to corona sdk and trying to build sample in it. i want to get back to main screen automatically after some time by destroying my scene(i mean that scene destroys itself after some particular time and user get back to main screen).I know that for some this may sound silly but i beginner to Corona
Here is my code of main.lua :-
local storyboard = require "storyboard"
local widget = require( "widget" )
--/**/ widget.setTheme( "widget_theme_android" )
local json = require "json"
local particleDesigner = require( "particleDesigner" )
local physics = require( "physics" )
physics.start()
-------------------------------------------------------------------------------
local sky = display.newImage( "sky.jpg",contentCenterX,display.contentCenterY)
local emitter
emitter = particleDesigner.newEmitter("air_stars.json")
emitter.x = (contentCenterX)
emitter.y = (contentCenterY)
local button = {}
y= -50
for count = 1,3 do
y = y + 110
x = 20
for insideCount = 1,3 do
x = x + 110
button[count] = display.newImage("1.png")
button[count].x = x
button[count].y = y
local container = display.newContainer( 0, 0 )
container:translate(button[count].x-40, button[count].y-40)
local bkgd = display.newImage( container, "2.png" )
function buttonTap(self)
button[count].touch = transition.to(container,{time=3000, height = button[count].height+x, width = button[count].width+y, onComplete = StartGame})
function StartGame()
storyboard.purgeScene("main")
if count == 1 and insideCount == 1 then
storyboard:gotoScene("bridge")
elseif count == 1 and insideCount == 2 then
storyboard:gotoScene("Heli")
end
end
end
button[count]:addEventListener( "touch", buttonTap)
end
end
return storyboard
And Here is my bridge.lua file :- (http://piratepad.net/ep/pad/view/ro.JR1Bpt1qkA$/latest)
Any help will be appreciated
Thanks
Hi sid here you go:
_W = display.contentWidth;
_H = display.contentHeight;
local button = {}
x = -20
for count = 1,3 do
x = x + 90
y = 20
for insideCount = 1,3 do
y = y + 90
button[count] = display.newImage("imgs/one.png");
button[count].x = x;
button[count].y = y;
local container = display.newContainer( 0, 0 )
container:translate(button[count].x, button[count].y)
local bkgd = display.newImage( container, "imgs/two.png" )
function buttonTap(self)
button[count].touch = transition.to(container,{time=3000, height = button[count].height+x, width = button[count].width+y})
end
button[count]:addEventListener( "touch", buttonTap )
end
end
just add this to the bridge.lua
local function goBack()
storyboard:gotoScene("buttons")
end
timer.performWithDelay( 3000, goBack, 1 )
and this to main.lua
storyboard.purgeOnSceneChange = true

zoom out larger image to smaller in jrcrop image cropping plugin for angularjs

I am trying capture images using camera plugin of cordova and crop image using jrCrop plugin in angularjs.
Both camera plugin of cordova and jrCrop plugin working well for cropping an image and store in file system.
problem in is there preview when smaller image is croping then container of jrCrop display image well but when the larger image is use for croping then it's not fit on the preview display.
original image (screenshot - 1)
problem for large image (screenshot - 2)
was i wanted to be (screenshot - 3)
Is there any method or solution for zoom out the larger image to fit in preview display of jrCrop.
Intialized jrCrop plugin :
$jrCrop.crop({
url: imageSrc, //get image path from camera plugin
width: $scope.imgWidth,
height: $scope.imgHeight,
}).then(function(canvas){
UserImages.tmpImage=canvas.toDataURL();
$location.path('/crop-image');
});
Code : jrCrop.js
angular.module('ionic')
.factory('$jrCrop', [
'$ionicModal',
'$rootScope',
'$q',
function($ionicModal, $rootScope, $q) {
var template = '<div class="jr-crop modal" ng-style="{height: heightGap + \'px\'}" style="min-height:50px;" >' +
'<div class="jr-crop-title fmed-reg">Pinch to zoom in/out <br> Position photo with your finger</div>' +
'<div class="jr-crop-center-container">' +
'<div class="jr-crop-img" ng-style="{width: width + \'px\', height: height + \'px\'}"></div>' +
'</div>' +
'<div class="jr-crop-center-container" style="opacity:0.5; background:#fff;border:1px solid #000;" >' +
'<div class="jr-crop-select" style="overflow: hidden;" ng-style="{width: width + \'px\', height: height + \'px\'}"></div>' +
'</div>' +
'<div class="bar bar-footer bar-dark jr-crop-footer">' +
'<button class="button button-clear fmed-reg jr-choose" ng-click="cancel()">Cancel</button>' +
'<div class="title">{{title}}</div>' +
'<button class="button button-clear fmed-reg jr-choose" ng-click="crop()">Choose</button>' +
'</div>' +
'</div>';
var jrCropController = ionic.views.View.inherit({
promise: null,
imgWidth: null,
imgHeight: null,
// Elements that hold the cropped version and the full
// overlaying image.
imgSelect: null,
imgFull: null,
// Values exposed by scaling and moving. Needed
// to calculate the result of cropped image
posX: 0,
posY: 0,
scale: 1,
initialize: function(options) {
var self = this;
this.options = options;
this.promise = $q.defer();
this.loadImage().then(function(elem) {
self.imgWidth = elem.naturalWidth;
self.imgHeight = elem.naturalHeight;
self.options.modal.el.querySelector('.jr-crop-img').appendChild(self.imgSelect = elem.cloneNode());
self.options.modal.el.querySelector('.jr-crop-select').appendChild(self.imgFull = elem.cloneNode());
self.bindHandlers();
});
// options === scope. Expose actions for modal.
this.options.cancel = this.cancel.bind(this);
this.options.crop = this.crop.bind(this);
},
cancel: function() {
var self = this;
this.options.modal.remove().then(function() {
self.promise.reject('canceled');
});
},
/**
* This is where the magic happens
*/
bindHandlers: function() {
var self = this,
last_scale,
last_posX = 0, last_posY = 0,
min_pos_x = 0, min_pos_y = 0,
max_pos_x = 0, max_pos_y = 0,
transforming_correctX = 0, transforming_correctY = 0,
scaleMin,
image_ratio = self.imgWidth / self.imgHeight,
cropper_ratio = self.options.width / self.options.height;
if (cropper_ratio < image_ratio) {
scaleMin = self.options.height / self.imgHeight;
} else {
scaleMin = self.options.width / self.imgWidth;
}
function setPosWithinBoundaries() {
calcMaxPos();
if (self.posX > min_pos_x) {
self.posX = min_pos_x;
}
if (self.posX < max_pos_x) {
self.posX = max_pos_x;
}
if (self.posY > min_pos_y) {
self.posY = min_pos_y;
}
if (self.posY < max_pos_y) {
self.posY = max_pos_y;
}
}
/**
* Calculate the minimum and maximum positions.
* This took some headaches to write, good luck
* figuring this out.
*/
function calcMaxPos() {
// Calculate current proportions of the image.
var currWidth = self.scale * self.imgWidth;
var currHeight = self.scale * self.imgHeight;
// Images are scaled from the center
min_pos_x = (currWidth - self.imgWidth) / 2;
min_pos_y = (currHeight - self.imgHeight) / 2;
max_pos_x = -(currWidth - min_pos_x - self.options.width);
max_pos_y = -(currHeight - min_pos_y - self.options.height);
}
// Based on: http://stackoverflow.com/questions/18011099/pinch-to-zoom-using-hammer-js
ionic.onGesture('touch transform drag dragstart dragend', function(e) {
switch (e.type) {
case 'touch':
last_scale = self.scale;
break;
case 'drag':
self.posX = last_posX + e.gesture.deltaX - transforming_correctX;
self.posY = last_posY + e.gesture.deltaY - transforming_correctY;
setPosWithinBoundaries();
break;
case 'transform':
self.scale = Math.max(scaleMin, Math.min(last_scale * e.gesture.scale, 10));
setPosWithinBoundaries();
break;
case 'dragend':
last_posX = self.posX;
last_posY = self.posY;
$(".jr-crop-select").show();
break;
case 'dragstart':
last_scale = self.scale;
// After scaling, hammerjs needs time to reset the deltaX and deltaY values,
// when the user drags the image before this is done the image will jump.
// This is an attempt to fix that.
if (e.gesture.deltaX > 1 || e.gesture.deltaX < -1) {
transforming_correctX = e.gesture.deltaX;
transforming_correctY = e.gesture.deltaY;
} else {
transforming_correctX = 0;
transforming_correctY = 0;
}
break;
}
var transform ='translate3d(' + self.posX + 'px,' + self.posY + 'px, 0) ' +'scale3d(' + self.scale + ',' + self.scale + ', 0)';
self.imgSelect.style[ionic.CSS.TRANSFORM] = transform;
self.imgFull.style[ionic.CSS.TRANSFORM] = transform;
}, self.options.modal.el);
},
/**
* Calculate the new image from the values calculated by
* user input. Return a canvas-object with the image on it.
*
* Note: It doesn't actually downsize the image, it only returns
* a cropped version. Since there's inconsistenties in image-quality
* when downsizing it's up to the developer to implement this. Preferably
* on the server.
*/
crop: function() {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
// Canvas size is original proportions but scaled down.
canvas.width = this.options.width / this.scale;
canvas.height = this.options.height / this.scale;
// The full proportions
var currWidth = this.imgWidth * this.scale;
var currHeight = this.imgHeight * this.scale;
// Because the top/left position doesn't take the scale of the image in
// we need to correct this value.
var correctX = (currWidth - this.imgWidth) / 2;
var correctY = (currHeight - this.imgHeight) / 2;
var sourceX = (this.posX - correctX) / this.scale;
var sourceY = (this.posY - correctY) / this.scale;
context.drawImage(this.imgFull, sourceX, sourceY);
this.options.modal.remove();
this.promise.resolve(canvas);
},
/**
* Load the image and return the element.
* Return Promise that will fail when unable to load image.
*/
loadImage: function() {
var promise = $q.defer();
// Load the image and resolve with the DOM node when done.
angular.element('<img />')
.bind('load', function(e) {
promise.resolve(this);
})
.bind('error', promise.reject)
.prop('src', this.options.url);
//this.options.heightGap=200;
// Return the promise
return promise.promise;
}
});
return {
crop: function(options) {
var scope = $rootScope.$new(true);
ionic.Utils.extend(scope, options);
scope.modal = $ionicModal.fromTemplate(template, {
scope: scope
});
// Show modal and initialize cropper.
return scope.modal.show().then(function() {
return (new jrCropController(scope)).promise.promise;
});
}
};
}]);
Problem Solve With Official Update Of These Plugin jr-Crop.

Adding Endless parallax background in cocos2d android

I am working on CoCos2d with android.I want to add an endless scrolling background to my Screen by using CCParallaxNode.
I am able to add background and move it but after the completion of that move action the screen goes black.
Can someone help me out?
My code is
CCParallaxNode parallaxNode;
CCSprite spacedust1;
CCSprite spacedust2;
CCSprite planetsunrise;
CCSprite galaxy;
CCSprite spacialanomaly;
CCSprite spacialanomaly2;
parallaxNode = CCParallaxNode.node();
spacedust1 = CCSprite.sprite("bg_front_spacedust.png");
spacedust2 = CCSprite.sprite("bg_front_spacedust.png");
planetsunrise = CCSprite.sprite("bg_planetsunrise.png");
galaxy = CCSprite.sprite("bg_galaxy.png");
spacialanomaly = CCSprite.sprite("bg_spacialanomaly.png");
spacialanomaly2 = CCSprite.sprite("bg_spacialanomaly2.png");
// 3) Determine relative movement speeds for space dust and background
// CGPoint cgPoint = CGPoint.ccp(0.1, 0.1);
CGPoint dustSpeed = CGPoint.ccp(10, 10);
CGPoint bgSpeed = CGPoint.ccp(5, 5);
// CGPoint bgSpeed = ccp(0.05, 0.05);
parallaxNode.addChild(spacedust1, 0, dustSpeed.x, dustSpeed.y, 0,
winSize.height / 2);
parallaxNode.addChild(spacedust2, 0, dustSpeed.x, dustSpeed.y,
spacedust1.getContentSize().width, winSize.height / 2);
parallaxNode.addChild(galaxy, -1, bgSpeed.x, bgSpeed.y, 0, 10);
parallaxNode.addChild(planetsunrise, -1, bgSpeed.x, bgSpeed.y, 600, 5);
parallaxNode
.addChild(spacialanomaly, -1, bgSpeed.x, bgSpeed.y, 900, 20);
parallaxNode.addChild(spacialanomaly2, -1, bgSpeed.x, bgSpeed.y, 1500,
30);
CCIntervalAction go = CCMoveBy.action(4, CGPoint.ccp(winSize.width, 0));
CCIntervalAction goBack = go.reverse();
CCIntervalAction seq = CCSequence.actions(go, goBack);
CCRepeatForever action = CCRepeatForever.action(goBack);
parallaxNode.runAction(action);
I see that since not a single answer worked for you. I will provide a simple code which will help you for your parralax scrolling background.
Add this code in your game layers constructor
background1 = CCSprite.sprite("bg2.png");
background2 = CCSprite.sprite("bg2.png");
background1.setPosition(CGPoint.ccp(winSize.width*0.5f,winSize.height*0.5f));
addChild(background1);
background2.setPosition(CGPoint.ccp(winSize.width+winSize.width*0.5f,winSize.height*0.5f));
addChild(background2);
and a scroll method which is scheduled every millisecond.
add this in constructor
this.schedule("scroll");
and now the scroll method.
public void scroll(float dt) {
CGPoint pos1 = background1.getPosition();
CGPoint pos2 = background2.getPosition();
pos1.x -= 5.0f;
pos2.x -= 5.0f;
if(pos1.x <=-(winSize.width*0.5f) )
{
pos1.x = pos2.x + winSize.width;
}
if(pos2.x <=-(winSize.width*0.5f) )
{
pos2.x = pos1.x + winSize.width;
}
background1.setPosition(pos1);
background2.setPosition(pos2);
}
mark my answer if it worked.
Call this method from the class Constructor. I found this trick from Example : "shotingblock-master" available on github...
private void endlessBackground() {
// Create the two background sprites which will alternate
_oddBackground = CCSprite.sprite("blue_background.png");
_evenBackground = CCSprite.sprite("blue_background.png");
// One starts dead centre and one starts exactly one screen height above
oddBackground.setPosition(_winSize.width / 2, _winSize.height / 2);
evenBackground.setPosition(_winSize.width / 2, _winSize.height
+ (_winSize.height / 2));
// Schedule the scrolling action
schedule("scroll");
// Add sprites to the layer
addChild(_oddBackground).addChild(_evenBackground);
}
public void scroll(float dt) {
// move them 100*dt pixels down
_oddBackground.setPosition(_oddBackground.getPosition().x,
_oddBackground.getPosition().y - 150 * dt);
_evenBackground.setPosition(_evenBackground.getPosition().x,
_evenBackground.getPosition().y - 150 * dt);
// reset position when they are off from view.
if (_oddBackground.getPosition().y < -_winSize.height / 2) {
_oddBackground.setPosition(_winSize.width / 2, _winSize.height / 2);
_evenBackground.setPosition(_winSize.width / 2, _winSize.height
+ (_winSize.height / 2));
}
}
}
IT works excellent in my case. May be it'll help full for you.
try using this:
CCTexture2D *texture = CCTextureCache::sharedTextureCache()->addImage("pic.png");
ccTexParams params = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT};
texture->setTexParameters(&params);
CCSprite *sprite = CCSprite::spriteWithTexture(texture, CCRectMake(0, 0, 90, 90));
and make sure that The image's height and width must be power of 2.
It looks like the CCRepeatForever action is only running it goBack, which means that it's not reversing. Try the following:
CCIntervalAction go = CCMoveBy.action(4, CGPoint.ccp(winSize.width, 0));
CCIntervalAction goBack = go.reverse();
CCIntervalAction seq = CCSequence.actions(go, goBack);
CCRepeatForever action = CCRepeatForever.action(seq); // change to seq instead of goBack
parallaxNode.runAction(action);
This is trick for make it happen. You can Use the large png and working on it or check the sample test code which is available in coocs2d-android library
CCSprite background = CCSprite.sprite("background.png");
// create a void node, a parent node
CCParallaxNode voidNode = CCParallaxNode.node();
// background image is moved at a ratio of 0.4x, 0.5y
voidNode.addChild(background, -1, 0.4f, 0.5f, 0, 0);
// write your own code for the parallax node
CCIntervalAction goUp = CCMoveBy.action(4, CGPoint.make(0,-200));
CCIntervalAction goDown = goUp.reverse();
CCIntervalAction go = CCMoveBy.action(8, CGPoint.make(-1000, 0));
CCIntervalAction goBack = go.reverse();
CCIntervalAction seq = CCSequence.actions(goUp, go, goDown, goBack);
voidNode.runAction(CCRepeatForever.action(seq));
addChild(voidNode);
Please check out below link for Parallax vertical endless background:
http://kalpeshsantoki.blogspot.in/2014/07/create-vertical-endless-parallax.html
CGSize winSize = CCDirector.sharedDirector().displaySize();
//I made graphics for screen 720*1200....so I made this dynamic scale to support multiple screens
float sX = winSize.width / 720.0f;
float sY = winSize.height / 1200.0f;
background = CCVerticalParallaxNode.node(sX, sY, true);
background.addEntity(1f, "background.png", 0);
background.addEntity(3, "road_simple.png", winSize.width / 2);
background.addEntity(1.7f, "road_side.png", 0);
addChild(background);

Measure volume on tap of button

Hey below is a code that measure volume at runtime. I want a button which when tapped once starts volume as in this code and then when tapped again stops measuring.
local g = display.newGroup()
local function newBar()
local bar = display.newLine( 0, 0, 1, 0 )
bar:setColor( 0, 55, 100, 20 )
bar.width = 7
bar.y=400
bar.x=20
return bar
end
local volumeBar = newBar()
volumeBar.y = 309
volumeBar.x = 320
function volumeBar:enterFrame ( event )
local v = 20*math.log(r:getTunerVolume())
local MINTHRESH = 20
local LEFTMARGIN = 20
local ONE = -1
local v2 = MINTHRESH + math.max (v, -MINTHRESH)
v2 = (display.contentWidth - 20 ) * v2 / MINTHRESH
local neg = math.max ( 20, v2 )
volumeBar.xScale = neg * ONE
if (v >= -4) then
volumeBar:setColor( 110, 110, 20, 200 )
elseif (v < -4) then
volumeBar:setColor( 235, 80, 80, 233)
end
end
Runtime:addEventListener("enterFrame", volumeBar)
g:insert(volumeBar)
Help please cause here there are 2 taps that need to be done.
Add a tap event listener to the button and call Runtime:removeEventListener("enterFrame", volumeBar) in the tap function.

Categories

Resources