WinRT - how to tell if device is on battery or wall powered? - windows-runtime

Say I want to tailor my application to throttle throughput when running on battery power, but go full bore when it's plugged to a wall socket.
Is there an event to plug into to detect when these things happen like when internet connection is detected?

Apparently there's this trigger you can plug in to. It only fires off when the device is plugged in.

IE and WebView http://ie.microsoft.com/testdrive/HTML5/PowerMeter/Default.html can poll the cpu power states
eg: http://apps.microsoft.com/windows/app/plugged-in/2b91b1e1-9e30-4a96-bc95-b196e46bef9d
In c#/xaml try:
XAML
<WebView x:Name="BatteryCheck_WV" Source="ms-appx-web:///Assets/JSBatteryCheck.html" Height="50" Width="50" Visibility="Collapsed" />
c#
var PeriodicTimer = ThreadPoolTimer.CreatePeriodicTimer(async (timer) =>
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low,
async () =>
{
if (Window.Current.Visible) BatteryStatus.IsOn= Convert.ToBoolean(await BatteryCheck_WV.InvokeScriptAsync("IsPluggedIn", null));
});
}, new TimeSpan(0, 0, 0, 1, 0));
html/js
<!DOCTYPE html>
<html>
<head>
<title>JSBatteryCheck</title>
<script type="text/javascript">
var batterytimeOut;
var timeOutGo = true;
var lastDisplayUpdateTime = new Date();
var MilliSeconds = 1000;
var displayUpdateInterval = 200;
var values = [];
var maxValues = displayUpdateInterval;
var PluggedIn = true;
var currentTicksPerMilliSecond = 0;
function GetTicksPerSecond() {
if ((new Date() - lastDisplayUpdateTime) >= displayUpdateInterval) {
lastDisplayUpdateTime = new Date;
currentTicksPerMilliSecond = Avg();
values = [];
if (!isNaN(currentTicksPerMilliSecond)) {
PluggedIn = (currentTicksPerMilliSecond > 9) ? false : true;
}
}
else Tick();
if (timeOutGo) batterytimeOut = setTimeout(function () { GetTicksPerSecond() }, 1);
}
function StartTimer() {
timeOutGo = true;
GetTicksPerSecond();
return "";
}
function Tick() {
if (values.length > maxValues) values.shift();
else values.push(new Date());
}
function Avg() {
if (values.length > 1) {
var earliest = values[0];
var latest = values[values.length - 1];
var elapsed = latest - earliest;
var elapsedSeconds = elapsed / MilliSeconds;
var avg = MilliSeconds / ((values.length - 1) / elapsedSeconds);
return parseInt(avg);
}
else return NaN;
}
function StopTimeOut() {
clearTimeout(batterytimeOut);
batterytimeOut = null;
timeOutGo = false;
}
function IsPluggedIn() {
return String(PluggedIn);
}
</script>
</head>
<body onload="GetTicksPerSecond()">
<div id="PowerStatus"></div>
<button onclick="StopTimeOut()">Stop timeout</button>
</body>
</html>
For background tasks SystemTriggerType.BackgroundWorkCostChange event is best but needs lock screen access

Related

How to syncronize iframes (html5-banner)?

