How can I determine the screen size using addon SDK? - firefox-addon-sdk

How can I get the screen size using with addon SDK ?
var w = screen.width/2;
gives me an error : Message: ReferenceError: screen is not defined

You can use the window you have associated to your add-on; it's probably safer, because it will work even if the last visible window is closed but firefox is still opened (e.g. on OS X):
const { window: { screen }} = require("sdk/addon/window");
console.log(screen.width);

This will work:
var screen = require('sdk/window/utils').getMostRecentBrowserWindow().screen;
console.log(screen.width);

If you want multi monitor support I have a script but you have to understand it. It uses XPCOM, and it needs a range. This script only checks along the x axis, you should also check along the y axis.
So this is the script here that will detect all monitors in the x plane IF it falls in the y plane of 0-20 coordintates of primary screen, I don't recommend this method.
var sm = Cc['#mozilla.org/gfx/screenmanager;1'].getService(Ci.nsIScreenManager);
function getScreens() {
var screen = null;
var screens = [];
var screenManager = sm;
var min = 0;
var max = 0;
for (x = 0; x < 15000; x += 600) {
var s = screenManager.screenForRect(x, 20, 10, 10);
if (s != screen) {
screen = s;
var left = {},
top = {},
width = {},
height = {};
screenManager.primaryScreen.GetRect(left, top, width, height);
screens.push({
width: width.value,
height: height.value,
min: min,
max: min + width.value
});
min += width.value;
}
}
return screens;
}
var screens = getScreens();
console.log('screens:', screens);
This is the method I recommend
I needed to detect all monitor dimensons and had to resort to jsctypes, if you need that its here: https://github.com/Noitidart/NativeShot/blob/master/modules/workers/MainWorker.js#L853-L1523
That code is extremely long, thats because its getting all monitors and the taking screenshots of them. So you will want to extract just the monitors part. If you need help with it I can do it for you.

Related

ChartJS - line graph, position tooltip

I have the following graph with 3 datasets. Everything works fine except for one small bug. I want to tooltip to be placed only on the first dataset, as it currently is placed on the average position of all datasets.
Here is a screenshot:
I know that ChartJS has the positioners function (the one below), but I can't figure out how to ignore the other 2 datasets so the tooltip is sticked only to the first line graph
Chart.Tooltip.positioners.top = function (elements, eventPosition) {
const tooltip = this;
return ;
};
You can also define a custom position function for tooltips. like this,
Chart.Tooltip.positioners.custom = function(elements, eventPosition) {
var x = eventPosition.x;
var y = eventPosition.y;
var minDistance = Number.POSITIVE_INFINITY;
var i, len, nearestElement;
var top_element = elements[0];
for (i = 0, len = elements.length; i < len; ++i) {
console.log(elements[i].tooltipPosition().y);
if (elements[i].tooltipPosition().y < top_element.tooltipPosition().y) {
top_element = elements[i];
}
}
var tp = top_element.tooltipPosition();
x = tp.x;
y = tp.y;
return {
x: x,
y: y
};
};
Once done, you can specify it in tooltips.options.
More information :
https://www.chartjs.org/docs/latest/configuration/tooltip.html#position-modes
Hope it helps!

How target a movieClip in animate cc in this drag drop code

