Fabricjs - select object programatically for immediate movement/drag - javascript

I am able to select object programatically using fabricjs. However, it does not behave like when one selects an object using mouse click. On a mouse click, the object comes under focus, and one can, for example, drag it. However, on programatic selection, I cannot immediately move an object. An example jsfiddle:
http://jsfiddle.net/ThzXM/1/
Programmatic selection:
canvas.setActiveObject(canvas.item(0));
What I would like to ultimately achieve is this: on clicking a button, a new rectangle is added to canvas, which the user can move around before placing it on canvas - without requiring extra clicks. Is it possible to do this in a cross-browser compatible way? (I know in some browsers I can fire a mouseclick event but most disallow it.)

You have to do this. Don´t forget to call setCoords() to update the bounding box of your object.
// Set the active element
canvas.setActiveObject(canvas.item(0));
// Set left, o right,or angle... check documentation.
//Don´t forget to call setCoords() after changes.
canvas.item(0).setLeft(80).setCoords();
//Then render the canvas
canvas.renderAll()

Related

How to create and use buttons in Spark AR (for Facebook)?

I'm working on a simple AR effect for Facebook in Spark AR studio using JavaScript. I have two 3D objects in the scene and I want to switch between them on button click.
So, for example, I have two buttons, and when I click on the first button I want to show the first 3D object (and hide another one). And vice versa - when I click on the second button I want to show the second 3D object and hide the first one.
I can see some examples of how can I access the object in the scene through the script, but I didn't find yet an example of how to create or use buttons in Spark AR.
Is there any easy "drag-and-drop" way to create a button and assign a function to it (like in Unity)? Or should I create an image of the button on the canvas in the scene, use JavaScript to "find" it, detect if the finger touch was made over this image and trigger a function this way?
There is no easy "drag-and-drop" way to create a button and assign a function to it.
You will need to create an image of the button on the canvas in the scene, use Javascript to "find" it, detect if the finger touch was made over this image and trigger a function this way. Here is example code:
var Scene = require('Scene');
var TouchGestures = require('TouchGestures');
var myBtn = Scene.root.find('button');
TouchGestures.onTap(myBtn).subscribe(function() {
//do stuff here
});
Also do not forget to enable the Tap Gesture in your project capabilities settings.
There is also the Native UI Picker that you can make use of:
https://developers.facebook.com/docs/ar-studio/docs/native-ui
(I'm not sure if this was available at the time the question was posted, I'm new to the game)
This is more "drag-and-drop" in that you don't have to create and place the buttons, just assign textures to fill them in, and then you can write a script to do whatever you want when the user selects a button.

Checking visibility of layer in KineticJS

I am trying to figure out how to check whether or not a layer in KineticJS is visible. I need this in order to appropriately toggle the visibility of any given layer when the user clicks a button. If it's visible, I want to hide it when they click the button. If it isn't visible, then I want to show it. Thoughts? I saw that there is a isVisible function, but nothing at all happens when I try to use it on a layer. The below code doesn't error, but it isn't doing anything. This is written in KineticJS on Angular. In my tests, I found that this event is appropriately getting triggered, so it's not that. I also found that the draw function is appropriately firing.
scope.$on('layertoggle', function(event){
var layerShapes = scope.kineticStageObj.get('#layer1');
if(!layerShapes.isVisible()){
layerShapes.hide();
}
else{
layerShapes.show();
}
scope.kineticStageObj.draw();
});
Try this:
var layerShapes = scope.kineticStageObj.get('#layer1')[0];
get returns a collection of shapes that match that criteria. Despite id being unique, you still have to access the first position of the array to access the desired shape.

jQuery draggable helper clone event

I'm using jQuery to drag items around. The items have click events. I'd like to register clicks where the user moves the mouse a little while the button is still down, so, using mouseup instead of click is the obvious answer, but! I need to use helper: 'clone' on drag, because items are in a container set to overflow: scroll (or auto) and I need to drag(/drop) outside of that container.
So the question is, is there a way to register a mouseup event on the clone?
I'd also need access to the original item - for a colour change, let's say.
Here's an example: http://jsfiddle.net/kFBtr/
Thank you.
Yes, using delegate or live, something like this:
jQuery('body').delegate('.ui-draggable-dragging','mouseup',function(){alert('OMG!! Mouse Up')})
To access the original element, just use prev:
function(){jQuery(this).prev()}
Example: http://jsfiddle.net/kFBtr/1/

