How to loop an animation for multiple appended divs? - loops

I made a div wich I animate with jquery.
The loop goes like this: to the right, then down, to the left, and down again.
When the start button is pressed, the first div starts the animation loop. The next div is appended at a random interval, same for the next one etc.
BUT when a second div is appended, the whole animation loop goes nuts.
What I'm trying to accomplish:
If a second div is appended, the first one should just complete it's animtion loop.
And the second one and the ones after that also complete their loop.
Can you help me with this? Should I add counters for the classes or something?
(By the way I disabled the random appending code in this jsfiddle, so you can see the right animation loop first. Please enable to see the crazy effect)
Demo
HTML
<div id="arena">
<div id="start">start</div>
</div>
jQuery
var counter = 0;
$("#start").on('click', function () {
$("#arena").append('<div class="b"></div>');
bbLoop();
$("#start").hide();
});
function bbLoop() {
bbRight();
}
function bbLeft() {
$(".b").animate({
left: "-=300"
}, 1500, "swing", bbLeftDown);
}
function bbRight() {
$(".b").animate({
left: "+=300"
}, 1500, "swing", bbRightDown);
}
function bbLeftDown() {
$(".b").animate({
bottom: "-=30"
}, 300, "swing", bbRight);
}
function bbRightDown() {
$(".b").animate({
bottom: "-=30"
}, 300, "swing", bbLeft);
}
/*
function doSomething() {}
(function loop() {
var rand = Math.round(Math.random() * (3000 - 500)) + 500;
setTimeout(function () {
doSomething();
$("#arena").append('<div class="b"></div>');
loop();
}, rand);
}());
*/

Try this
It makes use of passing the same object through each function so that the appended elements can be animated separately from the first
$("#start").on('click', function () {
$("#arena").append('<div class="b"></div>');
bbLoop($('.b:eq(0)'));
$("#start").hide();
(function loop() {
var rand = Math.round(Math.random() * (3000 - 500)) + 500;
setTimeout(function () {
var elem = $('<div class="b"></div>');
$("#arena").append(elem);
bbRight(elem);
doSomething();
loop();
}, rand);
}());
});
function bbLoop(obj) {
bbRight(obj);
}
function bbLeft(obj) {
obj.animate({
left: "-=300"
}, 1500, "swing", bbLeftDown(obj));
}
function bbRight(obj) {
obj.animate({
left: "+=300"
}, 1500, "swing", function() { bbRightDown(obj) });
}
function bbLeftDown(obj) {
obj.animate({
top: "+=300"
}, 300, "swing");
}
function bbRightDown(obj) {
obj.animate({
top: "+=300"
}, 300, "swing", bbLeft(obj));
}
function doSomething() {}
Or if you want them removed at the end, check here. .animate works in quirky ways sometimes, thus the approximation of the end animation time in the setTimeout is necessary

Related

animating number change in directive in angular