is there a way to modify this code for animate cc to make object in the stage and interact with it ?
it is a bit of pain to make drag and drop in createjs for animate cc
there is nothing in the web that describe how to do it for animate cc or flash cc even the documentation has nothing to tell about drag and drop in the canvas
//Stage
var stage = new createjs.Stage("demoCanvas");
//VARIABLES
//Drag Object Size
dragRadius = 40;
//Destination Size
destHeight = 100;
destWidth = 100;
//Circle Creation
var label = new createjs.Text("DRAG ME", "14px Lato", "#fff");
label.textAlign="center";
label.y -= 7;
var circle = new createjs.Shape();
circle.graphics.setStrokeStyle(2).beginStroke("black")
.beginFill("red").drawCircle(0,0, dragRadius);
//Drag Object Creation
//Placed inside a container to hold both label and shape
var dragger = new createjs.Container();
dragger.x = dragger.y = 100;
dragger.addChild(circle, label);
dragger.setBounds(100, 100, dragRadius*2, dragRadius*2);
//DragRadius * 2 because 2*r = width of the bounding box
var label2 = new createjs.Text("HERE", "bold 14px Lato", "#000");
label2.textAlign = "center";
label2.x += 50;
label2.y += 40;
var box = new createjs.Shape();
box.graphics.setStrokeStyle(2).beginStroke("black").rect(0, 0, destHeight, destWidth);
var destination = new createjs.Container();
destination.x = 350;
destination.y = 50;
destination.setBounds(350, 50, destHeight, destWidth);
destination.addChild(label2, box);
//DRAG FUNCTIONALITY =====================
dragger.on("pressmove", function(evt){
evt.currentTarget.x = evt.stageX;
evt.currentTarget.y = evt.stageY;
stage.update(); //much smoother because it refreshes the screen every pixel movement instead of the FPS set on the Ticker
if(intersect(evt.currentTarget, destination)){
evt.currentTarget.alpha=0.2;
box.graphics.clear();
box.graphics.setStrokeStyle(3)
.beginStroke("#0066A4")
.rect(0, 0, destHeight, destWidth);
}else{
evt.currentTarget.alpha=1;
box.graphics.clear(); box.graphics.setStrokeStyle(2).beginStroke("black").rect(0, 0, destHeight, destWidth);
}
});
//Mouse UP and SNAP====================
dragger.on("pressup", function(evt) {
if(intersect(evt.currentTarget, destination)){
dragger.x = destination.x + destWidth/2;
dragger.y = destination.y + destHeight/2;
dragger.alpha = 1;
box.graphics.clear();
box.graphics.setStrokeStyle(2).beginStroke("black").rect(0, 0, destHeight, destWidth);
stage.update(evt);
}
});
//Tests if two objects are intersecting
//Sees if obj1 passes through the first and last line of its
//bounding box in the x and y sectors
//Utilizes globalToLocal to get the x and y of obj1 in relation
//to obj2
//PRE: Must have bounds set for each object
//Post: Returns true or false
function intersect(obj1, obj2){
var objBounds1 = obj1.getBounds().clone();
var objBounds2 = obj2.getBounds().clone();
var pt = obj1.globalToLocal(objBounds2.x, objBounds2.y);
var h1 = -(objBounds1.height / 2 + objBounds2.height);
var h2 = objBounds2.width / 2;
var w1 = -(objBounds1.width / 2 + objBounds2.width);
var w2 = objBounds2.width / 2;
if(pt.x > w2 || pt.x < w1) return false;
if(pt.y > h2 || pt.y < h1) return false;
return true;
}
//Adds the object into stage
stage.addChild(destination, dragger);
stage.mouseMoveOutside = true;
stage.update();
thanks
I am not exactly sure what you are asking. The demo you showed works fine (looks like it came from this codepen), and it is not clear what you are trying to add. This demo was made directly in code, not with Animate CC - which is really good for building assets, animations, and display list structure, but you should write application code around what gets exported.
There are plenty of documentation and examples online for Drag and Drop, in the EaselJS GitHub, and EaselJS docs:
DragAndDrop demo in GitHub
Live demo on EaselJS demos page
Documentation on pressMove
Tutorial on Mouse Events which includes Drag and Drop
I recommend narrowing down what you are trying to do, show what code or approaches you have tried so far, and posting specific questions here.
Lastly, here is the first part of an ongoing series for working with Animate CC: http://blog.gskinner.com/archives/2015/04/introduction-to-the-flash-cc-html5-canvas-document.html
Cheers.

event processing in dojo surface

