TextBox width dynamic adjustment fabric js - html5-canvas

I want to modify to the textbox width according to the longest line that user enters, dynamically. I initialize the width = width of my canvas but as soon as user exits editing, the width must shorten to the width of the longest line in user's text written in the textBox.
obj.on(("editing:exited"),function() {
can.setActiveObject(textBox);
var largest = Math.max.apply(Math, can.getActiveObject().__lineWidths);
can.getActiveObject().set("width",largest);
})
Problem is that each time I exit editing, the width reduces and the top line is shifted below. I just cant understand what is happening. Please help at the earliest. Thanks in advance. Please also upload a demo so that I can see the effect of your code.
Update 1 : If I change the line
can.getActiveObject().set("width",largest);
to
can.getActiveObject().set("width",(largest + 1));
It works as desired. I have no idea why this is happening.

I have found the answer to this question by some coding myself.
https://jsfiddle.net/xpntggdo/8/
To all those who might be facing a similar issue, here is the fiddle and here is the code.
textBox.on(("changed"),function(){
var actualWidth = textBox.scaleX * textBox.width;
var largest = canvas.getActiveObject().__lineWidths[0];
var tryWidth = (largest + 15) * textBox.scaleX;
canvas.getActiveObject().set("width",tryWidth);
if((textBox.left + actualWidth) >= canvas.width - 10)
{
textBox.set("width", canvas.width - left - 10)
}
canvas.renderAll();
});
textBox.on(("modified"),function(){
left = textBox.left;
canvas.renderAll();
});

Related

How do I "register" a dragged group to specific coordinates with d3?

I'm trying to do something that (it seems to me!) should be simple,
but my attempts are getting very convoluted, and I'm looking for d3
guidance.
Suppose I have a dragged group object (consisting of a rectangle and
its text) that has been dropped someplace at the end of a drag. I want
to "register" this group at specific coordinates. How do I do that?
I am adding my code to the dragended() function associated with
d3.drag's on("end") event.
function dragended(d) {
var move = d3.select(this);
var g = move._groups[0][0]; // same as this!
var rect = g.children[0]
rect.x = schedLeft;
rect.y = schedTop;
d3.select(this).classed("active", false);
}
I bind d3.select(this) to the variable move, and get an object
like that shown in the attached figure (Chrome developer Local).
EDIT: move._groups[0][0] is silly; it's the same as this!
Using this I can get the group (with child rect and
text nodes) that I want to move.
schedLeft is the x coordinate where I want the group dropped. The rect node has x and y attributes, but my rect.x = schedLeft
doesn't change anything (watching in the debugger).
Is that even the right way to have a transition of the entire group
(ie, including the attending text) to its new location?
Thanks to hints I found on SO here (from 2013!) I got it working using this:
function dragended(d) {
// register dragged move into hourSched
var top = schedTop + (nsched++) * menuWOHgt;
var transX = newDropX - d.x ;
var transY = newDropY - d.y;
var tstr = `translate( ${transX}, ${transY} )`;
d3.select(this).attr("transform", tstr)
.classed("active", false);
}

Appcelerator view hiding animation

I am trying to integrate animation in a module where, when the dismiss button is clicked, the entire pendingTasksBar view's height turn to 0dp but at a stretch of 300ms. This is what i have tried so far. Can someone please help me out here?
function hidePendingTasksBar(){
log.trace("[tasks] >> [hidePendingTasksBar]");
var animationObj = Ti.UI.createAnimation({
height : "0dp",
duration : 300
});
$.pendingTasksBar.animate(animationObj);
//.pendingTasksBar.height = "0dp";
}
Height property must be a Number, and you are using a String. I think that's the problem. Try using 0 instead of "0dp".
http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Animation-property-height
Setting height to 0 as number should work. And if it doesn't work, then you can safely use matrix transformation to decrease height or to increase it to same height again as below:
var matrix = Ti.UI.create2DMatrix();
matrix = matrix.scale(1, 0);
// to decrease height
$.pendingTasksBar.animate({
duration : 300,
transform : matrix
});
// to reset height
$.pendingTasksBar.animate({
duration : 300,
transform : Ti.UI.create2DMatrix() // use empty matrix & it will reset original matrix or UI.
});

Update D3 text width by adding new width

I have a D3 text added inside a rectangle , where the value of text field is updated programtically. Now I need to expand the width based on the text value length but making sure to keep the default width as min width.
I have tried getting the new value.length and updating the d3 text width like below.
var length = //length of the updated text value
var elm = d3.selectAll("[id=s1]");
elm.attr('width', function(d) { return length; });
This works fine but when i delete the text D3 text box also shrinks all the way. I need to keep a default width and then just increase if the value is longer than that. Any idea how to do this?
You can use a ternary operator to check for a minimum value:
elm.attr('width', function() {
return length < minimumValue ? minimumValue : length;
});
Where minimumValue is, of course, your minimum value.

Setting kendo grid height scrollable auto min-height max-height