Pass events through Protovis Panels

I have a Protovis graph that responds to pan/zoom events like the sample on the website, which covers the Panel that holds the graph with an empty one. Unfortunately it captures all Events like mouseover and mouseout which my underlying graph usually responds to.
This is because you have to set the Panel to accept all events. According to the docs the only valid params for this are 'all', 'painted' and 'none'
vis.add(pv.Panel)
.events("all")
How can I prevent the zoom Panel from capturing these events? Or how can I pass them through to the Panel below it?
I don't think this is necessarily the answer you want, but as far as I can tell there's no easy way to pass events through to lower elements. However, if your graph is similar to the example, you can simply change the order of the invisible Panel and the marks that should receive events, from:
vis.add(pv.Dot)
.event('click', function() { alert("clicked") })
// ... etc
vis.add(pv.Panel)
.events("all")
// ... etc
to:
vis.add(pv.Panel)
.events("all")
// ... etc
vis.add(pv.Dot)
.event('click', function() { alert("clicked") })
// ... etc
This will change the z-order of the marks, so that the dots receive click events before the panel. It's a little less plug-and-play, as you have to insert the panel at the correct point in your existing graph, but it should work.
You can see a jsFiddle based on the example here: http://jsfiddle.net/nrabinowitz/Ctxrr/
EDIT: Per the comment below, this approach can be a problem for zoom events. The better approach, shown in this updated fiddle, is to make the invisible Panel the parent of the marks in question - events will automatically bubble up from child to parent, and if the child doesn't set a listener for an event, it won't interfere with the parent. So as long as all foreground marks that need to receive events are children of the pan/zoom Panel, this should work.

selecting multiple elements using shift and mouse click - jquery

Is it possible to use shift and mouse click to select multiple elements on a page using jquery?
I have several divs that i have given a tabindex to so that i can select them and can do things like delete them etc.
I want to be able to select more than 1 by holding down shift and using the mouse to click on each div and am struggling to do this.
Does anyone know how this can be done?
I did something like that some time ago, with jQuery:
$(id).click(function(event){ //Mouse Click+shift event
if(event.shiftKey){
//give some attribute that can indentify the elements of the selection
//example rel='multi-selection' or class='multi-selection'
}
});
Then you should do functions that select this elements and do whatever you need, I used this to drag multiple elements. Example if you want to delete this divs, you can for example:
function deleteMultiSelection(){
$('html').find('div[rel=multi-selection']).each(function(){
$(this).remove();
})
}
$("#button").click(function(){
deleteMultiSelection();
})
Be careful because I didn't test this code.
I have a jQuery plugin that does exactly what you want it is called finderSelect it enables Shift+Click, Ctrl+Click, Ctrl+Click+Drag and Standard Clicking on any element.
It sounds like jQuery UI Selectable is what you're after, you can try it out here.
To stay with OS conventions, they key it uses is Ctrl and not Shift, this isn't an option you can change without changing the jQuery UI code itself. It also has the feature of click and drag over elements to get a rectangular selection as well...if that's of any use.
Sure, if you are willing to do some work :)
Listen for the shift keydown, set a var that you can access from within your click handler functions, if the var is set then add that item, (or their tabindex for your current implementation) to your list of items to operate on when an 'action button' is pressed.
unset the var when you get the shift keyup event.
To be honest, the Ctrl + left click for selecting multiple items is pretty standard UI behaviour and built-in to the jQueryUI Selectable. Did you also know you can left click and drag a focus over multiple items to select them?
However, I can see an advantage in offering the behaviour in question, so how about using left click or drag to select and then left click and drag to also de-select?
It may not be the most efficient way of doing it, but after playing around with the in-built callbacks, I've come up with something that seems to work. Based on the code in your question I've hooked into the in-built callback functions to store what was selected and also handle the selection removal. JavaScript duplicated below but

Categories

Resources