I have a surface where i draw some kind of dynamic image based on the data from my backend, on click of a certain area, i want different data to be published. but my following code always takes last data drawn to publish.
function renderICD() {
var totalx=1200;
var totaly=1000;
var xOffset = 150;
var yOffset = 20;
surface = dojox.gfx.createSurface("icdTab",totalx+2,totaly+2);
var grid = surface.createGroup();
var step = 1;
var xyHolder = {};
var group = grid.createGroup();
for(var ii=0;ii<2;ii++)
{
var x = (step-1) * (75+85);
step++;
var group = grid.createGroup();
group.createRect({x:xOffset+x+33, y:yOffset+20+90, width: 10, height: 10}).setFill([255, 255, 255, 0.9])
.setStroke({color:'black' , width:2});
dojo.connect(group.getEventSource(),"onclick",function(e) {
var internal = ii;
alert("publishing "+internal);
//shape was clicked, now do something!
});
grid.createText({x:xOffset+x+33, y:yOffset+20+80, text:ii,align:"middle"})
.setFill('red')
.setFont({size: '10px',weight: "bold"});
}
}
As i understand, only 1 instance of function written to handle event is present, but what i am trying to handle is 2 different events.
How can i achieve this?
Snapshot of surface with 2 rects, when i click on both rects, i get '2' in my alert.
JavaScript has functional scope, not block scope, so you only have one ii variable, which is always equal to "2" by the time you click on a rect. There are many ways to fix this, example below :
function renderICD() {
var totalx=1200;
var totaly=1000;
var xOffset = 150;
var yOffset = 20;
surface = dojox.gfx.createSurface("icdTab",totalx+2,totaly+2);
var grid = surface.createGroup();
var step = 1;
var xyHolder = {};
var group = grid.createGroup();
dojo.forEach([0,1], function(item, ii) {
var x = (step-1) * (75+85);
step++;
var group = grid.createGroup();
group.createRect({x:xOffset+x+33, y:yOffset+20+90, width: 10, height: 10}).setFill([255, 255, 255, 0.9])
.setStroke({color:'black' , width:2});
dojo.connect(group.getEventSource(),"onclick",function(e) {
var internal = ii;
alert("publishing "+internal);
//shape was clicked, now do something!
});
grid.createText({x:xOffset+x+33, y:yOffset+20+80, text:ii,align:"middle"})
.setFill('red')
.setFont({size: '10px',weight: "bold"});
});
}

How to give hyperllink in an image using Titanium

I am looking to give a hyperlink on particular point in an image using Titanium, like Facebook does in showing images on focus of faces it is showing names.
So is there any possibility i can do this on titanium. If possible please provide some sample code of it.
Just use the click event for a view, then detect if its inside a certain area, I use a circular area as an example since its the most straightforward to code, you can use this as a guide for rectangular areas
var clickPoint = {x : 100, y : 100};
var clickRadiusSquared = 25;
// View user clicks on
var view = Ti.UI.createView({
width : 200,
height : 200,
});
view.addEventListener('click', function(e) {
// Get the X and Y coordinates of the click inside the view
var x = e.x;
var y = e.y;
// Now see if it is inside the area
var distanceSquared = Math.pow(clickPoint.x - x, 2) + Math.pow(clickPoint.y - y, 2);
if(distanceSquared < clickRadiusSquared) {
// Open the link or do whatever
Titanium.Platform.openURL('http://www.yoururl.com');
}
});

Making paths and images draggable in Raphael js

