Ember animate view changes - javascript

I experience an issue with animating the change of a particular view. I have two views which use among other properties the same 'options' parameter.
The DrawVisualizationView actually draws a chart with the options, that are obtained from inputs from the OptionsView.
The .hbs file:
<!-- Options Part --!>
<div>
{{view App.OptionsView options=controller.options}}
</div>
<!-- Visualization Part --!>
<div id="visualization">
{{view App.DrawVisualizationView options=controller.options}}
</div>
I use ember-animate to produce some animations between routes and I would like to produce an animation when I change the options and the chart is redrawn. For example, the old one would fade out and the new new would fade in.
Both views use VisualizationController and VisualizationRoute, so I don't have any transitions between routes and controllers.
Here is DrawVisualizationView
App.DrawVisualizationView = Ember.View.extend({
willAnimateIn: function() { //ember-animate method
//preparation
},
animateIn: function(done) {
//some animation
},
animateOut: function(done) {
//some animation
},
drawVisualization: function(){
//draw a chart
}.observes('options.#each').on('didInsertElement')
});
The VisualizationController is set up in a way, that every change in options in OptionsView triggers redrawing of a chart through DrawVisualizationView.
willAnimateIn, animateIn and animateOut work only once during the loading of a page.
I tried events like didInsertElement and adding eventManager but none of them are triggered when the DrawVisualizationView is invoked after options changes.
Is there a way to trigger animate actions of the DrawVisualizationView if a particular option is changed?

Author of ember-animate. If you want your view to re-animate when options changes, do this:
App.DrawVisualizationView = Ember.View.extend({
willAnimateIn: function() { //ember-animate method
//preparation
},
animateIn: function(done) {
//some animation
},
animateOut: function(done) {
//some animation
},
drawVisualization: function () {
this.animateOut(function () {
this.willAnimateIn();
this.animateIn();
}.bind(this));
}.observes('options.#each')
});

Related

Refreshing a div every 3 seconds

