Connect elements with Bézier curve (line)…

CleanShot 2022-06-04 at 16.40.31

connectWithLine.hype.zip (22,9 KB)


Using Hype Action Event for the update on each frame… but that could also be done with an interval or any other timer. This was a request on a job the other day. I couldn't fulfill it out of a time constraint, but thought I would build this for future use and for the benefit of the community.

Have fun°

CleanShot 2022-06-04 at 17.23.00

10 Likes

Hi Max. That works wonderfully!! Now I'd like to do the following: the connecting line should be colored depending on the dragged element. The color is attached to the drag element as an HTML attribute. Is that possible?

connectElementsWithLine.hype.zip (145.6 KB)

1 Like

It be cool if the first example had a rubber band effect. Reminds me when I played an iOS game cut the rope?

1 Like

nice.

Use this connectWithLine function instead:

hypeDocument.connectWithLine = function(a, b) {
	var a_id = a.id;
	var b_id = b.id;
	var svg_id = a_id + "_" + b_id;
	var svg = document.getElementById(svg_id);
	
	if (!svg) {
		svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
		svg.setAttribute("id", svg_id);
		svg.setAttribute("width", "100%");
		svg.setAttribute("height", "100%");
		svg.setAttribute("style", "position: absolute;");
		
		var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
		path.setAttribute("id", svg_id + "_path");
		path.setAttribute("fill", "none");
		svg.appendChild(path);
		a.parentNode.closest('.HYPE_element').appendChild(svg);
	}
	
	var path = document.getElementById(svg_id + "_path");
	var hP = hypeDocument.getElementProperty;
	
	// Get element rectangles
	var a_rect = {
		left: hP(a, 'left'), top: hP(a, 'top'),
		width: hP(a, 'width'), height: hP(a, 'height'),
	};
	var b_rect = {
		left: hP(b, 'left'), top: hP(b, 'top'),
		width: hP(b, 'width'), height: hP(b, 'height'),
	};
	
	// Calculate connection points
	var a_x = a_rect.left + a_rect.width / 2;
	var a_y = a_rect.top + a_rect.height / 2;
	var b_x = b_rect.left + b_rect.width / 2;
	var b_y = b_rect.top + b_rect.height / 2;
	
	// Calculate curve control points
	var delta_x = Math.abs(a_x - b_x);
	var delta_y = Math.abs(a_y - b_y);
	var c_x = a_x + delta_x / 2 * (a_x < b_x ? 1 : -1);
	var c_y = b_y + delta_y / 2 * (a_y < b_y ? 1 : -1);
	
	// Create path
	var d = "M" + a_x + " " + a_y + " C " + c_x + " " + a_y + " " + c_x + " " + b_y + " " + b_x + " " + b_y;
	path.setAttribute("d", d);
	
	// Apply customization from data attributes (hierarchy: a -> b -> defaults)
	var getDataAttribute = function(attr, defaultValue) {
		return a.dataset[attr] || b.dataset[attr] || defaultValue;
	};
	
	// Line styling attributes
	path.setAttribute("stroke", getDataAttribute("colorLine", "red"));
	path.setAttribute("stroke-width", getDataAttribute("widthLine", "2"));
	path.setAttribute("stroke-dasharray", getDataAttribute("dashLine", ""));
	path.setAttribute("stroke-linecap", getDataAttribute("capLine", "round"));
	path.setAttribute("opacity", getDataAttribute("opacityLine", "1"));
}

This gives you the following options. You can put them either on a or b of your line pair.

Available Data Attributes:

data-color-line
Line color (default: "red") - Any valid CSS color value

data-width-line
Line width (default: "2") - Numeric value for stroke thickness

data-dash-line
Dash pattern (default: "" - solid line) - SVG dash array like "5,5" for dashed or "10,5,2,5" for complex patterns

data-cap-line
Line cap style (default: "round") - SVG line cap: "round", "square", or "butt"

data-opacity-line
Line opacity (default: "1") - Decimal value from 0 (transparent) to 1 (opaque)

3 Likes

Awesome! That's exactly what I was looking for. A thousand thanks, Max!

1 Like