This app creates circular and elliptical borders for text on a web page, made up of images. In this example the images are svg but any hrml acceptable image could be used:
The html file creates 5 divisions and corresponding svg elements.
This is that code:
<!DOCTYPE html>
<html>
<style>
body{}
#frame{}
svg{position: absolute; width: 0; height: 0; top: 0; left: 0}
</style>
<body>
<div id=”frame” style=”position: absolute; left: 0; top: 0; width: 100%; height: 100%”>
<div id= “d1” style = “position: absolute; left: 200px; top: 150px; font: italic normal 800 24px Georgia” contenteditable = “true” onclick=’getId(this.id);’ ondblclick=’drawCircle();’ >d1</div>
<div id= “d2” style = “position: absolute; left: 200px; top: 250px; font: italic normal 800 24px Georgia” contenteditable = “true” onclick=’getId(this.id);’ ondblclick=’drawCircle();’ >d2</div>
<div id= “d3” style = “position: absolute; left: 200px; top: 350px; font: italic normal 800 24px Georgia” contenteditable = “true” onclick=’getId(this.id);’ ondblclick=’drawCircle();’ >d3</div>
<div id= “d4” style = “position: absolute; left: 200px; top: 450px; font: italic normal 800 24px Georgia” contenteditable = “true” onclick=’getId(this.id);’ ondblclick=’drawCircle();’ >d4</div>
<div id= “d5” style = “position: absolute; left: 200px; top: 550px; font: italic normal 800 24px Georgia” contenteditable = “true” onclick=’getId(this.id);’ ondblclick=’drawCircle();’ >d5</div>
<svg id=”svg1″ ></svg>
<svg id=”svg2″></svg>
<svg id=”svg3″></svg>
<svg id=”svg4″></svg>
<svg id=”svg5″></svg>
</div>
http://imgFrame.js
</body></html>
Everything else is done in a js file:
var rad = 0; var ang; var anginc; var str; var sclx = 1; scly = 1; var mov = false; var nm; var cnt; var oldURL = “tmp.html”; var cnt2 = 0;
function drawCircle() {
document.getElementById(nm).style.zIndex -= 1;
nm = “svg” + cnt;
rad = 300;
sclx = 1;
scly = 1;
document.getElementById(“svg” + cnt).style.width=”100%”;
document.getElementById(“svg” + cnt).style.height=”100%”;
ang = (-10 * (Math.PI / 180));
anginc = 10 * (Math.PI / 180);
for (var i = 0; i <= 37; i ++) {
ang += anginc;
var xval = rad + rad * Math.cos(ang) ;
var yval = rad + rad * Math.sin(ang);
document.getElementById(“svg” + cnt).innerHTML += ‘<image x=”‘ + xval + ‘” y=”‘ + yval + ‘” width=”56″ height=”56″ href=”8Petal.svg” />’
}
document.getElementById(“svg” + cnt).innerHTML = ‘<g id=”gframe’ + cnt + ‘” >’ + document.getElementById(“svg” + cnt).innerHTML + ‘</g>’;
str = rad + “px ” + rad + “px”;
document.getElementById(“gframe” + cnt).style.transformOrigin = str;
document.getElementById(“svg” + cnt).style.width = (2.2 * rad) + “px”;
document.getElementById(“svg” + cnt).style.height = (2.2* rad) + “px”;
document.getElementById(“svg” + cnt).style.left = “10px”;
document.getElementById(“svg” + cnt).style.top = “10px”;
}
document.onmousemove = mv; document.onkeydown = setMove;
function setScale(par) {
if (par == “+”) scly += .02;
if (par == “-“) scly -= .02;
if (par == “r”) sclx += .02;
if (par == “l”) sclx -= .02;
document.getElementById(“gframe” + cnt).style.transform = “scaleX(” + sclx + “) scaleY(” + scly + “)” ;
}
function setMove(e) {
if(e.keyCode == 18) mov = true
if(e.keyCode == 17) mov = false;
if(e.keyCode == 38) setScale(“+”);
if(e.keyCode == 40) setScale(“-“);
if(e.keyCode == 37) setScale(“l”);
if(e.keyCode == 39) setScale(“r”);
if(e.keyCode == 9) sve();
if(e.keyCode == 27) trim();
}
function mv(e) {
if (mov) {
if (nm.indexOf(“d”) != -1) rad = 0;
posX = e.pageX ;
posY = e.pageY;
document.getElementById(nm).style.left= (posX – rad) + “px”;
document.getElementById(nm).style.top= (posY – rad) + “px”;
}
}
function getId(par) {
if (cnt2 == 2) cnt2 = 0;
cnt2 ++;
nm = par;
cnt = par.substr(1);
document.getElementById(nm).style.zIndex += 1;
if (cnt2 == 2) selectElementContents(document.getElementById(nm));
}
function trim() {
document.getElementById(“d” + cnt).remove();
document.getElementById(“svg” + cnt).remove();
var fr = document.getElementById(“frame”);
fr.innerHTML = fr.innerHTML.replace(‘<div id= “d’ + cnt + ‘” style = “position: absolute; left: 200px; top: 250px; font: italic normal 800 24px Georgia” contenteditable = “true” onclick=\’getId(this.id);\’ ondblclick=\’drawCircle();\’ >d’ + cnt + ‘</div>’,”);
fr.innerHTML = fr.innerHTML.replace(‘<svg id=”svg’ + cnt + ‘” ></svg>’,”);
}
function sve() {
var textToSave = ‘<!DOCTYPE HTML> <html> <head> <title></title> <style> svg{position: absolute; width: 0; height: 0; top: 0; left: 0} </style> </head> <body> ‘ + document.getElementById(“frame”).innerHTML + ‘ </body></html>’;
alert(textToSave);
var textToSaveAsBlob = new Blob([textToSave], {type:”text/plain”});
var textToSaveAsURL = window.URL.createObjectURL(textToSaveAsBlob);
fileNameToSaveAs = prompt(“FileName to save as”,oldURL);
oldURL = fileNameToSaveAs;
var downloadLink = document.createElement(“a”);
downloadLink.download = fileNameToSaveAs;
downloadLink.innerHTML = “Download File”;
downloadLink.href = textToSaveAsURL;
downloadLink.onclick = destroyClickedElement;
downloadLink.style.display = “none”;
document.body.appendChild(downloadLink);
downloadLink.click();
}
function destroyClickedElement(event) {
document.body.removeChild(event.target);
}
function selectElementContents(el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
Clicking a division twice selects its text:
function getId(par) {
if (cnt2 == 2) cnt2 = 0;
cnt2 ++;
nm = par;
cnt = par.substr(1);
document.getElementById(nm).style.zIndex += 1;
if (cnt2 == 2) selectElementContents(document.getElementById(nm));
}
function selectElementContents(el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
Hitting the backspace deletes any text for divisions that will not be used and then hitting esc then removes the division and any mention in the source code:
function setMove(e) {
if(e.keyCode == 18) mov = true
if(e.keyCode == 17) mov = false;
if(e.keyCode == 38) setScale(“+”);
if(e.keyCode == 40) setScale(“-“);
if(e.keyCode == 37) setScale(“l”);
if(e.keyCode == 39) setScale(“r”);
if(e.keyCode == 9) sve();
if(e.keyCode == 27) trim();
}
function trim() {
document.getElementById(“d” + cnt).remove();
document.getElementById(“svg” + cnt).remove();
var fr = document.getElementById(“frame”);
fr.innerHTML = fr.innerHTML.replace(‘<div id= “d’ + cnt + ‘” style = “position: absolute; left: 200px; top: 250px; font: italic normal 800 24px Georgia” contenteditable = “true” onclick=\’getId(this.id);\’ ondblclick=\’drawCircle();\’ >d’ + cnt + ‘</div>’,”);
fr.innerHTML = fr.innerHTML.replace(‘<svg id=”svg’ + cnt + ‘” ></svg>’,”);
}
Typing in a selected division inserts any text you want.
Double clicking the selected division created a circular border:
<div id=”frame” style=”position: absolute; left: 0; top: 0; width: 100%; height: 100%”>
<div id= “d1” style = “position: absolute; left: 200px; top: 150px; font: italic normal 800 24px Georgia” contenteditable = “true” onclick=’getId(this.id);’ ondblclick=’drawCircle();’ >d1</div>
function drawCircle() {
document.getElementById(nm).style.zIndex -= 1;
nm = “svg” + cnt;
rad = 300;
sclx = 1;
scly = 1;
document.getElementById(“svg” + cnt).style.width=”100%”;
document.getElementById(“svg” + cnt).style.height=”100%”;
ang = (-10 * (Math.PI / 180));
anginc = 10 * (Math.PI / 180);
for (var i = 0; i <= 37; i ++) {
ang += anginc;
var xval = rad + rad * Math.cos(ang) ;
var yval = rad + rad * Math.sin(ang);
document.getElementById(“svg” + cnt).innerHTML += ‘<image x=”‘ + xval + ‘” y=”‘ + yval + ‘” width=”56″ height=”56″ href=”8Petal.svg” />’
}
document.getElementById(“svg” + cnt).innerHTML = ‘<g id=”gframe’ + cnt + ‘” >’ + document.getElementById(“svg” + cnt).innerHTML + ‘</g>’;
str = rad + “px ” + rad + “px”;
document.getElementById(“gframe” + cnt).style.transformOrigin = str;
document.getElementById(“svg” + cnt).style.width = (2.2 * rad) + “px”;
document.getElementById(“svg” + cnt).style.height = (2.2* rad) + “px”;
document.getElementById(“svg” + cnt).style.left = “10px”;
document.getElementById(“svg” + cnt).style.top = “10px”;
}
Either a division or its border can be moved:
document.onmousemove = mv;
The division should be moved while it is selected. Creating a border automatically selects it.
function mv(e) {
if (mov) {
if (nm.indexOf(“d”) != -1) rad = 0;
posX = e.pageX ;
posY = e.pageY;
document.getElementById(nm).style.left= (posX – rad) + “px”;
document.getElementById(nm).style.top= (posY – rad) + “px”;
}
}
The alt key allows the response to the mousemove and the control blocks it.
The border should be placed around the division and the arrow keys used to adjust it either horizontally or vertically, using the scale function of a <g> element:
function setScale(par) {
if (par == “+”) scly += .02;
if (par == “-“) scly -= .02;
if (par == “r”) sclx += .02;
if (par == “l”) sclx -= .02;
document.getElementById(“gframe” + cnt).style.transform = “scaleX(” + sclx + “) scaleY(” + scly + “)” ;
}