Using a Path for an SVG ClipPath


I had previously posted creating an image mask to prepare a tiled object.
Something similar can be done with svg, without creating the masking image, which I will post in the future.
This post describes the start of the procedure, with the creation a path as a clipPath.

This is the original image:

and this is the image clipped by a path:

Here is the code:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head profile=”http://gmpg.org/xfn/11″&gt;
<title>svg test</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal normal 15px Arial;}
a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { }
table{position: absolute; left: 20px; top: 5px}
input{width: 70px; text-align: center}
#svg1{position: absolute; width: 100%; height: 100%; top: 50px;}
#svg2{position: absolute; width: 100%; height: 100%; top: 50px; filter:contrast(100%) saturate(100%)}
#img1{}
</style>
</head>
<body>
<svg id=”svg2″ xmlns=”http://www.w3.org/2000/svg&#8221; version=”1.1″>
<defs>
<clipPath id=”pathMask” >
<path
d=”M 12.42,308.00
C 12.42,308.00 16.72,293.00 16.72,293.00
16.72,293.00 20.27,269.00 20.27,269.00
20.27,269.00 28.28,212.00 28.28,212.00
28.28,212.00 37.00,168.00 37.00,168.00
37.00,168.00 46.92,106.00 46.92,106.00
48.23,101.11 50.57,96.62 52.58,92.00
52.58,92.00 61.37,72.00 61.37,72.00
61.37,72.00 78.51,46.00 78.51,46.00
86.36,35.89 104.79,15.74 116.00,10.29
116.00,10.29 131.00,6.12 131.00,6.12
131.00,6.12 151.00,1.21 151.00,1.21
151.00,1.21 165.00,2.85 165.00,2.85
180.87,4.75 187.64,6.34 203.00,10.71
210.38,12.81 232.50,21.44 237.91,25.64
241.40,28.34 250.96,42.63 253.55,47.00
253.55,47.00 259.26,59.00 259.26,59.00
265.54,71.98 273.98,92.17 277.52,106.00
277.52,106.00 282.00,128.00 282.00,128.00
282.00,128.00 286.82,162.00 286.82,162.00
286.82,162.00 280.30,203.00 280.30,203.00
279.08,207.46 274.56,213.88 271.95,218.00
271.95,218.00 254.69,246.00 254.69,246.00
251.97,251.25 251.71,257.25 250.75,263.00
248.59,275.96 247.85,275.66 248.92,289.00
249.24,293.05 249.49,297.08 250.71,301.00
252.52,306.83 260.57,313.57 265.00,318.00
265.00,318.00 279.00,331.72 279.00,331.72
279.00,331.72 302.00,352.00 302.00,352.00
302.00,352.00 0.00,352.00 0.00,352.00
0.00,352.00 12.42,308.00 12.42,308.00 Z” />
</clipPath>
</defs>
<image id=”img2″x=”0″ y=”0″ xlink:href=”SAG.png” style=”clip-path: url(#pathMask)” />
</svg>
</body></html>


A SVG element is created with a clipPath placed withing a tag.
<svg id=”svg2″ xmlns=”http://www.w3.org/2000/svg&#8221; version=”1.1″>
<defs>
<clipPath id=”pathMask” >
<path

This is then used to clip an image placed in the SVG:
<image id=”img2″x=”0″ y=”0″ xlink:href=”SAG.png” style=”clip-path: url(#pathMask)” />

The path was obtained by selecting the object from the image using GIMP, converting the image to a path and exporting the path.

In the future I will describe a HTML app I wrote that can create a path from an image without an external graphics application.

HTML – Using a Tiled Custom Mask to Create Mosaic Type Effects to Object


This app tiles an image in a custom shape and then applies that to the same image, giving a sort of mosaic appearance.

It can be customized by adjusting the opacity and size of the tiles and the contrast and saturation of the image to compensate for the superimposed tiles.

Here is how it looks on loading:

and with an opacity of .3, tile size of 8 pixels and increases of the image contrast and saturation.

I used the same image for the tiles, but that is not necessary.

Here is the code:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head profile=”http://gmpg.org/xfn/11″&gt;
<title>tile</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal normal 15px Arial; background; black}
a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { }
img, #tile{position: absolute; left: 20px; top: 40px}
#tile{background-image: url(“SAG.png”); background-size: 12px; background-repeat: repeat; opacity:0.25}
table{position: absolute; left: 20px; top: 5px}
input{width: 70px; text-align: center}
#c1{width: 15px}
</style>
</head>
<body>
<table><tr>
<td><input type=”button” id=”b1″ name=”b1″ value=”draw” onclick=’drw();’ /></td><td><input type=”text” id=”t1″ name=”t1″ value=”” placeholder= “opacity” /></td><td><input type=”text” id=”t2″ name=”t2″ value=”” placeholder= “tile size” /></td>
<td><input type=”text” id=”t3″ name=”t3″ value=”” placeholder= “contrast” /></td><td><input type=”text” id=”t4″ name=”t4″ value=”” placeholder= “saturation” /></td><td><input type=”checkbox” id=”c1″ name=”c1″ value=” ” />inverse</td>
<tr></table>
<img id=”im1″ src= “SAG.png” />

<img id=”mask” src= “SAGMask.gif” />

var wd; var ht; var cont = “100”; var sat = “100”;

function drw() {
wd = im1.clientWidth;
ht = im1.clientHeight;
document.getElementById(“tile”).style.width = wd + “px”;
document.getElementById(“tile”).style.height = ht + “px”;
if (document.getElementById(“c1”).checked) {
document.getElementById(“tile”).style.backgroundImage = ‘url(“SAGMask.gif”)’;
} else {
document.getElementById(“tile”).style.backgroundImage = ‘url(“SAG.png”)’;
}
document.getElementById(“tile”).style.opacity = document.getElementById(“t1”).value;
document.getElementById(“tile”).style.backgroundSize = document.getElementById(“t2”).value + “px”;
if (document.getElementById(“t3”).value != “”) cont = document.getElementById(“t3”).value;
if (document.getElementById(“t4”).value != “”) sat = document.getElementById(“t4”).value;
document.getElementById(“im1”).style.filter = “contrast(” + cont + “%) saturate(” + sat + “%)”;
}

</body></html>


The app calls for three layers, the image on the bottom, a layer with the tiled images in the middle and an image mask on the top.

The image mask calls for some graphics work.

The image with the selected objects is opened in a graphics application, the object selected and filled with a solid color different from the ultimate page background color. The selection is inverted and filled with the page background color.
It is then saved as a gif image with the object color as the transparent one.
It will now act as a clip mask giving everything beneath the shape of the selected object.

After setting parameters, clicking the button calls the function drw():

The tiled layer is set the same size as the underlying image:
wd = im1.clientWidth;
ht = im1.clientHeight;
document.getElementById(“tile”).style.width = wd + “px”;
document.getElementById(“tile”).style.height = ht + “px”;

The image mask, being derived from the image is already the same size.

There is a checkbox that when checked substitutes the image mask for the image in the tiling:
if (document.getElementById(“c1”).checked) {
document.getElementById(“tile”).style.backgroundImage = ‘url(“SAGMask.gif”)’;
} else {
document.getElementById(“tile”).style.backgroundImage = ‘url(“SAG.png”)’;
}

Here is how that looks:

Finally the remaining parameters are set:
document.getElementById(“tile”).style.opacity = document.getElementById(“t1”).value;
document.getElementById(“tile”).style.backgroundSize = document.getElementById(“t2”).value + “px”;
if (document.getElementById(“t3”).value != “”) cont = document.getElementById(“t3”).value;
if (document.getElementById(“t4”).value != “”) sat = document.getElementById(“t4”).value;
document.getElementById(“im1”).style.filter = “contrast(” + cont + “%) saturate(” + sat + “%)”;

With five variables that can be set, this app affords a lot of tinkering.

Variables can be set individually or multiply. Clicking the button will give an instant update.

To try click here

HTML5 Filter


I previously posted a filter to be applied to images. This post extends it to the use of the HTML5 filter, which can apply editing directly to the image.

This is the default image. It has a black filter with 50% opacity:

Here it is with the opacity removed and contrast increased:

and with saturation decreased:

and made sepia with a slight yellow external filter applied:

Here are the effects that can be applied interactively in any combination:

Here is the code:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head profile=”http://gmpg.org/xfn/11″&gt;
<title>Color</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal normal 15px Arial;}
a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { }
#t1 {position: absolute; top: 0; left: 20px; width: 1000px; height: 20px; font:normal normal 600 18px Arial; text-align: center; cursor: crosshair; border:1px solid black}
</style>
</head>
<body onload=’init();’>

