Snap SVG - Animating a Path in the opposite direction - svg

I am working on a path animation, but am stuck at how to accomplish it in reverse.
http://jsfiddle.net/t1yu3mcn/1/
Currently, the red path starts at full length, and over time becomes shorter and shorter from the right direction. I want to accomplish the same animation but where the path gets shorter starting from the left direction. (starts disappearing from the left rectangle, and ends disappearing at the right rectangle).
I have tried altering the following snippet inside .animate:
'stroke-dasharray': val + ' ' + (pathCoverLength - val)
But changing this around to different values never results in the correct effect.
Does anybody know an easy way of accomplishing this?

One way is to juggle the dashOffset point further...
jsfiddle
pathCover.attr({ strokeDasharray: pathCoverLength + ' ' + pathCoverLength })
Snap.animate(pathCoverLength*2, pathCoverLength, function(val) {
pathCover.attr({
strokeDashoffset: val });
}, 7000, mina.ease);

Related

How could I build a resizizing or collapsing Textbox in D3.JS for mitch-tree

Hallo I am currently trying to build a tree in D3.js.
For this I donwloadet the repository of the mitch-tree:
https://github.com/deltoss/d3-mitch-tree
I wantet to ask, if maybe somebody already has expirience with this issue?
So, I build a tree with processcharts.
But I have the problem, that the text hast to fit the boxes right nor, or it will get cut out.
It would be great to be able to fit the boxes to the content, so making them resizeable or, maybe make the boxes collapsable..
Maybe somebody hast a tipp for me, how to reach that goal.
I think I found the part of the code where the cutting/ resizing might be happaning for my textBox.
But I am really not sure..
If I got it right, the textbox resizes already what is inside with this function and cuts the words, that are to much for my box are out:
// D3Plus Textbox with resizing capability
var d3PlusBodyTextBox = new d3PlusTextBox()
.select(element) // Sets the D3Plus code to append to the specified DOM element.
.data(singledOutData)
.text((data, index, arr) => {
return self.getBodyDisplayText.call(self, data);
})
.textAnchor("middle")
.verticalAlign("middle")
.fontSize(13) // in pixels
.x(nodeBodyBoxPadding.left)
.y(recalculatedPaddingTop - nodeBodyBoxHeight / 2)
.width(nodeBodyBoxWidth - nodeBodyBoxPadding.left - nodeBodyBoxPadding.right)
.height(nodeBodyBoxHeight - recalculatedPaddingTop - nodeBodyBoxPadding.bottom)
.ellipsis((text, line) => {
// If text was cut-off, add tooltip
selection.append("title")
.text(self.getBodyDisplayText(data));
return ((text.replace(/\.|,$/g, "")) + "...");
})
.render();
});
Has anyone maybe a tipp for me how to change it in a good and functional way?
Thanks in advance :)

noUISlider - Any way to place labels within the connect segments

I have a noUiSlider with several handles to allow specifying several contiguous date periods (example = Feb to Apr, May to July, and Aug to Sept). Ideally I would like to have labels that appear centered on the connect divisions to describe what each period relates to (ex. "Current Period", "Next Period"). I was thinking I could do this by setting a centered background image on the noUi-connect divisions.
However, the noUi-connect divisions use transform (translate/scale) styling which results in my background images being scaled which I do not want.
I also thought maybe I could revise the javascript to generate an outer division around each nonUi-connect division, and I would apply the background onto the outer division instead - but I was unable to get the background from the outer division to appear.
Any other ways I could accomplish this? The only other thing I can think of it to have floating divisions defined outside of the noUiSlider object which I would need to reposition whenever I detect changes in the handle positions.
You can add an element outside of the connects and absolutely position it.
A quick version for a slider with two handles (showing the value for the first handle):
var origin = slider.querySelector('.noUi-connects');
var node = document.createElement('div');
node.style.textAlign = 'center';
node.style.position = 'absolute';
node.style.zIndex = '10';
node.style.fontSize = '10px';
origin.appendChild(node);
slider.noUiSlider.on('update', function(values, handle, unencoded, tap, positions) {
node.style.left = positions[0] + '%';
node.style.right = (100 - positions[1]) + '%';
node.innerText = values[0];
});
Just realized another approach is to set the innerHtml of the specific noUi-connect divisions to my label values. Simpler than playing with background images.
But the transform styling still affects the labels, so the end result is not better. Maybe I can load the innerHtml with an inner division that somehow ignores the transform settings but I haven't figure out how to do that yet. transform: none does not make any difference.