Is it possible to be able to drag and drop objects other than just circles and rectangles around a page using Raphael js?
I want to add in paths and images which you can then move around but its proving tricky.
I would like to work this out with Raphael because of its support with touch interfaces.
Here is the code
<script>
window.onload = function () {
var R = Raphael(0, 0, "100%", "100%"),
r = R.circle(100, 100, 50).attr({fill: "hsb(0, 1, 1)", stroke: "none", opacity: .5}),
g = R.circle(210, 100, 50).attr({fill: "hsb(.3, 1, 1)", stroke: "none", opacity: .5}),
b = R.circle(320, 100, 50).attr({fill: "hsb(.6, 1, 1)", stroke: "#fff", "fill-opacity": 0, "stroke-width": 0.8, opacity: .5}),
p = R.path("M 250 250 l 0 -50 l -50 0 l 0 -50 l -50 0 l 0 50 l -50 0 l 0 50 z") .attr({fill: "hsb(.8, 1, 1)", stroke: "none", opacity: .5});
var start = function () {
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.animate({r: 70, opacity: .25}, 500, ">");
},
move = function (dx, dy) {
this.attr({cx: this.ox + dx, cy: this.oy + dy});
},
up = function () {
this.animate({r: 50, opacity: .5}, 500, ">");
};
R.set(r, g, b, p).drag(move, start, up);
};
</script>
The key here (that I found) is to convert the x and y deltas into translate values, which the path object understands.
http://www.nathancolgate.com/post/2946823151/drag-and-drop-paths-in-raphael-js
Effectively the same approach:
var paper = Raphael(10, 50, 320, 200);
var tri = paper.path("M0 0L0 20L25 10L0 0Z").attr("fill", "#ff0");
var rex = paper.rect(10, 20, 50, 50).attr("fill", "#ff0");
var start = function () {
this.odx = 0;
this.ody = 0;
this.animate({"fill-opacity": 0.2}, 500);
},
move = function (dx, dy) {
this.translate(dx - this.odx, dy - this.ody);
this.odx = dx;
this.ody = dy;
},
up = function () {
this.animate({"fill-opacity": 1}, 500);
};
tri.drag(move, start, up);
rex.drag(move, start, up);
As translate is being deprecated in Raphael, I've modified Nathan's answer to work with transform:
var paper = Raphael(10, 50, 320, 200);
var tri = paper.path("M0 0L0 20L25 10L0 0Z").attr("fill", "#ff0");
var start = function () {
this.lastdx ? this.odx += this.lastdx : this.odx = 0;
this.lastdy ? this.ody += this.lastdy : this.ody = 0;
this.animate({"fill-opacity": 0.2}, 500);
},
move = function (dx, dy) {
this.transform("T"+(dx+this.odx)+","+(dy+this.ody));
this.lastdx = dx;
this.lastdy = dy;
},
up = function () {
this.animate({"fill-opacity": 1}, 500);
};
tri.drag(move, start, up);
I'm relatively new to Raphael and came up with this through trial and error, so someone out there might have an explanation of why it works or a cleaner way of doing it ;)
I experimented with this a little while ago, and got it working using the following approach:
Add an initially hidden, styled, absolutely positioned div with a transparent background and suitable border styling to your page, and using jQuery/UI make it draggable.
Add a click event to each of the Rapahel/SVG elements you wish to be draggable, and in this event add code to resize and reposition the div over the element which has just been clicked and then make it visible.
Add code to the div which updates the position of the Raphael element when it is dragged.
I extended this to add resizing capabilities, and this also worked well, but going forward it would be great to see drag, drop and resize capabilities (ideally properly integrated into the library rather than using jQuery) built into Raphael, as these features would open up a whole bunch of possibilities for in-browser designers using pure Raphael.
Try this for non-circles. Circles attributes are different than images, text, etc, I think.
var start = function () {
this.ox = this.attr("x");
this.oy = this.attr("y");
this.animate({r: 70, opacity: .25}, 500, ">");
},
move = function (dx, dy) {
this.attr({x: this.ox + dx, y: this.oy + dy});
},
up = function () {
this.animate({r: 50, opacity: .5}, 500, ">");
};
I would recommend you raphael.draggable library, that makes the trick for you. I used it with a map application that allows the user to use zoom over the map and then drag it.
I had a problem with this library in IE8 because in the function events refering to mousedown, mousemove, etc. IE drops an exception, telling the user that event is null. You can solve it by replacing the event by e and adding e = e || event in the raphael.draggable.js script. This fix doesn't affect other browsers.
So, the method mousemove in the startDragger is:
function startDragger() {
document.onmousemove = function(e) {
e = e || event
if (paper.draggable.current()) {
var transX = e.clientX - lastDragX;
var transY = e.clientY - lastDragY;
paper.draggable.current().translate(transX, transY);
lastDragX = e.clientX;
lastDragY = e.clientY;
}
};
}
And the link:
https://github.com/mephraim/raphael.draggable
Hope this could help you.
it's not that hard if you understand the usual dragging functions Chris Butler gave you.
I use this:
var start = function () {
//storing original coordinates
this.xSource = this.attrs.path[0][1];
this.ySource = this.attrs.path[0][2];
this.xDest = this.attrs.path[1][1];
this.yDest = this.attrs.path[1][2];
this.attr({opacity: 0.5});
},
move = function (dx, dy) {
//move will be called with dx and dy
var xS = this.xSource+dx;
var xD = this.xDest+dx;
var yS = this.ySource+dy;
var yD = this.yDest+dy;
this.attr({path: "M"+ xS +" "+ yS +"L"+ xD +" "+yD});
},
drag = function(){
this.node.drag(this.move,this.start,this.up);
};
You can also know which sort of figure you're dragging in the functions with this.type, so that you can make these functions work for all sort of figures.
In case anyone is still looking for a solution, here's a plugin that scales, rotates and drags all shapes including paths.
https://github.com/ElbertF/Raphael.FreeTransform