Like titles states I need two boards sharing the same slider. Lets say
var s = board3.create('slider',[[-10,-5],[-5,-5],[-11,-11,5]]);
and then another board (board4) to have the same slider meaning it reacts on on the slide of slider s
Is this possible? How to do it?
Two boards can be connected with the command "board.addChild()". In your case, there are the two boards "board3" and "board4". Whenever board3 is updated, board4 should also receive a board update event call. This can be achieved by the call of "board3.addChild(board4)":
var board3 = JXG.JSXGraph.initBoard('jxgbox3', {axis:true, boundingbox: [-15,10,15,-10], keepaspectratio:false}),
board4 = JXG.JSXGraph.initBoard('jxgbox4', {axis:true, boundingbox: [-15,10,15,-10], keepaspectratio:false});
board3.addChild(board4);
// slider s in board3 and
// point p in board4 which reacts to slider s
var s = board3.create('slider', [[-10,-5],[-5,-5],[-11,-11,5]]),
p = board4.create('point', [function() {
return s.Value();
},
function() {
return 0.5 * s.Value();
}]);
Related
Hey everyone I am currently building a mobile app for my company and I have a angularjs function that is currently adding a css class based on whether it's day or night. It does what it's supposed to do perfectly by putting a day or night image based on whether it's day or night.
The issue I am running into is that when testing the app right before the clock let's say goes from 1:59 to 2 it doesn't change the background image until you refresh the page. I want it to automatically change the background image without having to refresh and can't seem to find a way to do it. I will link the code here!
Any help is appreciated as it has me completely stumped...
Here is what I have in my html.
<div class="dashboard-welcome" ng-class="{'hide-homescreen-image-landscape'
: isLandscape, 'homescreenImageDay' : isDay, 'homescreenImageNight' :
isNight }">
Here is where the function is being called
angular.module('starter').controller('homeCtrl', ['$scope', '$interval',
'jsBridge', 'authService', 'tierService', '$window', fnc]);
function fnc($scope, $interval, jsBridge, authService, tierService, $window)
{
$scope.$on('$ionicView.afterEnter', function (event, viewData) {
setOrientation();
$scope.isDay = !isDayTime(1000);
$scope.isNight = isDayTime(1000);
});
Here is where the function is instantiated. Basically checking what time it is.
var isDayTime = function () {
var h = new Date().getHours();
if (h >= 14) {
return true;
} else {
return false;
}
}
I can't supply all the code since this application is thousands of lines long but this is the working function as of now. Just need it to switch background images without refreshing using angularjs...
Assuming that inside your div you are using an background-image: url("...")
I suggest you set up an object to hold a single $scope.isDay value instead of doing the calculation twice.
Also use the $interval service to check every nth millisecond to update your $scope.isDay value.
The code below works fine in dynamically changing a background image on a page using its CSS class.
HTML:
<div ng-class="data.isDay ? 'back1' : 'back2'"></div>
JS:
var exampleApp = angular.module('exampleApp', []);
exampleApp.controller('exampleController', function($scope, $interval) {
$scope.data = {
isDay: true,
classVal: {
one: 'text-danger',
two: 'text-success'
}
};
$interval(function() {
$scope.toggleImage();
}, 600);
$scope.toggleImage = function() {
$scope.data.isDay = ($scope.data.isDay ? false : true)
};
$scope.toggleImage();
});
Here is also a plnkr demo
I have a mover directive with the following html for the list
<select class="select-list" multiple
ng-model="unassigned"
name="unAssignedList"
data-no-dirty-check
ng-options="unassignedItem.descrip for unassignedItem in unassignedItems | orderBy:'descrip' | filter: filterCriteria"></select>
So, when I use this directive I can specify my filter-criteria like this
<data-sm:duallist-directive ng-required="false" keep-pristine="true"
unassigned-items-title="'#String.Format(Labels.availableX, Labels.items)'"
unassigned-items="currentItemGroup.unassignedItems"
assigned-items-title="'#String.Format(Labels.assignedX, Labels.items)'"
assigned-items="currentItemGroup.assignedItems"
sortable="false"
filter-criteria="{categoryId:selectedCategoryId}"
selected-item="currentItemGroup.selectedItem">
</data-sm:duallist-directive>
The problem is with the MoveAllLeft (or MoveAllRight) buttons. They have the following code:
$scope.moveRightAll = function() {
var unassignedItems = $scope.unassignedItems.slice(0);
var smItems = $scope.unassignedItems.slice(0);
angular.forEach(smItems, function (value, key) {
$scope.assignedItems.push(value);
removeItem(unassignedItems, value);
});
$scope.unassignedItems = unassignedItems;
if (!$scope.keepPristine)
$scope.form.$setDirty();
$scope.assigned = null;
};
The problem is that it works against original unfiltered array. Say, if I have 642 items in total and I filtered them by category to only, say, 5, I only want to move these 5 items when I press my button, not all 642 which I don't even see on the screen.
How can I modify my code to get only items which are filtered? Also, I don't have to enter filter-criteria, so it should work correctly when nothing is entered in the filter-criteria.
I solved the problem - it turned out to be very easy. I added the following code at the top
var filteredData ;
if ($scope.filterCriteria)
filteredData = $filter('filter')($scope.unassignedItems, $scope.filterCriteria);
else
filteredData = $scope.unassignedItems;
var unassignedItems = filteredData.slice(0);
var smItems = filteredData.slice(0);
and now only filtered items are moved.
My Problem:
I am trying to click options in a dropdown with Nightwatch, using sections in page objects. I'm not sure if it's a problem with the section declaration or i'm missing something scope-related. Problem is that it finds the element as visible, but when it tries to click it will throw error that it cannot locate it using recursion.
What could i try to do to fix this issue using sections?
In the test:
var myPage = browser.page.searchPageObject();
var mySection = searchPage.section.setResults;
// [finding and clicking the dropdown so it opens and displays the options]
browser.pause (3000);
browser.expect.section('#setResults').to.be.visible.before(1000);
myPage.myFunction(mySection, '18');
In the page object:
var searchKeywordCommands = {
myFunction: function (section, x) {
section.expect.element('#set18').to.be.visible.before(2000);
if (x == '18') section.click('#set18');
//[...]
};
module.exports = {
//[.. other elements and commands..]
sections: {
setResults: {
selector: '.select-theme-result', //have also tried with '.select-content' and '.select-options' but with the same result
elements: {
set18: '.select-option[data-value="18"]',
set36: '.select-option[data-value="36"]' //etc
}}}}
Here is my source code:
When i run this piece of core, it seems to find the section, finds the element visible (i also can clearly see that it opens the dropdown and shows the options) but when trying to click any option, i get the error: ERROR: Unable to locate element: Section[name=setResults], Element[name=#set18]" using: recursion
Here is the full error:
My attempts:
I have tried to declare that set18 selector as an individual element instead of inside of the section and everything works fine this way, but won't work inside of the section. I have also tried all the selectors available to define the section's selector, but it won't work with any of them.
This is what i am doing with(LOL)
I assume steps would be (find dropbox - click dropbox - select value).
var getValueElement = {
getValueSelector: function (x) {
return 'li[data-value="'+ x + '"]';
}
};
module.exports = {
//[.. other elements and commands..]
sections: {
setResults: {
commands:[getValueElement],
selector: 'div[class*="select-theme-result"', //* mean contains,sometime class is too long and unique,also because i am lazy.
elements: {
setHighlight:'li[class*="select-option-highlight"]',
setSelected:'li[class*="select-option-selected"]',
//set18: 'li[data-value="18"]',
//set36: 'li[data-value="36"]'
// i think getValueFunction is better,what if you have 100+ of set.
}}}}
In your test
var myPage = browser.page.searchPageObject();
var mySection = searchPage.section.setResults;
// [finding and clicking the dropdown so it opens and displays the options]
mySection
.click('#dropboxSelector')
.waitForElementVisible('#setHighlight',5000,false,
function(){
var set18 = mySection.getValueElement(18);
mySection.click(set18);
});
Ps:in my case(i think your case also), dropbox or any small third-party js framework which is used many times in your web app, so better create a different PageObject for it,make pageObject/section is simple as possible.
I'm creating an AngularJS and HTML5-based game that consists of users finding and clicking on birds. I want birds to appear at random places on the screen. If you click a bird - or if you wait more than 5 seconds - the bird automatically disappears.
I'm new to Angular, but I thought I would approach this problem by...
Creating a controller that is responsible for managing game
sessions (time limit, difficulty, etc.)
Using that
controller to create Bird objects (sub-controllers?) at a regular
interval.
Putting logic into each of the Bird objects so
that they automatically destroy themselves after 5 seconds or if
they are clicked.
Here's the main controller that created for part 1 of my problem:
myGameModule.controller( 'BirdActivityCtrl', function BirdActivityCtrl($scope) {
$scope.difficulty = 'Easy';
$scope.reward = 250;
$scope.spawn_interval = 1000;
$scope.status = 'starting';
$scope.birds_required = 30;
$scope.birds_clicked = 0;
$scope.time_left = 60;
$scope.start = function(){
location = '#/birds_in_progress';
$scope.status = 'in_progress';
}
$scope.cancel = function(){
location = '#/cafeteria';
}
});
Specifically, I am asking for help with Parts 2 and 3 of my question (mentioned above). I know that Angular has strict conventions for separating DOM elements from controllers. What is the correct way to spawn bird objects (which will be tied to DIVs on the page) and to destroy them after 5 seconds? Thank you for reading. Any help will be greatly appreciated!
Your DOM-related work should be in directives. Any directive can have it's own controller, it will be your BirdController. For any new bird instance (div with directive) new controller and scope will be created.
I suggest you put all your birds in some data structire in a service accessible from any part of your app with DI. Then you can simply use ng-repeat for you birds!
Something like this pseudocode should work:
game.factory('BirdStorage', ['in', 'ject', 'ables', function(){
var birds = [];
return {
addBird : function(){
birds.push({...})
},
deleteBird : function(id){
...
},
...
}
}]);
game.directive('bird', ['in', 'ject', 'ables', function(){
return {
restrict: 'EA',
template: '<div>...</div>',
replace: true,
scope: {
...
}
controller: function($scope, $element, $attrs){
...
}
link: function(){
...
}
}
}]);
Then you can use it in HTML like an element:
<ul>
<li data-ng-repeat="bird in birds">
<bird attrs=...>
</li>
</ul>
birds will come from a service you defined earlier.
And a logic to remove bird will come to BirdStorage. Just create a timeout that will delete specified bird:
setTimeout(function(){
this.deleteBird(id);
}, 5000)
Is there any simple way how to create undo redo function in Kineticjs ?
I have found a Undo Manager for HTML 5 in https://github.com/ArthurClemens/Javascript-Undo-Manager, but I don't know how to put in Kineticjs, please help me.
thank you.
I was able to implement a simple solution based on a post by Chtiwi Malek at CodiCode. I also used some of the code from this problem as an example to draw rectangles, so credits go to them and Chtiwi.
The only difference in my solution is I used toJSON() to store each layer state in an array instead of toDataURL() on the canvas. I think toJSON() is needed over toDataURL() to be able to serialize all the data necessary to store each action on the canvas, but I'm not 100% on this so if someone else knows please leave a comment.
function makeHistory() {
historyStep++;
if (historyStep < history.length) {
history.length = historyStep;
}
json = layer.toJSON();
history.push(json);
}
Call this function everytime you want to save a step to undo or redo. In my case, I call this function on every mouseup event.
Bind these 2 functions to the Undo/Redo events.
function undoHistory() {
if (historyStep > 0) {
historyStep--;
layer.destroy();
layer = Kinetic.Node.create(history[historyStep], 'container')
stage.add(layer);
}
}
function redoHistory() {
if (historyStep < history.length-1) {
historyStep++;
layer.destroy();
layer = Kinetic.Node.create(history[historyStep], 'container')
stage.add(layer);
}
}
Here's the jsfiddle. Don't forget to initialize the array and step counter up top. Good luck!
I am not familiar with KineticJS, but the approach should be similar to the provided demo (that also uses a canvas).
Perhaps another example helps. Let's say I have an app to create/move/delete colored shapes that represent musical notes. I have a way to click-drag and highlight a selection of notes. Pressing Delete on the keyboard invokes the function onDeleteGroup:
onDeleteGroup: function(gridModel) {
// collect all notes in an array
// ...
this._deleteGroup(notes);
this.undoManager.register(
this, this._createGroup, [notes], 'Undo delete',
this, this._deleteGroup, [notes], 'Redo delete'
);
}
All notes are deleted, and 2 methods are registered with the undo manager:
The undo function (undo of delete will be create)
The redo function (after undo/create will be delete again)
Both functions are straightforward:
_deleteGroup:function(notes) {
// removes each note from the model
// thereby removing them from the canvas
// ...
}
_createGroup:function(notes) {
// add each note to the model
// thereby adding them to the canvas
// ...
}
As you can see, the data object (array of notes) is passed around for creation and deleting. You can do the same for manipulating singular objects.
i have written a class for the functionality:
http://www.sebastianviereck.de/en/redo-undo-class-kinetic-js/
To solve event listeners problem, work on by making clones
$scope.makeHistory=function() {
$scope.historyStep++;
if ($scope.historyStep < $scope.history.length) {
$scope.history.length = $scope.historyStep;
}
var layerC = $scope.topLayer.clone();
$scope.history.push(layerC);
};
$scope.undoObject = function(){
if($scope.historyStep > 0) {
$scope.historyStep--;
$scope.topLayer.destroy();
if($scope.historyStep==0){
$scope.topLayerAdd(2); // will put empty layer
}
else{
var layer = $scope.history[$scope.historyStep-1].clone();
$scope.topLayerAdd(1,layer);
}
$scope.topLayer.draw();
}
};
$scope.redoObject = function(){
if($scope.historyStep <= $scope.history.length-1) {
$scope.historyStep++;
$scope.topLayer.destroy();
var layer = $scope.history[$scope.historyStep-1].clone();
if($scope.historyStep==0){
$scope.topLayerAdd(2); // will put empty layer
}
else{
$scope.topLayerAdd(1,layer);
}
$scope.topLayer.draw();
}
};
works perfectly for me.