Need to dynamically cut corners on rectangle using Javascript - javascript

I have a problem. I am creating the form where the user can enter coordinates x1,x2,y1,y2 for each corner to cut it top left, top right, bottom left, bottom right. Those coordinates are in millimeters and after the user enters data He should see the following image:
The racktangle itself I presented using div
<div id='detailPlot' style=' position: relative; width:300px;height:300px;background-color:white;border:1px solid black; ' ></div>
Can I cut those corners on that using Javascript and show result there?

I'd use SVG Path instead of the <div> element. You can draw lines between defined coordinates using it's d property:
<svg id="detailPlot" height="150px" width="150px">
<path d="M0 0 L100 0 L150 100 L150 150 L0 150 L0 0" stroke="black" stroke-width="1" fill="none" />
</svg>
Using javascript you'll be able to change it's d property at will:
var pathElement= document.querySelectorAll("path")[0];
pathElement.d = "M0 0 L300 0 L300 300 L0 300 L0 0"; // draw a rectangle

Related

Splitting the color of a curved text along a path in svg

I'm using SVG in HTML to draw a bended word along a path. Now that I managed to do draw the text, I need to split the word in 2 colors along the path that the word sits on. You can see the effect I'm trying to make in the image. Does anyone know how can I split the word in such a way? (I'm not sure if this matters, but the word is constantly bended, stretched and moved by the user, by modifying the "d" attribute of the path.)
var path = document.getElementById("Path");
var textPath = document.getElementById("TextPath");
document.onmousemove = function(e){
path.setAttribute("d", `M 100 100 q ${e.x-100} ${e.y-100} 230 0`);
textPath.setAttribute("textLength", path.getTotalLength() + "px")
}
svg {
width: 500px;
height: 500px;
}
<svg>
<path id="Path" d="M 100 100 q 50 -100 230 0" stroke="#000000" stroke-width="1" fill="none"></path>
<text id="Text" fill="#000000" font-size="64px">
<textPath startOffset="0%" id="TextPath" alignment-baseline="middle" href="#Path" startOffset="0%" startOffset="0%">Example</textPath>
</text>
</svg>
Here's a simpler version of what I have now. What I want to happen, is to color everything above the curve with one color and everything below with another.
One way of doing it: you use the text twice: once filled with color A and once filled with color B. Next you clip the second text with the path.
<svg viewBox="0 0 260 200">
<defs>
<path id="pth" d="M70,150 C10,40 240,40 180,150" stroke="red" fill="none" />
<text id="txt" font-size="45" text-anchor="middle" dominant-baseline="central">
<textPath font-size="35" startOffset="50%" href="#pth">
SSSSSSSSSSSS
</textPath>
</text>
<clipPath id="cp">
<use href="#pth" />
</clipPath>
</defs>
<use href="#txt" fill="blue" />
<use href="#txt" fill="orange" clip-path="url(#cp)" />
</svg>

Svg button path animation

I have this SVG button that I'm trying to animate on hover . I want the button to have a blob effect on the hover. I hope you guys can help me out. Here is the link to the SVG
https://codepen.io/haroldhall/pen/ZEJWJqo
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px" viewBox="0 0 169.5451 69.2823">
<defs>
<style>
.fbfb67fb-85bf-41e7-ba32-d1082da05d29 {
fill: #ff83b5;
}
</style>
</defs>
<g id="ee4ac112-3396-4e4b-9bd2-9cf074846425" data-name="Layer 2">
<g id="b0f8822e-1e1e-4dce-a2e6-9a8bebf20196" data-name="Background">
<path id="original" class="fbfb67fb-85bf-41e7-ba32-d1082da05d29" d="M76.9857,59.1319C52.7693,55.9614,1.16,89.3257.01,40.4447-.7354,8.7354,38.7113-11.033,76.1673,6.64c33.8056,15.9511,84.1836-17.2117,85.0374,23.6112C162.2335,79.4411,111.2431,65.3513,76.9857,59.1319Z" />
</g>
</g>
</svg>
CSS rule d: path (" M76 .....); not currently supported by the W3C SVG spec.
This is so far only an experimental technology of browsers based on the Blink engine.
Therefore, a solution based on rule d: path` will not be cross-browser, for example Firefox it does not work.
Consider a solution with SVG SMIL.
SMIL support
To morph the contours of the button, you need to create a final path in the vector editor in the form of a drop
The figures below show the process of getting the final path in the vector editor.
Grab the anchor point and drag it down until you get the desired shape.
Save the svg file and copy the final path to the morph animation command.
Below is the code for animating the morphing of the button outline into a drop shape:
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" width="50px" height="50px" viewBox="0 0 169.5451 69.2823">
<defs>
<style>
.fbfb67fb-85bf-41e7-ba32-d1082da05d29 {
fill: #ff83b5;
}
</style>
</defs>
<g id="ee4ac112-3396-4e4b-9bd2-9cf074846425" data-name="Layer 2">
<g id="b0f8822e-1e1e-4dce-a2e6-9a8bebf20196" data-name="Background">
<path id="original" class="fbfb67fb-85bf-41e7-ba32-d1082da05d29" d="M77 59C53 56 1 89 0 40-1 9 39-11 76 7c34 16 84-18 85 23 1 49-50 35-84 29Z" >
<animate
attributeName="d"
begin="original.mouseover"
dur="1s"
fill="freeze"
restart="WhenNotActive"
values="
M77 59C53 56 1 89 0 40-1 9 39-11 76 7c34 16 84-18 85 23 1 49-50 35-84 29Z;
M81 113C57 110 1 89 0 40-1 9 39-11 76 7c34 16 84-18 85 23 1 49-45 89-80 83z"
/>
</path>
</g>
</g>
</svg>
not sure what kind of blob effect you're looking to have, but you can do this either with JS or CSS. Both involve changing the path to the new desired positions. I am including an example that changes a bit on hover. If you need help creating a blob I recommend https://www.blobmaker.app/
svg #original {
transition: all 0.5s;
}
svg:hover #original {
d: path("M76.9857,59.1319C52.7693,55.9614,1.16,189.3257.01,40.4447-.7354,8.7354,38.7113-11.033,76.1673,6.64c33.8056,15.9511,84.1836-17.2117,85.0374,23.6112C162.2335,179.4411,11.2431,65.3513,76.9857,59.1319Z");
}
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px" viewBox="0 0 169.5451 69.2823"><defs><style>.fbfb67fb-85bf-41e7-ba32-d1082da05d29{fill:#ff83b5;}</style></defs><g id="ee4ac112-3396-4e4b-9bd2-9cf074846425" data-name="Layer 2"><g id="b0f8822e-1e1e-4dce-a2e6-9a8bebf20196" data-name="Background"><path id="original" class="fbfb67fb-85bf-41e7-ba32-d1082da05d29" d="M76.9857,59.1319C52.7693,55.9614,1.16,89.3257.01,40.4447-.7354,8.7354,38.7113-11.033,76.1673,6.64c33.8056,15.9511,84.1836-17.2117,85.0374,23.6112C162.2335,79.4411,111.2431,65.3513,76.9857,59.1319Z"/>
</g></g></svg>

Different sizes of SVG icons

I don't know why those two svg icons don't have exactly the same size when I'm checking it in the browser.
The first one is:
<svg viewBox="0 0 60 60">
<path
d='M10.3333333,16.7141667 L14.88,25.8333333 L51.6666667,25.8333333 L51.6666667,46.5 L10.3333333,46.5 L10.3333333,16.7141667 Z M56.8333333,10.3333333 L46.5,10.3333333 L51.6666667,20.6666667 L43.9166667,20.6666667 L38.75,10.3333333 L33.5833333,10.3333333 L38.75,20.6666667 L31,20.6666667 L25.8333333,10.3333333 L20.6666667,10.3333333 L25.8333333,20.6666667 L18.0833333,20.6666667 L12.9166667,10.3333333 L10.3333333,10.3333333 C7.49166667,10.3333333 5.1925,12.6583333 5.1925,15.5 L5.16666667,46.5 C5.16666667,49.3416667 7.49166667,51.6666667 10.3333333,51.6666667 L51.6666667,51.6666667 C54.5083333,51.6666667 56.8333333,49.3416667 56.8333333,46.5 L56.8333333,10.3333333 Z'
/>
</svg>
The second one:
<svg viewBox="0 0 60 60">
<path
d='M21,2 L3,2 C1.9,2 1,2.9 1,4 L1,16 C1,17.1 1.9,18 3,18 L10,18 L10,20 L8,20 L8,22 L16,22 L16,20 L14,20 L14,18 L21,18 C22.1,18 23,17.1 23,16 L23,4 C23,2.9 22.1,2 21,2 Z M21,16 L3,16 L3,4 L21,4 L21,16 Z'
/>
</svg>
The thing is that I need to have exactly the same viewBox (here 0 0 60 60)for both but when I'm setting it like this the second icon is much smaller then the first one. I'd like to have them looking the same (size) while having hte same viewBox. What am I missing here?
You can put the width and height atribute but still will not solve the issue
<svg viewBox="0 0 60 60" width="60" height="60">
<path d="M10.3333333,16.7141667 L14.88,25.8333333 L51.6666667,25.8333333 L51.6666667,46.5 L10.3333333,46.5 L10.3333333,16.7141667 Z M56.8333333,10.3333333 L46.5,10.3333333 L51.6666667,20.6666667 L43.9166667,20.6666667 L38.75,10.3333333 L33.5833333,10.3333333 L38.75,20.6666667 L31,20.6666667 L25.8333333,10.3333333 L20.6666667,10.3333333 L25.8333333,20.6666667 L18.0833333,20.6666667 L12.9166667,10.3333333 L10.3333333,10.3333333 C7.49166667,10.3333333 5.1925,12.6583333 5.1925,15.5 L5.16666667,46.5 C5.16666667,49.3416667 7.49166667,51.6666667 10.3333333,51.6666667 L51.6666667,51.6666667 C54.5083333,51.6666667 56.8333333,49.3416667 56.8333333,46.5 L56.8333333,10.3333333 Z"></path>
</svg>
and
<svg viewBox="0 0 60 60" width="60" height="60">
<path d="M21,2 L3,2 C1.9,2 1,2.9 1,4 L1,16 C1,17.1 1.9,18 3,18 L10,18 L10,20 L8,20 L8,22 L16,22 L16,20 L14,20 L14,18 L21,18 C22.1,18 23,17.1 23,16 L23,4 C23,2.9 22.1,2 21,2 Z M21,16 L3,16 L3,4 L21,4 L21,16 Z"></path>
</svg>
You can open the svg in ilustrator and fit the path to 60x60px
The second SVG has much more whitespace, and the paths only cover the top-left of the viewbox.
Added borders to show:
<svg viewBox="0 0 60 60" style="border:solid 1px red">
<path
d='M10.3333333,16.7141667 L14.88,25.8333333 L51.6666667,25.8333333 L51.6666667,46.5 L10.3333333,46.5 L10.3333333,16.7141667 Z M56.8333333,10.3333333 L46.5,10.3333333 L51.6666667,20.6666667 L43.9166667,20.6666667 L38.75,10.3333333 L33.5833333,10.3333333 L38.75,20.6666667 L31,20.6666667 L25.8333333,10.3333333 L20.6666667,10.3333333 L25.8333333,20.6666667 L18.0833333,20.6666667 L12.9166667,10.3333333 L10.3333333,10.3333333 C7.49166667,10.3333333 5.1925,12.6583333 5.1925,15.5 L5.16666667,46.5 C5.16666667,49.3416667 7.49166667,51.6666667 10.3333333,51.6666667 L51.6666667,51.6666667 C54.5083333,51.6666667 56.8333333,49.3416667 56.8333333,46.5 L56.8333333,10.3333333 Z'
/>
</svg>
<svg viewBox="0 0 60 60" style="border:solid 1px red">
<path
d='M21,2 L3,2 C1.9,2 1,2.9 1,4 L1,16 C1,17.1 1.9,18 3,18 L10,18 L10,20 L8,20 L8,22 L16,22 L16,20 L14,20 L14,18 L21,18 C22.1,18 23,17.1 23,16 L23,4 C23,2.9 22.1,2 21,2 Z M21,16 L3,16 L3,4 L21,4 L21,16 Z'
/>
</svg>
You can either:
Reduce the viewbox down to its ~ 25x25 viewbox and style the height/width using HTML/CSS instead
edit the SVG and have it fill a 60x60 viewbox

Using feMorphology svg filter trims corners in the output

I am using SVG filter feMorphology's dilate to implement shadow spread for a shape.
Am expecting below result.
<?xml version="1.0" encoding="UTF-8"?>
<svg width="188px" height="209px" viewBox="0 0 188 209" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Test</title>
<defs>
<polygon id="path-1" points="94 29 168 194 20 194"></polygon>
<filter x="-100%" y="-100%" width="1000%" height="1000%" filterUnits="userSpaceOnUse" id="filter">
<feMorphology radius="5" operator="dilate" in="SourceAlpha" result="morphOut"></feMorphology>
<feMerge>
<feMergeNode in="morphOut"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
</defs>
<g id="Triangle">
<path d="M 20 20 L 120 20 L 120 120 L 20 120 z " filter="url(#filter)" stroke-width="1" fill-rule="evenodd" fill="rgb(216,216,216)"/>
<path d="M 70 150 L 120 200 L 20 200 z" filter="url(#filter)" stroke-width="1" fill-rule="evenodd" fill="rgb(216,216,216)"/>
</g>
</svg>
But my code returns somewhat trimmed corners in some shapes. Help me
sort out this.
The filter is working as expected:
The dilation (or erosion) kernel is a rectangle with a width of 2*x-radius and a height of 2*y-radius. In dilation, the output pixel is the individual component-wise maximum of the corresponding R,G,B,A values in the input image's kernel rectangle. In erosion, the output pixel is the individual component-wise minimum of the corresponding R,G,B,A values in the input image's kernel rectangle.
Imagine a square of, in your case, 10px × 10px, moving along the path. For dilation, the outermost pixel the square sweeps over will define the new outer border of the grafic. (For erosion, it would be the outermost pixel inside the path the square does not sweep over.)

svg / snapsvg creating text that bends

Okay so i am relatively new to both svgand snap.svg.
However i am trying out the different features and how to create all sorts of different text elements.
Normal text is not a challenge however i started wondering how do i make text that actually bends?
Say for instance i want to create a text such as this:
As you can see the text bends.
My Ultimate goal is to use snap.svgto allow the user to bend the text however I'm not quite sure on how to do this.
Has anyone attempted to bend text and is able to point me in the right direction?
SVG is necessary to define a path with curved dimensions.
Here an example:
<svg height="70" width="300">
<defs>
<path id="myTextPath" d="M 30 55 q 100 -46 240 0" />
</defs>
<rect x="0" y="0" height="70" width="300" fill="#292425" />
<text x="10" y="100" style="font-size: 18px; stroke: #E6E6E6;">
<textPath xlink:href="#myTextPath">INVITATION TIL BRYLLUP</textPath>
</text>
</svg>
Update:
And this is a simple example where a user can bend the text, in real time.
Using VanillaJS (Javascript) and Snap.svg.
(function() {
var orientation = document.getElementById("orientation");
orientation.addEventListener("change", function() {
bendText(this.value);
});
function bendText(value) {
var snap = Snap("#myTextPath");
snap.attr("d", "M 30 55 q 100 " + value * -1 + " 240 0");
}
})();
input[type=range][orient=vertical] {
writing-mode: bt-lr;
/* IE */
-webkit-appearance: slider-vertical;
/* WebKit */
width: 8px;
height: 175px;
padding: 0 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg.js"></script>
<input id="orientation" type="range" orient="vertical" value="46" max="46" min="-46" />
<svg height="70" width="300">
<defs>
<path id="myTextPath" d="M 30 55 q 100 -46 240 0" />
</defs>
<rect x="0" y="0" height="70" width="300" fill="#292425" />
<text x="10" y="100" style="font-size: 18px; stroke: #E6E6E6;">
<textPath xlink:href="#myTextPath">INVITATION TIL BRYLLUP</textPath>
</text>
</svg>
Demo
You can just use a textpath attribute, which takes a path and positions the string along it.
var s = Snap(500,500);
var path = "M 100 200 C 200 100 300 0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100";
var text = s.text(50,50,'Hi there, Im a textpath that curves along a path string')
.attr({ 'textpath': path })
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg.js"></script>
docs

Categories

Resources