a

<select id=”s1″ name=”s1″ style = “position: absolute; left: 20px; top: 30px”>
<option >Choose</option>
<option >opacity</option>
<option >red</option>
<option >green</option>
<option >blue</option>
<option >contrast</option>
<option >brightness</option>
<option >saturation</option>
<option >desaturate</option>
<option >sepia</option>
</select>
<img id = “img1” src= “images/PJRose.jpg” style=”position: absolute; top: 60px; left: 20px” />

var chang = false; var a = .5; var re = 0; var gr = 0; var bl = 0; var cont = 100; var brt = 100; var sat = 100; var desat = 0; var sep = 0;
function init() {
var wd = img1.clientWidth;
var ht = img1.clientHeight;
document.getElementById(“fltr”).style.width = wd + “px”;
document.getElementById(“fltr”).style.height = ht + “px”;
}

document.onkeyup = chng;

function chng(e) {
if (e.keyCode == 16 ) {
chang = true;
} else {
chang = false;
}
}

var posX;var posY;
var IE = document.all?true:false;
if (!IE) document.captureEvents(Event.MOUSEMOVE)
document.onmousemove = getMouseXY;

function getMouseXY(e) {
if (IE) {
posX = event.clientX + document.body.scrollLeft;
posY = event.clientY + document.body.scrollTop;
}
else {
posX = e.pageX -20;
posY = e.pageY;
}
if (chang) {
if (posY > 0 && posY

</body></html>


The key is the following:

if (chang) {
if (posY > 0 && posY < 20) {
if (document.getElementById(“s1”).value == “opacity”) a = posX / 1000;
if (document.getElementById(“s1”).value == “red”) re = posX / 4;
if (document.getElementById(“s1”).value == “green”) gr = posX / 4;
if (document.getElementById(“s1”).value == “blue”) bl = posX / 4;
if (document.getElementById(“s1”).value == “contrast”) cont = posX / 4 ;
if (document.getElementById(“s1”).value == “brightness”) brt = posX / 4 ;
if (document.getElementById(“s1”).value == “saturation”) sat = posX / 4;
if (document.getElementById(“s1”).value == “desaturate”) desat = 100;
if (document.getElementById(“s1”).value == “sepia”) sep = 100;
}

document.getElementById(“fltr”).style.backgroundColor = “rgba(” + re + “,” + gr + “,” + bl + “,” + a + “)”;
document.getElementById(“img1”).style.filter = “contrast(” + cont + “%) brightness(” + brt + “%) saturate(” + sat + “%) grayscale(” + desat + “%) sepia(” + sep + “%)”;

If the pointer is within the box the various variables are determined by its x value.
The value of the select determines the variable that will be edited.
For everything but grayscale and sepia, the a in the box is a mid point. Having the pointer on the a means no change, anything above is an increase and below is a decrease.
Although grayscale and sepia can also be varied, I made them all or nothing.
Varying amounts of desaturation can be controlled by a saturation decrease.

HTML5 Figure


The HTML5 figure tag places a container that allows the insertion of an image and a caption.

The caption is placed in a figcaption tag.

This app shows the creation of a figure as well as its conversion to fullscreen.

Here is a figure in a normal window:

and fullscreen:

The border disappears when going fullscreen, which is effected by clicking the image.

Here is the code:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml”&gt;
<head profile=”http://gmpg.org/xfn/11″&gt;
<title>test</title>
<style>
body {margin-left:0;margin-right:0;font:normal normal 600 18px Arial;}
a{ text-decoration: }:link { color: rgb(0, 0, 255) }:visited {color :rgb(100, 0,100) }:hover { }:active { }
figure{position: absolute; text-align: center; flow: right; background: white; margin: 10px; padding: 20px 0 0 0; border: 1px solid black; }
img.scaled{height: 90%}
</style>
</head>
<body onload = ‘init2();’>
<figure id=”f1″>
<img id = “img1″ class = scaled src= ” ” onclick=’fs();’ />
<center><figcaption id=”fc”> This is a test of the figure with some added text to make it wrap onto a second line</figcaption></center>
</figure>

var wd; var ht;
function fs() {
document.getElementById(“f1”).requestFullscreen();
}

function init2() {
wd = img1.clientWidth;
ht = img1.clientHeight;
document.getElementById(“f1”).style.width = wd + “px”;
document.getElementById(“fc”).style.width = .9*wd + “px”;
document.getElementById(“f1”).style.height = ht + “px”;
document.getElementById(“f1”).style.left = “50%”;
document.getElementById(“f1”).style.marginLeft = -.45*wd + “px”;
}

</body></html>


The figure (id: f1) was set with no size, but with margins and padding:
figure{position: absolute; text-align: center; flow: right; background: white; margin: 10px; padding: 20px 0 0 0; border: 1px solid black; }

The size is set by init2(), equal to the client size of the image, and was called on loading:
wd = img1.clientWidth;
ht = img1.clientHeight;
document.getElementById(“f1”).style.width = wd + “px”;
document.getElementById(“fc”).style.width = .9*wd + “px”;
document.getElementById(“f1”).style.height = ht + “px”;
document.getElementById(“f1”).style.left = “50%”;
document.getElementById(“f1”).style.marginLeft = -.45*wd + “px”;
}

The caption width (id: fc) was also set relative to the image.

Fullscreen is called by clicking the image:
<img id = “img1″ class = scaled src= ” ” onclick=’fs();’ />

function fs() {
document.getElementById(“f1”).requestFullscreen();
}

The image is set as a scalable class, so that it keeps its proportion on going fullscale:
img.scaled{height: 90%}

So, the image scales relative to the figure and the figcaption scales relative to the image.