I am aware of this beeing a frequently discussed issue.
Anyway I want to give it a shot:
I am using multiple kendo grids - so I am looking for a reusable and clean way how to set the grids styles without having side effects on each other.
So here's what I want to achieve:
Grid style 1:
- min-height: 150px max-heigt: 600px scrollable
Grid style 2:
- min-height: 150px max-heigt: 300px scrollable
Doesn't seem very extraordinary, does it?
I tryed setting html.attributes, setting scrollable() height and overwriting css.
But in the end I'll always find myself in having following problems, though:
Grid content div overflows the parent div
no scrollbars anymore
"fixing" by overwriting css classes what has undesired side effects
of course
Does anybody have a solution?
I have a possible solution which I have modified from a bit of code I use.
independent grid height resizing
So lets examine the magic bit for you:
function resizeGrid(grid, size, fixed, minHeight, minSizeHeight, maxHeight, maxSizHeight) {
if (size === null || size === undefined) {
size = 0.6;
}
if (minHeight === null || minHeight === undefined) {
minHeight = 600;
minSizeHeight = 150;
}
if (maxHeight === null || maxHeight === undefined) {
maxHeight = 800;
maxSizHeight = 600;
}
var windowHeight = $(window).height();
if (!fixed) {
windowHeight = windowHeight * size;
} else {
windowHeight = size;
}
if ($(window).height() < minHeight) {
windowHeight = minSizeHeight;
}
if ($(window).height() > maxHeight) {
windowHeight = maxSizHeight;
}
var gridContent = $("#" + grid + " div.k-grid-content");
var lockedContent = $("#" + grid + " div.k-grid-content-locked");
gridContent.height(windowHeight);
if (lockedContent !== null && lockedContent !== undefined) {
lockedContent.height(windowHeight);
}
}
So based on your requirements and my understanding you want to be able to change the scrollable area dynamically and independently of one another.
in this example we provide the following signature:
resizeGrid(grid, size, fixed, minHeight, minSizeHeight, maxHeight, maxSizeHeight)
Grid ==> the id of the grid we are working with
Size ==> this is the size either expressed as a pixel value or percentage (eg. 150 or 0.4 (40%))
fixed ==> this tells the function if the value passed is a fixed height or a percentage height for the initial height requirements
minHeight==> this should be the minimum screen size that the grid should resize itself
minSizeHeight ==> this is the size the grid should resize to if the minHeight condition is met.
maxHeight ==> this should be the maximum screen size that the grid should resize itself.
maxSizeHeight ==> this should be the maximum size of the grid should be be above the maxHeight of the window.
Note: the final 4 settings will use pixel defined values but the code could be adapted to work with percentages as well
so in the example I have provided I have declared:
resizeGrid("grid",600,true, 400,150, 800,600 );
resizeGrid("grid2",150,true, 300,300, 600,400 );
So the first grid #grid will set itself to a size of 600px initially and then resize itself if the window goes below 400px and over 800px. In both scenarios it will resize to 150px, 600px respectively.
then when we start resizing the window I have added this:
$(window).resize(function () {
console.log("resizing::" ,$(window).height() );
resizeGrid("grid",600,true, 400,150, 800,600 );
resizeGrid("grid2",150,true, 300,300, 600,400 );
});
This will then look for the window resize event to be fired off and then resize the grids accordingly.
I have added the console statement purely so you can see this event being fired off and what the window height is to check the code is being activated at the right point.
One thing you may notice are these lines here:
var gridContent = $("#" + grid + " div.k-grid-content");
var lockedContent = $("#" + grid + " div.k-grid-content-locked");
Due to the grid "wrapping" the locked and non-locked portions into different tags I am checking to see if there are any locked columns as otherwise you will have different scrolling/unexpected style on the various parts of the grid.
If you need anything more explaining/changing let me know and I will update my answer accordingly. Hopefully this is what you are after.
Edit: I have updated the example so you can see the grids side by side

d3 - Axis Label Transition

In Mike Bostock's cubism demo (http://bost.ocks.org/mike/cubism/intro/demo-stocks.html), there is a cursor which displays the values of all horizon charts on display. Furthermore, the cursor text shows the time axis point in time. As the cursor text obscures an axis label, the label fades.
I am working on a similar display with d3.js (but not cubism). I have all working except that fade portion. I have searched through the CSS in the developer's window, searched the source code (as best I could), but I don't understand what manner of magic is being used to accomplish this feat. I've even looked through SO "axis label transition" questions, but I have failed to connect the dots on xaxis label transitions.
How does that fade in/out when obscured by text happen?
UPDATE:
I think I located the event script area where this happens - its just a little over my head at the moment - can anyone help me decipher what this event listener is doing? Specifically, in the second g.selectAll in the else clause below - what data (d) is being used here? What is causing this event to fire?
This is the coolest part of the display (outside of the horizon charts), I would love to figure this out ...
context.on("focus.axis-" + id, function(i) {
if (tick) {
if (i == null) {
tick.style("display", "none");
g.selectAll("text").style("fill-opacity", null);
} else {
tick.style("display", null).attr("x", i).text(format(scale.invert(i)));
var dx = tick.node().getComputedTextLength() + 6;
g.selectAll("text").style("fill-opacity", function(d) { return Math.abs(scale(d) - i) < dx ? 0 : 1; });
}
}
});
I used this as reference to accomplish the same effect.
I'm not sure what the context variable is or how the id's are set or what the tick flag references but what I did was simply update the opacity of the ticks according to their proximity to the mouse. With this, the vertical tick fades as well as the label text.
svg.selectAll('.x.axis .tick').style('opacity', function (d) {
return Math.min(1, (Math.round(Math.abs(d3.mouse(svg.node())[0] - x(d))) - 10) / 15.0);
});
This way, the opacity is set to 0 if it's within 10 pixels, and fades from 1-0 between 10 and 25. Above 25, the opacity would be set to an increasingly large number, so I clamp it to 1.0 using the Math.min function.
My labels are slightly rotated, so I also added an offset not shown inside the formula above (a +3 after [0]) just to make it look a bit nicer. A year late to answer your only question, but hey it's a nice effect.
same answer as Kevin Branigan's post, but using the d3 scale to calculate the opacity value.
var tickFadeScale = d3.scale.linear().domain([10,15]).range([0,1]).clamp(true);
svg.selectAll('.x.axis .tick').style('opacity', function (d) {
return tickFadeScale(Math.abs(d3.mouse(svg.node())[0] - x(d)));
}

Resources