Android drawing path with unexpected results

On the left is the path I want to draw - a check mark.
On the right is what is being drawn - a check mark that's been filled in. Here is my code. It's behaving as if after drawing to the 3rd point its returning back to the first point.
private void final_line2 (PointF pointA,PointF pointB,Canvas canvas,double radiusmult){
Path path=new Path();
path.moveTo(648, 142); Top Right
path.lineTo(612,428); // Bottom
path.lineTo(598, 412); // Top left
path.close();
canvas.drawPath(path, paint);
Any help is much appreciated.

Why isn't my path2d position updating?

I created a new path2d following the instructions in the my first game article: http://docs.godotengine.org/en/3.0/getting_started/step_by_step/your_first_game.html
I wanted to move the "box" on screen so that I could see how the mobs spawn in, but when I ran the scene, it stayed off screen.
I created a new path2d, centered this one in the middle of the screen, and it works like I wanted it to, but now I moving this one in the editor doesn't update the position in game.
What's going on?
Thanks
func _on_mobtimer_timeout():
$mobtimer.wait_time = 0.1 + randf() / 2
$mobspawn/moblocation.set_offset(randi())
var mob = Mob.instance()
add_child(mob)
var direction = $mobspawn/moblocation.rotation + PI/2
mob.position = $mobspawn/moblocation.position
direction += rand_range(-PI/8, PI/8)
mob.rotation = direction
mob.set_linear_velocity(Vector2(rand_range(200, 200 + score * 30), 0).rotated(direction))
A Node2D's position property is relative to it's parent's position. The code from the Dodge The Creeps tutorial assumes that MobPath is located at 0, 0 and fails when that assumption is false.
In your case you are taking a MobSpawnLocation's position relative to MobPath and then setting it as the new Mob's global position.
Luckily Node2D's have another property that we can use in these circumstances global_position. It can be used like this:
mob.position = $mobspawn/moblocation.global_position
http://docs.godotengine.org/en/stable/classes/class_node2d.html#member-variables
This isn't a full solution, but I found a weird workaround. Instead of changing the position in the editor, if you use the nodes on the orange box (at the intersection of orange and blue), you can kind of alternate to move the box around.

How to right/end align text along an textPath inside an arc using d3.js?

Here's the fiddle: http://jsfiddle.net/DevChefOwen/CZ6Dp/
var text = g.append("text")
.style("font-size",30)
.style("fill","#000")
.attr("dy",0)
.append("textPath")
.attr("xlink:href","#yyy")
.style("text-anchor","left") // using "end", the entire text disappears
.text("some text");
I've tried a number of different things to no avail. The left align is the easy part. If you did a middle, though, you see only "text" instead of "some text", implying that "some" is just hidden because it went "out of span" for the given arc.
If, however, I added:
.attr("startOffset","39%")
(as in here: http://jsfiddle.net/DevChefOwen/2H99c/)
It would look right aligned, but outside of programmatically trying to get the width/height of the text element and look for sharp changes in width/height (which seems wrong and likely error-prone), I can't seem to find a way to right align the text.
I've also tried using an SVG path (essentially a curved arc line) and the same disappearing act happens with the text when "text-anchor" is set to "left".
Thanks ahead for your time!
The question is somewhat confusing matters. The issue isn't aligning text at the end of the path -- that's easy to do with "text-anchor"="end" and "startOffset"="100%".
However, using those settings with the path created by the d3 arc function, you end up with the text cornering around the end of the inside curve and the left straight edge, to the end of the path as defined by the arc function:
http://jsfiddle.net/CZ6Dp/8/
The real issue is that the path that you want the text to be aligned along (the outside arc of the shape) is only one segment of the path that defines the shape.
(By the way, "left" and "right" are not valid values for the "text-anchor" property, and will just be ignored).
The answer by #defghi1977 gives one way to approach the problem, by figuring out the length of the path segment that you do want to use and adjusting the start offset accordingly.
Another way to approach the problem is to create a separate path (not drawn on screen) that represents only the part of the path that you want to be used for positioning text.
There are a number of possible ways to create a path that only represents the outside arc (some example code here). #defghi1977's approach of grabbing it from the existing path with regular expressions is probably the most efficent for your situation. But instead of just creating a temporary element to calculate a length, I actually have to add the new path to the DOM so it can be used as the reference path for the <textPath> element. (Which I suppose is the downside to this approach -- twice as many DOM elements!)
var path = g.append("svg:path")
.attr("d", arct)
.style("fill","#ccc")
.attr("transform", "translate("+cfg.w/2+","+cfg.h/2+")")
.each(function(d,i) {
var justArc = /(^.+?)L/;
//grab everything up to the first Line statement
var thisSelected = d3.select(this);
var arcD = justArc.exec( thisSelected.attr("d") )[1];
defs.append("path")
.attr("id", "yyy") //normally the id would be based on the data or index
.attr("d", arcD)
.attr("transform", thisSelected.attr("transform") );
//if you can avoid using transforms directly on the path element,
//you'll save yourself having to repeat them for the text paths...
});
var text = g.append("text")
.style("font-size",30)
.style("fill","#000")
.attr("dy",0)
.append("textPath")
.attr("xlink:href","#yyy")
.style("text-anchor","end")
.attr("startOffset","100%")
.text("some text");
http://jsfiddle.net/CZ6Dp/9/
Again, factoring in the extra DOM load #defghi1977's method is probably slightly preferrable, although this version has the benefit of not being dependent on browser support for getTotalLength. But as far as I know that method is fairly well implemented.
So just consider this an alternate approach for completeness' sake.
This path is constructed by 4(or 5) path segments.
So, this probrem will be solved to get first arc path length.
But I don't know how to get sub path length by using d3.js, thus I use svgdom directly.
I tried to fix your code. If this code is not what you hope, I'm sorry.
path-anchor attribute to end.
define function to get startOffset value.
var path = g.append("svg:path")
.attr("id","yyy")
.attr("d", arct)
.style("fill","#ccc")
.attr("transform", "translate("+cfg.w/2+","+cfg.h/2+")");
var text = g.append("text")
.style("font-size",30)
.style("fill","#000")
.attr("dy",0)
.append("textPath")
.attr("xlink:href","#yyy")
//.style("text-anchor","left") // using "end", the entire text disappears
.attr("text-anchor", "end")
.text("some text")
.attr("startOffset",function(){
var d = document.getElementById("yyy").getAttribute("d");
var tmp = document.createElementNS("http://www.w3.org/2000/svg" ,"path");
//get the arc segment of path
var arc = d.match(/(^.+?)L/)[1];
tmp.setAttribute("d", arc);
//return offset position
return tmp.getTotalLength();
});
I think the confusion comes from the meaning of text-anchor - it's not "relative to where on the parent will I justify" but rather "what part of me should I align to the start".
You're right to try to use startOffset to move the origin. Since the outer radius of your path is longer than the inner radius, the correct start offset is a little more than half of the path (around 53%).
Just a little more twiddling with your settings and you should have it. Here's a fiddle with my interpretation of what you're looking for.

Resources