I have a directive which I have included jquery's animate functionality in to. I'd like for a particular variable's number to change with easing animation. The issue is that then the directive loads, the initial number is shown but doesn't show the number changing with the animation effect.
I have created a similar version in Plunkr to make it easy to see what's going on.
If I trigger $apply() from elsewhere the final numbers show, skipping the whole animated sqeuqnce of numbers. Also, in the code when I try to do apply on each step, it throws an 'in progress' error.
This plugin almost does what I need it to, except that it doesn't increment over decimal places and doesn't use easing. http://sparkalow.github.io/angular-count-to/
scope.$watch('difference', function(newVal, oldVal) {
jQuery({someValue: oldVal}).animate({someValue: newVal}, {
duration: 1000,
easing:'swing',
step: function(e) {
scope.display = e.toFixed(2);
scope.$parent.$apply();
}
});
});
and..
template: function(scope, element, attrs) {
return '<h3>' +
'<i class="fa progress-arrow" ng-class="[{\'fa-caret-up\': direction_up}, {\'fa-caret-down\': direction_down}]" aria-hidden="true"></i> ' +
'{{ display }}' +
'</div>' +
'</h3>' +
'<label>{{ label }} (lbs)</label>';
The answer was to use the angular $timeout function in conjunction with scope.$apply().
Here's the updated code that does in fact work:
scope.$watch('difference', function(newVal, oldVal) {
jQuery({someValue: oldVal}).animate({someValue: newVal}, {
duration: 500,
easing:'swing',
step: function(e) {
$timeout(function () {
scope.$apply(function () {
scope.display = e.toFixed(2);
});
});
}
});
And here it is in Plunkr
create directive
export class IncrementCounterDirective implements AfterViewInit {
#Input('appIncrementCounter') to: number = 0;
constructor(private elRef: ElementRef, private renderer: Renderer2) {}
ngAfterViewInit(): void {
this.counterFunc(this.to, 2000);
}
private counterFunc(end: number, duration: number = 3000) {
let range, current: number, step, timer: any;
range = end - 0;
current = end - 150;
step = Math.abs(Math.floor(duration / range));
// console.log(`step`, step);
timer = setInterval(() => {
current += 1;
this.setText(current);
if (current >= end) {
clearInterval(timer);
}
}, step);
}
setText(n: number) {
this.renderer.setProperty(this.elRef.nativeElement, 'innerText', `${n}`);
}
}
To use
<h3 class="stat-count" [appIncrementCounter]="607">000</h3>

Display cursor movement while running e2e test cases using protractor

I am completely new to e2e testing using protractor.
My question is, How to display/show cursor movement when I run my test cases. I have searched in google, I didn't get any result. Help me.
I've done it by injecting a module with addMockModule that tracks the mouse events and creates temporary fixed dots at the coordinates of the event:
In the protractor.conf file
onPrepare: function() {
// track mouse movements
var trackMouse = function() {
angular.module('trackMouse', []).run(function($document) {
function addDot(ev) {
var color = 'black',
size = 6;
switch (ev.type) {
case 'click':
color = 'red';
break;
case 'dblclick':
color = 'blue';
break;
case 'mousemove':
color = 'green';
break;
}
var dotEl = $('<div></div>')
.css({
position: 'fixed',
height: size + 'px',
width: size + 'px',
'background-color': color,
top: ev.clientY,
left: ev.clientX,
'z-index': 9999,
// make sure this dot won't interfere with the mouse events of other elements
'pointer-events': 'none'
})
.appendTo('body');
setTimeout(function() {
dotEl.remove();
}, 1000)
}
$document.on({
click: addDot,
dblclick: addDot,
mousemove: addDot
});
});
};
browser.addMockModule('trackMouse', trackMouse);
},

angularjs-nvd3-directives line chart ticks doesn't work

I work with cmaurer nvd3 directives with angularjs and you can see it here
I want to change the x-axis ticks count to 3 (start, middle, end dates), but nvd3 ticks properties(xaxisticks, xaxistickvalues) don't work.
I even tried to use unix timestamp, but no success.
Have any thoughts?
<nvd3-line-chart
...
xAxisTickFormat="xAxisTickFormatFunction()"
yAxisTickFormat="yAxisTickFormatFunction()"
xaxistickvalues="xAxisTickValuesFunction()" // not work
xaxisticks="3" // not work
showXAxis="true"
showYAxis="true"
interactive="true"
...
forcey="[]"
>
<svg></svg>
</nvd3-line-chart>
Not a perfect solution, but was a quick change that removes duplication for the most part. Add a cache of the ticks as they are created, and since they are create in order, can eliminate sequential dupes.
controller: function($scope) {
var vm = this;
vm.xAxisTick = ""; // <- cache the x-axis ticks here...
vm.x2AxisTick = ""; // <- cache the x2-axis ticks here...
vm.options = {
chart: {
type: 'lineWithFocusChart',
xAxis: {
scale: d3.time.scale(),
tickFormat: function(d) {
var tick = moment.unix(d).format('h:mm a');
// compare tick versus the last one,
// return empty string if match
if (vm.xAxisTick === tick) {
return "";
}
// update our latest tick, and pass along to the chart
vm.xAxisTick = tick;
return tick;
},
rotateLabels: 30,
showMaxMin: false
},
x2Axis: {
scale: d3.time.scale(),
tickFormat: function(d) {
var tick = moment.unix(d).format('h:mm a');
// compare tick versus the last one,
// return empty string if match
if (vm.x2AxisTick === tick) {
return "";
}
// update our latest tick, and pass along to the chart
vm.x2AxisTick = tick;
return tick;
},
rotateLabels: 30,
showMaxMin: false
},
yAxis: {
axisLabel: 'Why',
axisLabelDistance: 30,
rotateYLabel: false
}
}
};
It seems all line charts in nvd3 have the ticks hardcoded, so any ticks setting gets ignored:
xAxis
.scale(x)
.ticks( availableWidth / 100 )
.tickSize(-availableHeight, 0);
See here: https://github.com/novus/nvd3/issues/70. Sadly it seems to get it working one needs to fork the library, or wait until version 2.0 is released, hopefully solving this among other bugs.

nvD3, line chart, D3, angular

Can any one help why my line chart is not plotting correctly? I have put my code with data at : http://jsfiddle.net/madasuk/U9KH5/4/
can any one help to plot it correctly? lines in the graph are jumbled up and tool tip is also not appearing?
function addLineChart(){
var chart;
nv.addGraph(function() {
chart = nv.models.lineChart()
.options({
margin: {left: 100, bottom: 100},
// x: function(d,i) { return i},
x : (function(d,i) {
return new Date(d.x);
}),
showXAxis: true,
showYAxis: true,
transitionDuration: 250
})
;
// chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately
chart.xAxis
.axisLabel("Time (s)")
// .tickFormat(d3.format(',.1f'));
.tickFormat(function(d) {
return d3.time.format('%m/%d/%y')(new Date(d))
});
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(d3.format(',.2f'))
// .tickFormat(d3.format(',g'));
;
d3.select('#chart1 svg')
.datum(cumulativeMSIData())
.call(chart);
//TODO: Figure out a good way to do this automatically
nv.utils.windowResize(chart.update);
//nv.utils.windowResize(function() { d3.select('#chart1 svg').call(chart) });
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
return chart;
});
}

Can not export renderer text using highcharts/highstock when click range selector

I have a question related the chart export.
Please see Jsfiddle here
I added a text label using chart.renderer.text on the Yaxis for the latest value of series.
If I directly click button "Export Image". There is no problem, the label can be displayed. I'm using the following way to export image. draw_labels() is a function to draw yaxis label.
$("#b").click(function () {
chart.exportChart(null, {
chart: {
backgroundColor: '#FFFFFF',
width: 972,
height: 480,
events: {
load: function () {
draw_labels(this);
}
}
}
});
});
The problem is after I clicked range selector or change Xaxis range. When I try to export the
chart to image, there is no labels are drawn. The following is the complete code.
The following is the complete code:
$(function () {
var chart;
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-c.json&callback=?', function (data) {
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
events: {
load: function () {
draw_labels(this);
$("#b").click(function () {
chart.exportChart(null, {
chart: {
backgroundColor: '#FFFFFF',
width: 972,
height: 480,
events: {
load: function () {
draw_labels(this);
}
}
}
});
});
}
}
},
series: [{
name: 'AAPL',
id: 'test',
data: data,
tooltip: {
valueDecimals: 2
}
}],
navigator: {
enabled: false
},
yAxis: {
tickWidth: 0,
id: 'value_axis',
type: 'linear',
gridLineColor: '#EEE',
lineColor: '#D0CDC9',
lineWidth: 0,
minorTickInterval: null,
opposite: true,
offset: 0
},
xAxis: {
events: {
afterSetExtremes: function (e) {
console.log('test');
$('[id="test_text"]').remove();
draw_labels(chart);
}
}
}
});
});
function draw_labels(chart) {
$(chart.series).each(function (i, serie) {
var s_id = serie.options.id;
var temp_id = s_id;
var point = serie.points[serie.points.length - 1];
if (point) {
var pre, post;
if (point.y) {
var last_value_dis = (point.y).toFixed(1);
yaxis_name = 'value_axis';
//Get Yaxis position
var y_axis = chart.get(yaxis_name);
offsite_yaxis = 0;
element_text = chart.renderer.text(
//the text to render
'<span style="font-size:10px;font-weight:bold;color:' + serie.color + ';">' + last_value_dis + '</span>',
//the 'x' position
y_axis.width + y_axis.offset,
//the 'y' position
chart.plotTop + point.plotY + 3).attr({
id: temp_id + '_text',
zIndex: 999
}).add();
}
}
});
}
});
Here, I have fixed it for you. Here is a saved image:
Following changes have been done:
Added a redraw event to your exportchart
redraw: function () {
$("#test_text").remove() ;
draw_labels(this);
}
Changed this line in afterSetExtremes
$('[id="test_text"]').remove();
to
$("#test_text").remove() ;
Earlier one was not working as expected, so I had to change it.
Problem with disappearing text is related with id, when I removed it, label appears. But then I came across second issue, wrong y position. So i declare global variable, then when you call your function, set position of label, and use in chart exporting this variable. As a result label is exported correct.
http://jsfiddle.net/UGbpJ/11/

Resources