I'm trying to refresh this AnyChart function div every 3 seconds, so that when data is entered using the (hopefully) interactive wordcloud on a wesbite, it refreshes automatcially. My code currently duplicates the div once, 3 seconds after the page loads. Thanks in advance for any help.
anychart.onDocumentReady(function() {
anychart.data.loadGoogleSpreadsheet({
key: '14jdnD4rzxPdZfLqpeh4gjtoN6ERyZuovBOoFOwuZQAM',
sheet: '2'
}, function(data) {
var chart = anychart.tagCloud();
// configure a color scale here
var customColorScale = anychart.scales.linearColor();
customColorScale.colors(["#FEBF57", "#428A46", "#21C5B4", "#E7438A", "#21295E"]);
// set the color scale as the color scale of the chart
chart.colorScale(customColorScale);
// add a color range
chart.colorRange().enabled(true);
chart.normal().fontFamily("Rubik", "sans-serif");
// set data
chart.data(data);
chart.container('wordcloud-container');
chart.draw();
});
});
$(document).ready(function() {
function refresh() {
var div = $('#wordcloud-container'),
divHtml = div.html();
div.html(divHtml);
}
setInterval(function() {
refresh()
}, 3000);
})
<h1>TEST WordCloud with colours</h1>
<div id='wordcloud-container'>
The issue is because your refresh() function simply gets the existing HTML of the container and then sets that same HTML within the container again, duplicating the content.
To actually refresh the chart you need to call loadGoogleSpreadsheet() from within the interval handler.
An important change to make here is to use setTimeout() within the chart callback instead of setInterval(). The latter can end up queueing requests if the response is slow, which can lead to your site becoming unresponsive due to too many in-progress requests. The setTimeout() approach will only start the timer when the previous request was successfully handled.
let loadChartData = () => {
console.log('loading data...');
anychart.data.loadGoogleSpreadsheet({
key: '14jdnD4rzxPdZfLqpeh4gjtoN6ERyZuovBOoFOwuZQAM',
sheet: '2'
}, function(data) {
var chart = anychart.tagCloud();
// configure a color scale here
var customColorScale = anychart.scales.linearColor();
customColorScale.colors(["#FEBF57", "#428A46", "#21C5B4", "#E7438A", "#21295E"]);
// set the color scale as the color scale of the chart
chart.colorScale(customColorScale);
// add a color range
chart.colorRange().enabled(true);
chart.normal().fontFamily("Rubik", "sans-serif");
// set data
chart.data(data);
$('#wordcloud-container').empty(); // important change here to stop duplicating the chart
chart.container('wordcloud-container');
chart.draw();
setTimeout(loadChartData, 3000);
});
}
$(document).ready(function() {
loadChartData();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.8.0/js/anychart-bundle.min.js"></script>
<link rel="stylesheet" href="https://cdn.anychart.com/releases/8.8.0/css/anychart-ui.min.css" />
<h1>TEST WordCloud with colours</h1>
<div id='wordcloud-container'></div>
One big issue to note here is that your approach of AJAX polling is not at all scalable. If this is implemented in a production system you will most likely hit rate limits on the Google docs API, or even be blocked for a potential DDOS risk.

mouseup/down on entire SPA angular

In my component class I have
#HostListener('document:mousedown', ['$event'])
onMouseDown() {
this.holding = true;
}
#HostListener('document:mouseup', ['$event'])
onMouseUp() {
this.holding = false;
}
In this project I'm also using swiper library. My swiper is 200px height and 100% width. Swiper use some own events catching for "grabing" elements to make it actually swipeable.
Now when I have my mouse on top of swiper element and I click above code doesn't catch the event.
This shoudln't happen but it is. Also what make it even weirder is that it doesn't catch only the left mouse click, right click works correctly.
How to make it works even when mouse is on top of swiper?
Edit
For some reason I'm not able to reproduce issue at online code playground, so I've created very basic app with just two components and I pushed it to git.
In this project I'm displaying {{ holding }} and as you can see (if you clone and ng serve this app) when clicking at the top or bottom of page it change from false to true but when clicking on swiper it doesn't catch onMouseDown and the value doesn't change.
because Swiper prevent the dispatching of internal DOM element, you can use Event API from swiper to get what is happening inside Swiper main dom element.
For example on your case you can do something like this :
this.mySwiper = new Swiper('.nav', {
paginationClickable: false,
grabCursor: true,
loop: true,
autoplay: 1000,
slidesPerView: 3,
spaceBetween: 50
});
this.mySwiper.on('touchStart', () => {
this.touchService.triggerTouchStart();
});
this.mySwiper.on('touchEnd', () => {
this.touchService.triggerTouchStop();
});
You can introduce new service on your application to abstract to the rest of your application this trick to be binded on all mousedown | mouseup events. bellow you can find the implementation :
export class TouchService {
private _manualControl$: Subject<boolean>;
constructor() {
this._manualControl$ = new Subject();
// React to the document mouse event.
fromEvent(document, 'mousedown').subscribe(() => this.triggerTouchStart());
fromEvent(document, 'mouseup').subscribe(() => this.triggerTouchStop());
}
// Can be call manually to force new state.
triggerTouchStart(): void {
this._manualControl$.next(true);
}
triggerTouchStop(): void {
this._manualControl$.next(false);
}
get touch$(): Observable<boolean> {
return this._manualControl$.asObservable();
}
}
Now you have observable which react on native mousedown and mouseup events and can also be trigger by manual API call like
this.mySwiper.on('touchStart', () => {
this.touchService.triggerTouchStart();
});
this.mySwiper.on('touchEnd', () => {
this.touchService.triggerTouchStop();
});
Finally you can use this service like following :
constructor(private touchService: TouchService) {
this.touchService.touch$.subscribe(e => this.holding = e);
}
I can't prupose you pull request on your project because i don't have right to do it. You can see it in action here
git remote add fork https://bitbucket.org/yghidouche/ng-hover-issue
git fetch fork issues_1

How to customize fullcalendar, a javascript event calendar?

I am new to javascript and web developing.
So, I used the fullcalendar library (https://fullcalendar.io/) to make a calendar view, and I wonder if I am able to customize it myself.
This is my Markup code:
<div id="blueBackground">
<div class="container">
<div id='calendar'></div>
</div>
</div>
So, the "blueBackground" is for changing the entire webpage background to blue colour. The "container" class if for resizing the fullcalendar to a more appropiate view.
This is the Javascript code:
$(document).ready(function () {
// page is now ready, initialize the calendar...
$('#calendar').fullCalendar({
// put your options and callbacks here
})
});
The javascript code is straight from the fullcalendar Usage page.(https://fullcalendar.io/docs/usage/)
So, how do I customize it? I am a complete newbie at javascript. I look around on the other questions similar to this but it bears no fruits. I can't make it work.
Thank you in advance.
I am currently also using fullcalendar and here is some of the customization i have made:
$(document).ready(function () {
// page is now ready, initialize the calendar...
$('#calendar').fullCalendar({
//Changing the header like this:
header:
{
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
//Lets us edit in the calendar
editable: true,
//When u select some space in the calendar do the following:
select: function(start, end, allDay){
//do something when space selected
},
//When u click on an event in the calendar do the following:
eventClick: function(event, element) {
//do something when event clicked
},
//When u drop an event in the calendar do the following:
eventDrop: function(event, delta, revertFunc) {
//do something when event is dropped at a new location
},
//When u resize an event in the calendar do the following:
eventResize: function(event, delta, revertFunc) {
//do something when event is resized
},
//Add some test events.
events: [
{
title : 'event1',
start : '2016-09-15'
},
{
title : 'event2',
start : '2016-09-15',
end : '2016-09-16'
},
{
title : 'event3',
start : '2016-09-15T12:30:00',
allDay : false // will make the time show
}
]
})
});
In my project I also use PHP and MySQL to store and change the events. Other than that almost all the customization's you can do are listed in the docs.
EDIT #1
How to change the basic color settings etc:
Changing the whole background color:
<div id="calendar" style="background:#de1f1f;"></div>
Changing the event background color (when you drag a new event the background is not blue anymore but red):
$(document).ready(function() {
$('#calendar').fullCalendar({
eventBackgroundColor: "#de1f1f"
});
});
Changing the event color (not blue anymore but red):
$('#calendar').fullCalendar({
events: [
// my event data
],
eventColor: "#de1f1f"
});
Changing the border color for the events:
$('#calendar').fullCalendar({
eventBorderColor: "#de1f1f"
});
Hope that clarified just some of the customization you can do :)

chart.js on animation end callback

Does the library chart.js support any sort of callbacks on specific events? I'm mostly interested in 'on animation end' event, but would be nice to know any other events if they're supported.
If this is not an option, do you know any workarounds? I'm using jQuery and vue.js and I just need to show some additional text on the page (completely outside of the chart itself) when chart.js finishes the animation of the chart.
For Chart.Js 2.6.0
options: {
cutoutPercentage: 90,
animation: {
duration: 2000,
onProgress: function(animation) {
$progress.attr({
value: animation.animationObject.currentStep / animation.animationObject.numSteps,
});
},
onComplete: function(animation) {
alert('onAnimationComplete')
}
}
},
See this codepen https://codepen.io/shivabhusal/pen/XaZQaW
There is an onAnimationComplete option you can specify to run stuff once the animation completes. See this section of the documentation.
Example
var ctx = document.getElementById("chart").getContext("2d");
var myLine1 = new Chart(ctx).Line(lineChartData1, {
onAnimationComplete: function() {
alert('animation complete')
}
});
Fiddle - http://jsfiddle.net/4vo72rLd/

What does rootmodifers do in famo.us?

I am new to Famo.us, can anybody explain me what does rootmodifers do in famo.us, here is its example
function SlideshowView () {
Views.apply(this, arguments);
this.rootModifier = new StateModifier({
size:this.options.size
});
this.mainNode = this.add(this.rootModifier);
_createLightBox.call(this);
_createSlides.call(this);
}
this.rootMidifier just allows you to have a way to control the entire slideShow's position, opacity, origin, or alignment later in the applications. More importantly this.rootModifier is added to the render node like this this.mainNode = this.add(this.rootModifier); This code places the modifier at the top of the render tree for the slideshow branch and exposes access to the modifier for later use in the all. For example later in the app you could have a function that changes the opacity.
SlideShow.prototype.hide = function() {
this.rootModifier.setOpacity(0, {duration: 3000});
}

Categories

Resources