I would like to synchronize two advertising banners (html5) on a website. The banners are displayed in iframes. I have unfortunately only access to the code of the two banner. I'm trying to use localconnection.js
The html5 banner I create with adobe animate. My two test banners contain a very simple animation. The one banner is a little shorter, in order to demonstrate the temporal "diverge" with different banners. The animation of the right banner I stopped in the first picture (directly behind the Connect) - which should then be "pushed" from the left banner. Is that right? And if so, how do I do that?
HTML - Banner 1:
<!DOCTYPE html>
<!--
NOTES:
1. All tokens are represented by '$' sign in the template.
2. You can write your code only wherever mentioned.
3. All occurrences of existing tokens will be replaced by their appropriate values.
4. Blank lines will be removed automatically.
5. Remove unnecessary comments before creating your template.
-->
<html>
<head>
<meta charset="UTF-8">
<meta name="authoring-tool" content="Adobe_Animate_CC">
<title>sky1</title>
<!-- write your code here -->
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script src="sky1.js"></script>
<script src="localconnection.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
handleComplete();
}
function handleComplete() {
//This function is always called, irrespective of the content. You can use the variable "stage" after it is created in token create_stage.
exportRoot = new lib.sky1();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
//Registers the "tick" event listener.
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
//Code to support hidpi screens and responsive scaling.
(function(isResp, respDim, isScale, scaleType) {
var lastW, lastH, lastS=1;
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
function resizeCanvas() {
var w = lib.properties.width, h = lib.properties.height;
var iw = window.innerWidth, ih=window.innerHeight;
var pRatio = window.devicePixelRatio || 1, xRatio=iw/w, yRatio=ih/h, sRatio=1;
if(isResp) {
if((respDim=='width'&&lastW==iw) || (respDim=='height'&&lastH==ih)) {
sRatio = lastS;
}
else if(!isScale) {
if(iw<w || ih<h)
sRatio = Math.min(xRatio, yRatio);
}
else if(scaleType==1) {
sRatio = Math.min(xRatio, yRatio);
}
else if(scaleType==2) {
sRatio = Math.max(xRatio, yRatio);
}
}
canvas.width = w*pRatio*sRatio;
canvas.height = h*pRatio*sRatio;
canvas.style.width = w*sRatio+'px';
canvas.style.height = h*sRatio+'px';
stage.scaleX = pRatio*sRatio;
stage.scaleY = pRatio*sRatio;
lastW = iw; lastH = ih; lastS = sRatio;
}
})(false,'both',false,1);
}
</script>
<!-- write your code here -->
</head>
<body onload="init();" style="margin:0px;">
<canvas id="canvas" width="200" height="668" style="display: block; background-color:rgba(255, 255, 255, 1.00)"></canvas>
</body>
</html>
js - Banner 1:
(function (lib, img, cjs, ss) {
var p; // shortcut to reference prototypes
lib.webFontTxtInst = {};
var loadedTypekitCount = 0;
var loadedGoogleCount = 0;
var gFontsUpdateCacheList = [];
var tFontsUpdateCacheList = [];
// library properties:
lib.properties = {
width: 200,
height: 668,
fps: 24,
color: "#FFFFFF",
opacity: 1.00,
webfonts: {},
manifest: []
};
lib.ssMetadata = [];
lib.updateListCache = function (cacheList) {
for(var i = 0; i < cacheList.length; i++) {
if(cacheList[i].cacheCanvas)
cacheList[i].updateCache();
}
};
lib.addElementsToCache = function (textInst, cacheList) {
var cur = textInst;
while(cur != exportRoot) {
if(cacheList.indexOf(cur) != -1)
break;
cur = cur.parent;
}
if(cur != exportRoot) { //we have found an element in the list
var cur2 = textInst;
var index = cacheList.indexOf(cur);
while(cur2 != cur) { //insert all it's children just before it
cacheList.splice(index, 0, cur2);
cur2 = cur2.parent;
index++;
}
}
else { //append element and it's parents in the array
cur = textInst;
while(cur != exportRoot) {
cacheList.push(cur);
cur = cur.parent;
}
}
};
lib.gfontAvailable = function(family, totalGoogleCount) {
lib.properties.webfonts[family] = true;
var txtInst = lib.webFontTxtInst && lib.webFontTxtInst[family] || [];
for(var f = 0; f < txtInst.length; ++f)
lib.addElementsToCache(txtInst[f], gFontsUpdateCacheList);
loadedGoogleCount++;
if(loadedGoogleCount == totalGoogleCount) {
lib.updateListCache(gFontsUpdateCacheList);
}
};
lib.tfontAvailable = function(family, totalTypekitCount) {
lib.properties.webfonts[family] = true;
var txtInst = lib.webFontTxtInst && lib.webFontTxtInst[family] || [];
for(var f = 0; f < txtInst.length; ++f)
lib.addElementsToCache(txtInst[f], tFontsUpdateCacheList);
loadedTypekitCount++;
if(loadedTypekitCount == totalTypekitCount) {
lib.updateListCache(tFontsUpdateCacheList);
}
};
// symbols:
(lib.Symbol1 = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Ebene 1
this.shape = new cjs.Shape();
this.shape.graphics.f("#990033").s().p("AvyMwIAA5fIflAAIAAZfg");
this.shape.setTransform(101.1,81.7);
this.timeline.addTween(cjs.Tween.get(this.shape).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(0,0,202.3,163.4);
// stage content:
(lib.sky1 = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// timeline functions:
this.frame_0 = function() {
LC.key = '123';
LC.name = 'links';
LC.frames = 'rechts';
LC.onConnect = function () {
console.log('Do this as soon as connection established!');
LC.rechts.document.getElementsByTagName('body')[0].style.backgroundColor = 'red';
};
LC.connect();
}
// actions tween:
this.timeline.addTween(cjs.Tween.get(this).call(this.frame_0).wait(203));
// animation
this.instance = new lib.Symbol1();
this.instance.parent = this;
this.instance.setTransform(100,80.6,1,1,0,0,0,101.1,81.7);
this.timeline.addTween(cjs.Tween.get(this.instance).wait(1).to({x:100.1,y:85.7},0).wait(1).to({y:90.8},0).wait(1).to({y:95.9},0).wait(1).to({y:101},0).wait(1).to({y:106.1},0).wait(1).to({y:111.3},0).wait(1).to({y:116.4},0).wait(1).to({y:121.5},0).wait(1).to({y:126.6},0).wait(1).to({x:100.2,y:131.7},0).wait(1).to({y:136.8},0).wait(1).to({y:141.9},0).wait(1).to({y:147},0).wait(1).to({y:152.1},0).wait(1).to({y:157.2},0).wait(1).to({y:162.3},0).wait(1).to({y:167.4},0).wait(1).to({y:172.6},0).wait(1).to({x:100.3,y:177.7},0).wait(1).to({y:182.8},0).wait(1).to({y:187.9},0).wait(1).to({y:193},0).wait(1).to({y:198.1},0).wait(1).to({y:203.2},0).wait(1).to({y:208.3},0).wait(1).to({y:213.4},0).wait(1).to({y:218.5},0).wait(1).to({x:100.4,y:223.6},0).wait(1).to({y:228.7},0).wait(1).to({y:233.9},0).wait(1).to({y:239},0).wait(1).to({y:244.1},0).wait(1).to({y:249.2},0).wait(1).to({y:254.3},0).wait(1).to({y:259.4},0).wait(1).to({y:264.5},0).wait(1).to({x:100.5,y:269.6},0).wait(1).to({y:274.7},0).wait(1).to({y:279.8},0).wait(1).to({y:284.9},0).wait(1).to({y:290.1},0).wait(1).to({y:295.2},0).wait(1).to({y:300.3},0).wait(1).to({y:305.4},0).wait(1).to({y:310.5},0).wait(1).to({x:100.6,y:315.6},0).wait(1).to({y:320.7},0).wait(1).to({y:325.8},0).wait(1).to({y:330.9},0).wait(1).to({y:336},0).wait(1).to({y:341.1},0).wait(1).to({y:346.2},0).wait(1).to({y:351.4},0).wait(1).to({y:356.5},0).wait(1).to({x:100.7,y:361.6},0).wait(1).to({y:366.7},0).wait(1).to({y:371.8},0).wait(1).to({y:376.9},0).wait(1).to({y:382},0).wait(1).to({y:387.1},0).wait(1).to({y:392.2},0).wait(1).to({y:397.3},0).wait(1).to({y:402.4},0).wait(1).to({x:100.8,y:407.5},0).wait(1).to({y:412.7},0).wait(1).to({y:417.8},0).wait(1).to({y:422.9},0).wait(1).to({y:428},0).wait(1).to({y:433.1},0).wait(1).to({y:438.2},0).wait(1).to({y:443.3},0).wait(1).to({y:448.4},0).wait(1).to({x:100.9,y:453.5},0).wait(1).to({y:458.6},0).wait(1).to({y:463.7},0).wait(1).to({y:468.9},0).wait(1).to({y:474},0).wait(1).to({y:479.1},0).wait(1).to({y:484.2},0).wait(1).to({y:489.3},0).wait(1).to({y:494.4},0).wait(1).to({x:101,y:499.5},0).wait(1).to({y:504.6},0).wait(1).to({y:509.7},0).wait(1).to({y:514.8},0).wait(1).to({y:519.9},0).wait(1).to({y:525},0).wait(1).to({y:530.2},0).wait(1).to({y:535.3},0).wait(1).to({y:540.4},0).wait(1).to({x:101.1,y:545.5},0).wait(1).to({y:550.6},0).wait(1).to({y:555.7},0).wait(1).to({y:560.8},0).wait(1).to({y:565.9},0).wait(1).to({y:571},0).wait(1).to({y:576.1},0).wait(1).to({y:581.2},0).wait(1).to({y:586.4},0).wait(1).to({y:581.5},0).wait(1).to({y:576.6},0).wait(1).to({y:571.7},0).wait(1).to({y:566.8},0).wait(1).to({y:561.9},0).wait(1).to({y:557},0).wait(1).to({y:552.1},0).wait(1).to({y:547.2},0).wait(1).to({y:542.3},0).wait(1).to({y:537.4},0).wait(1).to({y:532.5},0).wait(1).to({y:527.6},0).wait(1).to({y:522.7},0).wait(1).to({y:517.8},0).wait(1).to({y:512.9},0).wait(1).to({y:508},0).wait(1).to({y:503.1},0).wait(1).to({y:498.2},0).wait(1).to({y:493.3},0).wait(1).to({y:488.4},0).wait(1).to({y:483.5},0).wait(1).to({y:478.6},0).wait(1).to({y:473.7},0).wait(1).to({y:468.8},0).wait(1).to({y:463.9},0).wait(1).to({y:459},0).wait(1).to({y:454.1},0).wait(1).to({y:449.2},0).wait(1).to({y:444.3},0).wait(1).to({y:439.4},0).wait(1).to({y:434.5},0).wait(1).to({y:429.6},0).wait(1).to({y:424.7},0).wait(1).to({y:419.8},0).wait(1).to({y:414.9},0).wait(1).to({y:410},0).wait(1).to({y:405.1},0).wait(1).to({y:400.2},0).wait(1).to({y:395.3},0).wait(1).to({y:390.4},0).wait(1).to({y:385.5},0).wait(1).to({y:380.6},0).wait(1).to({y:375.7},0).wait(1).to({y:370.8},0).wait(1).to({y:365.9},0).wait(1).to({y:361},0).wait(1).to({y:356.1},0).wait(1).to({y:351.2},0).wait(1).to({y:346.3},0).wait(1).to({y:341.4},0).wait(1).to({y:336.5},0).wait(1).to({y:331.6},0).wait(1).to({y:326.7},0).wait(1).to({y:321.8},0).wait(1).to({y:316.9},0).wait(1).to({y:312},0).wait(1).to({y:307.1},0).wait(1).to({y:302.2},0).wait(1).to({y:297.3},0).wait(1).to({y:292.4},0).wait(1).to({y:287.5},0).wait(1).to({y:282.6},0).wait(1).to({y:277.7},0).wait(1).to({y:272.8},0).wait(1).to({y:267.9},0).wait(1).to({y:263},0).wait(1).to({y:258.1},0).wait(1).to({y:253.2},0).wait(1).to({y:248.3},0).wait(1).to({y:243.4},0).wait(1).to({y:238.5},0).wait(1).to({y:233.6},0).wait(1).to({y:228.7},0).wait(1).to({y:223.8},0).wait(1).to({y:218.9},0).wait(1).to({y:214},0).wait(1).to({y:209.1},0).wait(1).to({y:204.2},0).wait(1).to({y:199.3},0).wait(1).to({y:194.4},0).wait(1).to({y:189.5},0).wait(1).to({y:184.6},0).wait(1).to({y:179.7},0).wait(1).to({y:174.8},0).wait(1).to({y:169.9},0).wait(1).to({y:165},0).wait(1).to({y:160.1},0).wait(1).to({y:155.2},0).wait(1).to({y:150.3},0).wait(1).to({y:145.4},0).wait(1).to({y:140.5},0).wait(1).to({y:135.6},0).wait(1).to({y:130.7},0).wait(1).to({y:125.8},0).wait(1).to({y:120.9},0).wait(1).to({y:116},0).wait(1).to({y:111.1},0).wait(1).to({y:106.2},0).wait(1).to({y:101.3},0).wait(1).to({y:96.4},0).wait(1).to({y:91.5},0).wait(1).to({y:86.6},0).wait(1).to({y:81.7},0).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(98.9,332.9,202.3,163.4);
})(lib = lib||{}, images = images||{}, createjs = createjs||{}, ss = ss||{});
var lib, images, createjs, ss;
HTML - Banner 2:
<!DOCTYPE html>
<!--
NOTES:
1. All tokens are represented by '$' sign in the template.
2. You can write your code only wherever mentioned.
3. All occurrences of existing tokens will be replaced by their appropriate values.
4. Blank lines will be removed automatically.
5. Remove unnecessary comments before creating your template.
-->
<html>
<head>
<meta charset="UTF-8">
<meta name="authoring-tool" content="Adobe_Animate_CC">
<title>sky2</title>
<!-- write your code here -->
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script src="sky2.js"></script>
<script src="localconnection.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
handleComplete();
}
function handleComplete() {
//This function is always called, irrespective of the content. You can use the variable "stage" after it is created in token create_stage.
exportRoot = new lib.sky2();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
//Registers the "tick" event listener.
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
//Code to support hidpi screens and responsive scaling.
(function(isResp, respDim, isScale, scaleType) {
var lastW, lastH, lastS=1;
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
function resizeCanvas() {
var w = lib.properties.width, h = lib.properties.height;
var iw = window.innerWidth, ih=window.innerHeight;
var pRatio = window.devicePixelRatio || 1, xRatio=iw/w, yRatio=ih/h, sRatio=1;
if(isResp) {
if((respDim=='width'&&lastW==iw) || (respDim=='height'&&lastH==ih)) {
sRatio = lastS;
}
else if(!isScale) {
if(iw<w || ih<h)
sRatio = Math.min(xRatio, yRatio);
}
else if(scaleType==1) {
sRatio = Math.min(xRatio, yRatio);
}
else if(scaleType==2) {
sRatio = Math.max(xRatio, yRatio);
}
}
canvas.width = w*pRatio*sRatio;
canvas.height = h*pRatio*sRatio;
canvas.style.width = w*sRatio+'px';
canvas.style.height = h*sRatio+'px';
stage.scaleX = pRatio*sRatio;
stage.scaleY = pRatio*sRatio;
lastW = iw; lastH = ih; lastS = sRatio;
}
})(false,'both',false,1);
}
</script>
<!-- write your code here -->
</head>
<body onload="init();" style="margin:0px;">
<canvas id="canvas" width="200" height="668" style="display: block; background-color:rgba(255, 255, 255, 1.00)"></canvas>
</body>
</html>
js - Banner 2:
(function (lib, img, cjs, ss) {
var p; // shortcut to reference prototypes
lib.webFontTxtInst = {};
var loadedTypekitCount = 0;
var loadedGoogleCount = 0;
var gFontsUpdateCacheList = [];
var tFontsUpdateCacheList = [];
// library properties:
lib.properties = {
width: 200,
height: 668,
fps: 24,
color: "#FFFFFF",
opacity: 1.00,
webfonts: {},
manifest: []
};
lib.ssMetadata = [];
lib.updateListCache = function (cacheList) {
for(var i = 0; i < cacheList.length; i++) {
if(cacheList[i].cacheCanvas)
cacheList[i].updateCache();
}
};
lib.addElementsToCache = function (textInst, cacheList) {
var cur = textInst;
while(cur != exportRoot) {
if(cacheList.indexOf(cur) != -1)
break;
cur = cur.parent;
}
if(cur != exportRoot) { //we have found an element in the list
var cur2 = textInst;
var index = cacheList.indexOf(cur);
while(cur2 != cur) { //insert all it's children just before it
cacheList.splice(index, 0, cur2);
cur2 = cur2.parent;
index++;
}
}
else { //append element and it's parents in the array
cur = textInst;
while(cur != exportRoot) {
cacheList.push(cur);
cur = cur.parent;
}
}
};
lib.gfontAvailable = function(family, totalGoogleCount) {
lib.properties.webfonts[family] = true;
var txtInst = lib.webFontTxtInst && lib.webFontTxtInst[family] || [];
for(var f = 0; f < txtInst.length; ++f)
lib.addElementsToCache(txtInst[f], gFontsUpdateCacheList);
loadedGoogleCount++;
if(loadedGoogleCount == totalGoogleCount) {
lib.updateListCache(gFontsUpdateCacheList);
}
};
lib.tfontAvailable = function(family, totalTypekitCount) {
lib.properties.webfonts[family] = true;
var txtInst = lib.webFontTxtInst && lib.webFontTxtInst[family] || [];
for(var f = 0; f < txtInst.length; ++f)
lib.addElementsToCache(txtInst[f], tFontsUpdateCacheList);
loadedTypekitCount++;
if(loadedTypekitCount == totalTypekitCount) {
lib.updateListCache(tFontsUpdateCacheList);
}
};
// symbols:
(lib.Symbol1 = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// Ebene 1
this.shape = new cjs.Shape();
this.shape.graphics.f("#990033").s().p("AvyMwIAA5fIflAAIAAZfg");
this.shape.setTransform(101.1,81.7);
this.timeline.addTween(cjs.Tween.get(this.shape).wait(1));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(0,0,202.3,163.4);
// stage content:
(lib.sky2 = function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// timeline functions:
this.frame_0 = function() {
LC.key = '123';
LC.name = 'rechts';
LC.frames = 'links';
LC.onConnect = function () {
console.log('Do this as soon as connection established!');
LC.links.document.getElementsByTagName('body')[0].style.backgroundColor = 'blue';
};
LC.connect();
this.stop();
}
// actions tween:
this.timeline.addTween(cjs.Tween.get(this).call(this.frame_0).wait(202));
// animation
this.instance = new lib.Symbol1();
this.instance.parent = this;
this.instance.setTransform(100,80.6,1,1,0,0,0,101.1,81.7);
this.timeline.addTween(cjs.Tween.get(this.instance).wait(1).to({x:100.1,y:85.7},0).wait(1).to({y:90.8},0).wait(1).to({y:95.9},0).wait(1).to({y:101},0).wait(1).to({y:106.1},0).wait(1).to({y:111.3},0).wait(1).to({y:116.4},0).wait(1).to({y:121.5},0).wait(1).to({y:126.6},0).wait(1).to({x:100.2,y:131.7},0).wait(1).to({y:136.8},0).wait(1).to({y:141.9},0).wait(1).to({y:147},0).wait(1).to({y:152.1},0).wait(1).to({y:157.2},0).wait(1).to({y:162.3},0).wait(1).to({y:167.4},0).wait(1).to({y:172.6},0).wait(1).to({x:100.3,y:177.7},0).wait(1).to({y:182.8},0).wait(1).to({y:187.9},0).wait(1).to({y:193},0).wait(1).to({y:198.1},0).wait(1).to({y:203.2},0).wait(1).to({y:208.3},0).wait(1).to({y:213.4},0).wait(1).to({y:218.5},0).wait(1).to({x:100.4,y:223.6},0).wait(1).to({y:228.7},0).wait(1).to({y:233.9},0).wait(1).to({y:239},0).wait(1).to({y:244.1},0).wait(1).to({y:249.2},0).wait(1).to({y:254.3},0).wait(1).to({y:259.4},0).wait(1).to({y:264.5},0).wait(1).to({x:100.5,y:269.6},0).wait(1).to({y:274.7},0).wait(1).to({y:279.8},0).wait(1).to({y:284.9},0).wait(1).to({y:290.1},0).wait(1).to({y:295.2},0).wait(1).to({y:300.3},0).wait(1).to({y:305.4},0).wait(1).to({y:310.5},0).wait(1).to({x:100.6,y:315.6},0).wait(1).to({y:320.7},0).wait(1).to({y:325.8},0).wait(1).to({y:330.9},0).wait(1).to({y:336},0).wait(1).to({y:341.1},0).wait(1).to({y:346.2},0).wait(1).to({y:351.4},0).wait(1).to({y:356.5},0).wait(1).to({x:100.7,y:361.6},0).wait(1).to({y:366.7},0).wait(1).to({y:371.8},0).wait(1).to({y:376.9},0).wait(1).to({y:382},0).wait(1).to({y:387.1},0).wait(1).to({y:392.2},0).wait(1).to({y:397.3},0).wait(1).to({y:402.4},0).wait(1).to({x:100.8,y:407.5},0).wait(1).to({y:412.7},0).wait(1).to({y:417.8},0).wait(1).to({y:422.9},0).wait(1).to({y:428},0).wait(1).to({y:433.1},0).wait(1).to({y:438.2},0).wait(1).to({y:443.3},0).wait(1).to({y:448.4},0).wait(1).to({x:100.9,y:453.5},0).wait(1).to({y:458.6},0).wait(1).to({y:463.7},0).wait(1).to({y:468.9},0).wait(1).to({y:474},0).wait(1).to({y:479.1},0).wait(1).to({y:484.2},0).wait(1).to({y:489.3},0).wait(1).to({y:494.4},0).wait(1).to({x:101,y:499.5},0).wait(1).to({y:504.6},0).wait(1).to({y:509.7},0).wait(1).to({y:514.8},0).wait(1).to({y:519.9},0).wait(1).to({y:525},0).wait(1).to({y:530.2},0).wait(1).to({y:535.3},0).wait(1).to({y:540.4},0).wait(1).to({x:101.1,y:545.5},0).wait(1).to({y:550.6},0).wait(1).to({y:555.7},0).wait(1).to({y:560.8},0).wait(1).to({y:565.9},0).wait(1).to({y:571},0).wait(1).to({y:576.1},0).wait(1).to({y:581.2},0).wait(1).to({y:586.4},0).wait(1).to({y:581.4},0).wait(1).to({y:576.4},0).wait(1).to({y:571.4},0).wait(1).to({y:566.4},0).wait(1).to({y:561.4},0).wait(1).to({y:556.4},0).wait(1).to({y:551.4},0).wait(1).to({y:546.4},0).wait(1).to({y:541.4},0).wait(1).to({y:536.4},0).wait(1).to({y:531.4},0).wait(1).to({y:526.4},0).wait(1).to({y:521.4},0).wait(1).to({y:516.4},0).wait(1).to({y:511.4},0).wait(1).to({y:506.4},0).wait(1).to({y:501.4},0).wait(1).to({y:496.4},0).wait(1).to({y:491.4},0).wait(1).to({y:486.4},0).wait(1).to({y:481.4},0).wait(1).to({y:476.4},0).wait(1).to({y:471.4},0).wait(1).to({y:466.4},0).wait(1).to({y:461.4},0).wait(1).to({y:456.4},0).wait(1).to({y:451.4},0).wait(1).to({y:446.4},0).wait(1).to({y:441.5},0).wait(1).to({y:436.5},0).wait(1).to({y:431.5},0).wait(1).to({y:426.5},0).wait(1).to({y:421.5},0).wait(1).to({y:416.5},0).wait(1).to({y:411.5},0).wait(1).to({y:406.5},0).wait(1).to({y:401.5},0).wait(1).to({y:396.5},0).wait(1).to({y:391.5},0).wait(1).to({y:386.5},0).wait(1).to({y:381.5},0).wait(1).to({y:376.5},0).wait(1).to({y:371.5},0).wait(1).to({y:366.5},0).wait(1).to({y:361.5},0).wait(1).to({y:356.5},0).wait(1).to({y:351.5},0).wait(1).to({y:346.5},0).wait(1).to({y:341.5},0).wait(1).to({y:336.5},0).wait(1).to({y:331.5},0).wait(1).to({y:326.5},0).wait(1).to({y:321.5},0).wait(1).to({y:316.5},0).wait(1).to({y:311.5},0).wait(1).to({y:306.5},0).wait(1).to({y:301.6},0).wait(1).to({y:296.6},0).wait(1).to({y:291.6},0).wait(1).to({y:286.6},0).wait(1).to({y:281.6},0).wait(1).to({y:276.6},0).wait(1).to({y:271.6},0).wait(1).to({y:266.6},0).wait(1).to({y:261.6},0).wait(1).to({y:256.6},0).wait(1).to({y:251.6},0).wait(1).to({y:246.6},0).wait(1).to({y:241.6},0).wait(1).to({y:236.6},0).wait(1).to({y:231.6},0).wait(1).to({y:226.6},0).wait(1).to({y:221.6},0).wait(1).to({y:216.6},0).wait(1).to({y:211.6},0).wait(1).to({y:206.6},0).wait(1).to({y:201.6},0).wait(1).to({y:196.6},0).wait(1).to({y:191.6},0).wait(1).to({y:186.6},0).wait(1).to({y:181.6},0).wait(1).to({y:176.6},0).wait(1).to({y:171.6},0).wait(1).to({y:166.6},0).wait(1).to({y:161.6},0).wait(1).to({y:156.6},0).wait(1).to({y:151.7},0).wait(1).to({y:146.7},0).wait(1).to({y:141.7},0).wait(1).to({y:136.7},0).wait(1).to({y:131.7},0).wait(1).to({y:126.7},0).wait(1).to({y:121.7},0).wait(1).to({y:116.7},0).wait(1).to({y:111.7},0).wait(1).to({y:106.7},0).wait(1).to({y:101.7},0).wait(1).to({y:96.7},0).wait(1).to({y:91.7},0).wait(1).to({y:86.7},0).wait(1).to({y:81.7},0).wait(2));
}).prototype = p = new cjs.MovieClip();
p.nominalBounds = new cjs.Rectangle(98.9,332.9,202.3,163.4);
})(lib = lib||{}, images = images||{}, createjs = createjs||{}, ss = ss||{});
var lib, images, createjs, ss;
it's better to call LC.connect(); function at the end of handleComplete() event, because as soon as exportRoot defined, it's available to use it main Animation object.
For example :
.....
exportRoot = new lib.sky2();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
LC.key = '123';
LC.name = 'links';
LC.frames = 'rechts';
LC.onConnect = function () {
exportRoot.play();
LC.rechts.exportRoot.play();
};
exportRoot.stop();
LC.connect();
.....
on the other animation you only need to define & call LC.connect(); like this :
.....
exportRoot = new lib.sky2();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
LC.key = '123';
LC.name = 'rechts'; // adjust name
LC.frames = 'links'; // adjust frames
LC.onConnect = function () {
// no action needed here
};
exportRoot.stop();
LC.connect();
....

Is it possible to detect the number of users currently interacting a section of html code?

This may be a naive question, sorry for that, but I'm trying to sort out a potential concurrency issue. I have a registration procedure which begins with the user selecting their category from a drop down menu. That triggers a query to a particular page in a google sheet where it retrieves an available ID number that is displayed to the user. There are a couple steps required before the final submit button is pressed. This (I think) creates a chance for more than one person to retrieve the same ID. I do use google's lockservice but on the function which writes the form information to my spreadsheet (based on a script of Martin Hawksley). If it was possible to determine how many people were currently viewing the registration page I could use that value in the query with an if statement such that a different row number is retrieved. This would eliminate the chance of duplicates.
Does that sound reasonable? Perhaps there is a much better way.
Any advice would be most appreciated.
If it was possible to determine how many people were currently viewing
the registration page
If you don't want to use Google Analytics. Here is a simple example of how you can poll with a client to maintain a session, and count how many users are active.
NOTE: I threw this together, it could be refactored a bit to be prettier, but it should get the gist of it across
Working Example Open this a couple times, you will see your session IDs in each and a count. Sessions expire after 60 seconds of no activity, and auto-end if you close the page.
Project file structure:
Code.gs
index.html
javascript.html
Apps Script
var sessionTimeout = 60; //60 seconds
//Triggered when the page is navigated to, serves up HTML
function doGet(){
var template = HtmlService.createTemplateFromFile('index');
template.userID = NewSession();
return template.evaluate()
.setTitle('Active Users')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
/*================ Polling ================*/
//Client calls this function to poll, updates cache, returns active users
function ClientPoll(id){
var scriptCache = CacheService.getScriptCache();
UpdateScriptCache(id, 0, scriptCache, true);
var activeIDs = GetActiveIDs(scriptCache);
return activeIDs;
}
function EndSession(id){
var scriptCache = CacheService.getScriptCache();
scriptCache.remove(id);
var activeIDs = GetActiveIDs(scriptCache);
activeIDs.splice(activeIDs.indexOf(id), 1);
UpdateScriptCache('ActiveIDs', activeIDs, scriptCache, false);
}
//Server calls every minute to check for inactive sessions
function CheckForInactiveSessions(){
var scriptCache = CacheService.getScriptCache();
var activeIDs = GetActiveIDs(scriptCache);
var allSessions = scriptCache.getAll(activeIDs);
if(Object.keys(allSessions).length > 0){
var keys = Object.keys(allSessions);
var newActiveIDs = [];
for(var i = 0; i < keys.length; i++){
newActiveIDs.push(keys[i]);
}
Logger.log(keys.length);
UpdateScriptCache('ActiveIDs', newActiveIDs, scriptCache, false);
}
}
/*================ Session Creation & Cache ================*/
//Handles setting up a new session, called when page is opened
function NewSession(){
var id = GenerateUID();
AddNewActiveID(id);
return id;
}
//Gets a list of all active IDs
function GetActiveIDs(scriptCache){
if(!scriptCache){
scriptCache = CacheService.getScriptCache();
}
var active = scriptCache.get('ActiveIDs');
if(active !== null){
return JSON.parse(active);
}
return [];
}
//Adds a new ID to the cache
function AddNewActiveID(id){
var scriptCache = CacheService.getScriptCache();
var activeIDs = JSON.parse(scriptCache.get('ActiveIDs'));
if(activeIDs == null){
activeIDs = [];
}
activeIDs.push(id);
//Update the Active ID List
UpdateScriptCache('ActiveIDs', activeIDs, scriptCache, false);
//Add new ID to cache
UpdateScriptCache(id, 0, scriptCache, true);
}
//Handles updating the Active IDs cache and prevents race conditions or collisions
function UpdateScriptCache(key, data, cache, timeout){
var lock = LockService.getScriptLock();
lock.waitLock(15000);
if(timeout){
cache.put(key, JSON.stringify(data), sessionTimeout);
} else {
cache.put(key, JSON.stringify(data), 21600)
}
lock.releaseLock();
}
/*================ ID Generation ================*/
//Handles generating and returning a new ID
function GenerateUID(){
var generator = new IDGenerator();
var id = generator.generate();
return id;
}
//Generates a random(ish) ID;
function IDGenerator() {
this.length = 10;
this.timestamp = new Date().getTime();
var getRandomInt = function( min, max ) {
return Math.floor( Math.random() * ( max - min + 1 ) ) + min;
}
this.generate = function(){
var timestamp = this.timestamp.toString();
var parts = timestamp.split('').reverse();
var id = '';
for(var i = 0; i < this.length; i++){
var index = getRandomInt(0, parts.length - 1);
id += parts[index];
}
return id;
}
}
JavaScript:
<script>
//Initilization
$(function(){
//Set the users ID in HTML
$('#userID').text(userID);
//Setup handler to end the session before the page closes
$(window).bind('beforeunload', function(){
EndSession();
});
//Start the timer
var deadline = new Date(Date.parse(new Date()) + 5000);
initializeTimer('pollingIn', deadline);
});
//Polls the server to update session and get active users
function PollServer(){
console.log('Polling server');
google.script.run.withSuccessHandler(UpdateActiveUsers).ClientPoll(userID);
var deadline = new Date(Date.parse(new Date()) + 5000);
initializeTimer('pollingIn', deadline);
}
//Ends the session right before the page closes
function EndSession(){
google.script.run.withSuccessHandler().EndSession(userID);
}
//Updates the active users div
function UpdateActiveUsers(users){
console.log(users)
var userText = '';
for(var i = 0; i < users.length; i++){
if(i == 0){
userText += users[i];
continue;
}
userText += ', ' + users[i];
}
$('#activeUsersCount').text(users.length);
$('#activeUsers').text(userText);
}
//Initilizes the timer
function initializeTimer(id, endtime) {
var timer = $('#'+id);
function updateTimer() {
var time = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((time / 1000) % 60);
timer.text(seconds);
if (time <= 0) {
clearInterval(timeInterval);
PollServer();
}
}
updateTimer();
var timeInterval = setInterval(updateTimer, 1000);
}
</script>
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href="https://ssl.gstatic.com/docs/script/css/add-ons1.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<div id="mainForm">
<h1>Active Users</h1>
<div class="box">
Active Users Count:
<span id="activeUsersCount">0</span>
</div>
<div class="box">
Active Users:
<span id="activeUsers"></span>
</div>
<div class="box">
Polling in:
<span id="pollingIn"></span>
</div>
<div class="box">
You Are:
<span id="userID"></span>
</div>
</div>
<?!= HtmlService.createHtmlOutputFromFile('javascript').getContent(); ?>
<script>
var userID = <?= userID ?>;
</script>
</body>
</html>
<style>
.box {
display: block;
padding: 0.5em;
}
body {
padding: 1em;
}
</style>

Audio Level Meter for Web RTC Stream

I would like to create a decibel meter for the audio that is playing in a video element. The video element is playing a WebRTC stream.
At the moment WebRTC streams cannot be passed into a Web Audio Analyzer. (Although this might change soon … ) (see Web Audio API analyser node getByteFrequencyData returning blank array)
Is there currently another way to get decibel information from a remote mediastream?
Chrome 50 was released: As of the 13th of April 2016 using an Analyser Node with a MediaStreamAudioSourceNode works fine to get audio levels. The resulting audioLevels value can be animated or simply passed into a html meter element.
var _mediaStream = SOME_LOCAL_OR_RTP_MEDIASTREAM;
var _audioContext = new AudioContext();
var _audioAnalyser = [];
var _freqs = [];
var audioLevels = [0];
var _audioSource = _audioContext.createMediaStreamSource(_mediaStream);
var _audioGain1 = _audioContext.createGain();
var _audioChannelSplitter = _audioContext.createChannelSplitter(_audioSource.channelCount);
_audioSource.connect(_audioGain1);
_audioGain1.connect(_audioChannelSplitter);
_audioGain1.connect(_audioContext.destination);
for (let i = 0; i < _audioSource.channelCount; i++) {
_audioAnalyser[i] = _audioContext.createAnalyser();
_audioAnalyser[i].minDecibels = -100;
_audioAnalyser[i].maxDecibels = 0;
_audioAnalyser[i].smoothingTimeConstant = 0.8;
_audioAnalyser[i].fftSize = 32;
_freqs[i] = new Uint8Array(_audioAnalyser[i].frequencyBinCount);
_audioChannelSplitter.connect(_audioAnalyser[i], i, 0);
}
function calculateAudioLevels() {
setTimeout(() => {
for (let channelI = 0; channelI < _audioAnalyser.length; channelI++) {
_audioAnalyser[channelI].getByteFrequencyData(_freqs[channelI]);
let value = 0;
for (let freqBinI = 0; freqBinI < _audioAnalyser[channelI].frequencyBinCount; freqBinI++) {
value = Math.max(value, _freqs[channelI][freqBinI]);
}
audioLevels[channelI] = value / 256;
}
requestAnimationFrame(calculateAudioLevels.bind(this));
}, 1000 / 15); // Max 15fps — not more needed
}
This is a good example:
https://webrtc.github.io/samples/src/content/getusermedia/volume/
And this is the source code:
https://github.com/webrtc/samples/tree/gh-pages/src/content/getusermedia/volume
And this is a sample:
function recordAudio() {
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
window.audioContext = new AudioContext();
const instantMeter = document.querySelector('#sound-meter');
const constraints = {'video': false, 'audio': true};
const stream = await navigator.mediaDevices.getUserMedia(constraints);
window.stream = stream;
const soundMeter = window.soundMeter = new SoundMeter(window.audioContext);
soundMeter.connectToSource(stream, function(e) {
if (e) {
alert(e);
return;
}
setInterval(() => {
instantMeter.value = soundMeter.instant.toFixed(2);
}, 200);
});
$('#sound-meter').show();
$('#audio-icon').hide()
} catch(error) {
console.error('Error recording audio.', error);
}
}

Google maps api v3 calculate mileage by state

I'm searching for a way to calculate mileage by US State based on an origin, waypoints and destination of a route using Google Maps API v3.
I have tried using Googles Distance Matrix API but this it is calculating the distance between 2 points, which is good, but I need the break down for miles traveled for each State. For taxes purposes (IFTA reports for transportation).
I've done a lot of googling and looked through the documentation but I'm not seeing anything that calculate the mileage per State.
I know how to use Google maps and I know this is possible since I saw it on one video. There is no code I can show because I have no idea how to do it. Any thoughts?
Useful links I have found:
How to Draw Routes and Calculate Route Time and Distance on the Fly Using Google Map API V3 http://www.c-sharpcorner.com/UploadFile/8911c4/how-to-draw-routes-and-calculate-route-time-and-distance-on/
How to Build a Distance Finder with Google Maps API http://www.1stwebdesigner.com/distance-finder-google-maps-api/
Below is a fully functional implementation that uses the Google Maps Javascript API. All you need to add is your own Maps API Key. As noted in the posts referenced above, Google Maps throttles requests at an asymptotic rate, and thus, the longer the route, the longer it will take to calculate. To give a ballpark, a route from New Haven CT to the NJ/PA border takes approximately 5 minutes. A trip from New Haven CT to Los Angeles takes 45 minutes to index. One other note: There are a few state borders that run through bodies of water. Google considers these to be not located in any state, and so reports undefined as the state name. These sections are obviously only a few tenths of a mile in most cases, but I felt I should mention it just to clarify what is going on when that happens.
UPDATED:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=<YOUR-KEY-HERE>"></script>
<div id="map" style="height:400px"></div>
<div id="status"></div>
<div id="results" style="height:400px"><b>Results:</b></div>
<script>
var directionsRequest = {
origin: "New York, NY", //default
destination: "Los Angeles, LA", //default
optimizeWaypoints: true,
provideRouteAlternatives: false,
travelMode: google.maps.TravelMode.DRIVING,
drivingOptions: {
departureTime: new Date(),
trafficModel: google.maps.TrafficModel.PESSIMISTIC
}
};
directionsRequest.origin = prompt("Enter your starting address");
directionsRequest.destination = prompt("Enter your destination address");
var starttime = new Date();
var geocoder = new google.maps.Geocoder();
var startState;
var currentState;
var routeData;
var index = 0;
var stateChangeSteps = [];
var borderLatLngs = {};
var startLatLng;
var endLatLng;
directionsService = new google.maps.DirectionsService();
directionsService.route(directionsRequest, init);
function init(data){
routeData = data;
displayRoute();
startLatLng = data.routes[0].legs[0].start_location;
endLatLng = data.routes[0].legs[0].end_location;
geocoder.geocode({location:data.routes[0].legs[0].start_location}, assignInitialState)
}
function assignInitialState(data){
startState = getState(data);
currentState = startState;
compileStates(routeData);
}
function getState(data){
for (var i = 0; i < data.length; i++) {
if (data[i].types[0] === "administrative_area_level_1") {
var state = data[i].address_components[0].short_name;
}
}
return state;
}
function compileStates(data, this_index){
if(typeof(this_index) == "undefined"){
index = 1;
geocoder.geocode({location:data.routes[0].legs[0].steps[0].start_location}, compileStatesReceiver);
}else{
if(index >= data.routes[0].legs[0].steps.length){
console.log(stateChangeSteps);
index = 0;
startBinarySearch();
return;
}
setTimeout(function(){
geocoder.geocode({location:data.routes[0].legs[0].steps[index].start_location}, compileStatesReceiver);
$("#status").html("Indexing Step "+index+"... ("+data.routes[0].legs[0].steps.length+" Steps Total)");
}, 3000)
}
}
function compileStatesReceiver(response){
state = getState(response);
console.log(state);
if(state != currentState){
currentState = state;
stateChangeSteps.push(index-1);
}
index++;
compileStates(routeData, index);
}
var stepIndex = 0;
var stepStates = [];
var binaryCurrentState = "";
var stepNextState;
var stepEndState;
var step;
var myLatLng = {lat:39.8282, lng:-98.5795};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
function displayRoute() {
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
directionsDisplay.setDirections(routeData);
}
var orderedLatLngs = [];
function startBinarySearch(iterating){
if(stepIndex >= stateChangeSteps.length){
for(step in borderLatLngs){
for(state in borderLatLngs[step]){
for(statename in borderLatLngs[step][state]){
$("#results").append("<br>Cross into "+statename+" at "+JSON.stringify(borderLatLngs[step][state][statename], null, 4));
orderedLatLngs.push([borderLatLngs[step][state][statename], statename]);
}
}
}
compileMiles(true);
return;
}
step = routeData.routes[0].legs[0].steps[stateChangeSteps[stepIndex]];
console.log("Looking at step "+stateChangeSteps[stepIndex]);
borderLatLngs[stepIndex] = {};
if(!iterating){
binaryCurrentState = startState;
}
geocoder.geocode({location:step.end_location},
function(data){
if(data === null){
setTimeout(function(){startBinarySearch(true);}, 6000);
}else{
stepNextState = getState(data);
stepEndState = stepNextState;
binaryStage2(true);
}
});
}
var minIndex;
var maxIndex;
var currentIndex;
function binaryStage2(init){
if (typeof(init) != "undefined"){
minIndex = 0;
maxIndex = step.path.length - 1;
}
if((maxIndex-minIndex)<2){
borderLatLngs[stepIndex][maxIndex]={};
borderLatLngs[stepIndex][maxIndex][stepNextState]=step.path[maxIndex];
var marker = new google.maps.Marker({
position: borderLatLngs[stepIndex][maxIndex][stepNextState],
map: map,
});
if(stepNextState != stepEndState){
minIndex = maxIndex;
maxIndex = step.path.length - 1;
binaryCurrentState = stepNextState;
stepNextState = stepEndState;
}else{
stepIndex++;
binaryCurrentState = stepNextState;
startBinarySearch(true);
return;
}
}
console.log("Index starts: "+minIndex+" "+maxIndex);
console.log("current state is "+binaryCurrentState);
console.log("next state is "+ stepNextState);
console.log("end state is "+ stepEndState);
currentIndex = Math.floor((minIndex+maxIndex)/2);
setTimeout(function(){
geocoder.geocode({location:step.path[currentIndex]}, binaryStage2Reciever);
$("#status").html("Searching for division between "+binaryCurrentState+" and "+stepNextState+" between indexes "+minIndex+" and "+maxIndex+"...")
}, 3000);
}
function binaryStage2Reciever(response){
if(response === null){
setTimeout(binaryStage2, 6000);
}else{
state = getState(response)
if(state == binaryCurrentState){
minIndex = currentIndex +1;
}else{
maxIndex = currentIndex - 1
if(state != stepNextState){
stepNextState = state;
}
}
binaryStage2();
}
}
var currentStartPoint;
var compileMilesIndex = 0;
var stateMiles = {};
var trueState;
function compileMiles(init){
if(typeof(init)!= "undefined"){
currentStartPoint = startLatLng;
trueState = startState;
}
if(compileMilesIndex == orderedLatLngs.length){
directionsRequest.destination = endLatLng;
}else{
directionsRequest.destination = orderedLatLngs[compileMilesIndex][0];
}
directionsRequest.origin = currentStartPoint;
currentStartPoint = directionsRequest.destination;
directionsService.route(directionsRequest, compileMilesReciever)
}
function compileMilesReciever(data){
if(data===null){
setTimeout(compileMiles, 6000);
}else{
if(compileMilesIndex == orderedLatLngs.length){
stateMiles[stepEndState]=data.routes[0].legs[0].distance["text"];
$("#results").append("<br><br><b>Distances Traveled</b>");
for(state in stateMiles){
$("#results").append("<br>"+state+": "+stateMiles[state]);
}
var endtime = new Date();
totaltime = endtime - starttime;
$("#results").append("<br><br>Operation took "+Math.floor(totaltime/60000)+" minute(s) and "+(totaltime%60000)/1000+" second(s) to run.");
return;
}else{
stateMiles[trueState]=data.routes[0].legs[0].distance["text"];
}
trueState = orderedLatLngs[compileMilesIndex][1];
compileMilesIndex++;
setTimeout(compileMiles, 3000);
}
}
</script>
</script>

How can I turn part of my casperjs script into a function so I can use it multiple times

Okay, so here is a part of my casperjs script below which works fine
if(casper.exists(ac1)){
var uel = "https://example.ws/send.html?f=1099817";
this.thenOpen(uel, function() {
casper.wait(10000, function() {
casper.then(function() {
this.evaluate(function() {
var amount = 0.29
var result = amount * 0.019
var result2 = result.toFixed(6);
var fresult = amount - result2;
var needed = fresult.toFixed(3);
document.getElementById('account').value = 'ydfg028';
document.getElementsByName('data')[0].value = needed;
});
this.click("input#sbt.button[type='submit']");
casper.wait(10000, function() {
casper.then(function() {
this.capture("filenadfgmedsfg.jpg");
var el2 = this.getHTML();
fs.write('results23.html', el2, 'w');
});
});
});
});
});
} else {
this.exit();
}
The problem I have is over 14 of the following statements
if(casper.exists()){
So what I am trying to do, is use the casperjs steps as a function. This is what I have tried below, but it just does nothing and casperjs ends when it reaches the function. Here's what I am trying
This is the casperjs function I have made
function casperstep(amount, user, location) {
var uel = "https://example.ws/send.html?f=" + location;
this.thenOpen(uel, function() {
casper.wait(10000, function() {
casper.then(function() {
this.evaluate(function() {
var result = amount * 0.019
var result2 = result.toFixed(6);
var fresult = amount - result2;
var needed = fresult.toFixed(3);
document.getElementById('account').value = user;
document.getElementsByName('data')[0].value = needed;
});
this.click("input#sbt.button[type='submit']");
casper.wait(10000, function() {
casper.then(function() {
this.capture("filenadfgmedsfg.jpg");
var el2 = this.getHTML();
fs.write('results23.html', el2, 'w');
});
});
});
});
});
}
Then when I try the following
if(casper.exists(ac1)){
casperstep(0.29, "username", "3245324");
}
it just does not work at all. The casper steps just do not fire. How can I fix this in theory? It should have worked.
What I have been trying with your answers...
My function
casper.captchaget = function (selector) {
var Loc = this.getHTML(selector, true).match(/src="(.*?)"/)[1];
var Ilocation = 'https://perfectmoney.is' + Loc;
var image = Loc;
var imagesplit = image.split ('?');
var split1 = imagesplit[1];
var string = split1 + ".jpg";
this.download(Ilocation, string);
}
and how I am trying to use it
casper.then(function(){
this.captchaget('img#cpt_img');//this.casperstep(0.29, "username", "3245324");
});
I tried the above to test out using casper extension.
Well, you want to add your own method to a casper object instance : http://casperjs.readthedocs.org/en/latest/extending.html
so :
casper.casperstep = function (amount, user, location) {
{your instructions....}
}
Then call it :
casper.start();
casper.then(function(){
if(casper.exists(ac1)){
casper.casperstep(0.29, "username", "3245324");//this.casperstep(0.29, "username", "3245324");
}
})
.run(function() {
test.done();
});
Old-monkey patching :)
To see other ways to do it : Custom casperjs modules