How to scale text using Raphael.js - javascript

I came to know about Raphael.js recently and I was trying to do some hands on.
I would like to scale a text but it is not working.
After searching a lot in Google I have not find any idea.
Code is:
var paper = Raphael("paper1", 1000,1000);
var txt = paper.text(20,50,"Hello World").attr({
"font-family":"Arial","font-size":"30px", "font-weight": "normal",
fill: "#000000", stroke:"black", "stroke-width": "0px",
"text-anchor" : "start" , "font-style": "normal"});
flip is working by txt.scale(-1,1)
but txt.scale(2,1) is not scaling the text.
Is there a way to scale a text?
Note: Font size of the text needs to remain same i.e 30px in my case.

Is there a way to scale a text?
DEMO
I checked and it works like a charm
var r = Raphael('test');
var t = r.text(200, 100, "I am a text").attr({fill:'red', 'font-size':30});
$('#zoomin').click(function() {
t.scale(2);
});
$('#zoomout').click(function() {
t.scale(.5);
});

If we scale the text only then font size shall be changed.
We need to convert the text into an image and the we need to scale it.
To do that I have used a hidden canvas.
Following code works for me.
<canvas id='textCanvas' style="display:none"></canvas>
<script>
var paper = Raphael("paper1", 1000,1000);
var img = paper.image(getTxtImg("Hello World","italic","bold","15px","arial",
"#000000",130,35),20,28,300,80)
img.scale(2,1) //Double in width
img.scale(.5,1) //Half in width
function getTxtImg(txt,style,weight,fontsize,fontfamily,color,w,h)
{
var tCtx = document.getElementById('textCanvas').getContext('2d');
tCtx.canvas.width = w;
tCtx.canvas.height = h ;
var fontstr = "" + style + " " + weight + " " + fontsize + " " + fontfamily + " ";
tCtx.font = fontstr
tCtx.fillStyle = color
tCtx.fillText(txt, 0, h);
return tCtx.canvas.toDataURL();
}
</script>

Related

Snap.svg transform not working - possible issue with element selection?

function base_axes() {
var s = Snap("#base_axes");
var dim = 0.1*window.innerWidth;
var x_line = s.line(0, dim, 0, dim);
x_line.attr("stroke", "#5e0734");
x_line.attr("stroke-width", "5px");
x_line.animate({
x2: window.innerWidth
}, 1000, mina.easein);
var y_line = s.line(dim, 0, dim, 0);
y_line.attr("stroke", "#5e0734");
y_line.attr("stroke-width", "5px");
y_line.animate({
y2: window.innerHeight
}, 1000, mina.easein);
Snap.load('https://upload.wikimedia.org/wikipedia/commons/3/35/Tux.svg', function(data) {
var logo = s.append(data);
var bbox = logo.getBBox();
var scale_factor = dim/bbox.height;
var transform_string = "s" + scale_factor + "," + scale_factor;
logo.transform(transform_string);
});
}
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/snap.svg.js"></script>
<body onload="base_axes()">
<svg id="base_axes" height="100%" width="100%"></svg>
I'm using this to load an svg into another svg and then transform it:
<svg id="base" height="100%" width="100%"></svg>
JS:
var s = Snap("#base");
var dim = 1;
Snap.load('img.svg', function(data) {
var logo = s.append(data);
var bbox = logo.getBBox();
console.log(bbox);
var scale_factor = dim/bbox.height;
var transform_string = "'s" + scale_factor + "," + scale_factor + "'";
logo.transform(transform_string);
});
But nothing happens. In an effort to troubleshoot, I replaced the bottom line with logo.transform('s0.1,0.1'), and that failed too. Is there something wrong with the creation of logo?
To clarify - the first svg, #id, is selected correctly, the new svg (logo) is correctly appended to it, and bbox is calculated correctly, but the final transform does nothing. The transform string looks correct, evaluating to s0.03,0.03, but the final line logo.transform(transform_string) does nothing.
I think your problem is this line, but I can't be sure without seeing it in a test example...
var logo = s.append(data);
If you look at the docs here, it says it returns the parent element. So you are saying 'logo = the svg element'.
The svg element doesn't allow transforms (in some browsers, see Roberts comment below).
So you either want to select for example a 'g' element in the svg logo by selecting it (eg s.select('#logo') or Snap('#logo'), but we haven't seen that to know if it exists), or append the svg logo to a 'g' element thats inside your svg element eg
<svg id="base" height="100%" width="100%"><g id="logo"></g></svg>
then you can apply the transform to that, rather than the svg, eg
var logo = Snap('#logo').append(data)
You also need to remove the quotes in your transform string. I.e
var transform_string = "s" + scale_factor + "," + scale_factor;

Javascript / HTML5 - Canvas get selected objects dimensions

I have an image in a canvas. The image contains squares of different colors. I'd to click on a square and get the dimensions of the square. (pixels)
For example click on a red square with yellow border and return 24 X 100
I have seen code like this . which I think is part of the solution.... but can't seem to get it work.
Any ideas?
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
// Let's draw a green square
ctx.fillStyle = "rgb(0,127,0)";
ctx.fillRect(10, 10, 20, 20);
// We will now get two pixels, the first one filling inside the above square and the other outside the square
var Pixel = ctx.getImageData(29, 10, 2, 1);
// Let's print out the colour values of the first pixel. Since we have set the colour of the
// square as rgb(0,127,0), that is what the alert should print out. Since we have not set
// any alpha value, Pixel.data[3] should be the defualt 255.
alert("Pixel 1: " + Pixel.data[0] + ", " + Pixel.data[1] + ", " + Pixel.data[2] + ", " + Pixel.data[3]);
// Print out the second pixel, which is outside the square.
// since we have drawn nothing there yet, it will show the default values 0,0,0,0 (Transparent Black)
alert("Pixel 2: " + Pixel.data[4] + ", " + Pixel.data[5] + ", " + Pixel.data[6] + ", " + Pixel.data[7]);
// Let's get the width and height data from Pixel
alert("Pixels Width: " + Pixel.width);
alert("Pixels Height: " + Pixel.height);
}
}
You could use .getImageData, but there's a much easier way...
Save the information about each square you're drawing in an object:
var green={x:10,y:10,width:20,height:20,color:"rgb(0,127,0)"};
Put all objects in an array:
var squares=[];
squares.push(green);
Then when the user clicks, enumerate all the saved squares and see if the mouse is over one:
for(var i=0;i<squares.length;i++){
var s=squares[i];
if(mouseX>=s.x && mouseX<=s.x+s.width && mouseY>=s.y && mouseY<=s.y+s.height){
alert("You clicked on a square with size: "+s.width+"x"+s.height);
}
}
[ Addition based on questioner's comment (that comment was deleted by questioner) ]
Questioner's deleted comment:
What if I don't have info on the squares. The squares are from a photo?
Assuming the canvas contains colored rectangles, here's how to calculate the width x height of the colored rectangle containing the specified x,y coordinate:
function calcColorBounds(x,y){
var data=ctx.getImageData(0,0,canvas.width,canvas.height).data;
var n=i=(y*canvas.width+x)*4;
var r=data[i];
var g=data[i+1];
var b=data[i+2];
var minX=x;
while(minX>=0 && data[i]==r && data[i+1]==g && data[i+2]==b){
minX--;
i=(y*canvas.width+minX)*4;
}
i=n;
var maxX=x;
while(maxX<=canvas.width && data[i]==r && data[i+1]==g && data[i+2]==b){
maxX++;
i=(y*canvas.width+maxX)*4;
}
i=n;
var minY=y;
while(minY>=0 && data[i]==r && data[i+1]==g && data[i+2]==b){
minY--;
i=(minY*canvas.width+x)*4;
}
i=n;
var maxY=y;
while(maxY<=canvas.height && data[i]==r && data[i+1]==g && data[i+2]==b){
maxY++;
i=(maxY*canvas.width+x)*4;
}
alert("size",maxX-minX-1,"x",maxY-minY-1);
}

How to construct Raster and resize it?

I'm using Paper.js for some canvas drawings. I'm trying to resize and position an Raster depending on canvas size but my code doesn't works properly.
var canvas = document.getElementById('canvas');
paper.setup(canvas);
var pitch = new paper.Raster('{{ STATIC_URL }}images/pitch.png');
var width = paper.view.size.width;
var height = paper.view.size.height;
console.log("screen dimensions: " + width + " " + height);
var midPoint = [width/2,height/2];
var paddingLeft = width/40;
var scale = (height/pitch.height)*(90/100);
console.log("scale: " + scale);
pitch.scale(scale);
console.log("pitch dimensions: " + pitch.height + " " + pitch.width);
pitch.position = [midPoint[0] + paddingLeft - (width-pitch.width*scale)/2 , midPoint[1]];
console.log("pitch position: " + pitch.position);
when I load the page for the first time, I get this logs:
screen dimensions: 472.5 340
scale: Infinity
pitch dimensions: 0 0
pitch position: { x: NaN, y: NaN }
but after refreshing the page, everything works fine.
screen dimensions: 472.5 340
scale: 0.6120000000000001
pitch dimensions: 500 759
pitch position: { x: 244.0665, y: 170 }
I think creating a new var for a Raster lags a bit at the first time. But i have no idea how to overcome this problem.
If you create a raster with a url as the input, you can use the onLoad handler to hold a function. In your case:
var canvas = document.getElementById('canvas');
paper.setup(canvas);
var pitch = new paper.Raster('{{ STATIC_URL }}images/pitch.png');
pitch.onLoad = function () {
var width = paper.view.size.width;
etc ...
}

Measuring length of string in pixel in javascript

How do I find the length of string in pixels in javascript , if I know the font-size and font-family?
The simplest solution is to create an in memory canvas (i.e. one that isn't added to the DOM) and then use the measureText function :
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.font = "11px Arial";
var width = ctx.measureText(str).width;
you can put your string into paragraph and use the jquery width function to get the width in pixel width
function showWidth(ele, w) {
$("div").text("The width for the " + ele +
" is " + w + "px.");
}
$("#getp").click(function () {
showWidth("paragraph", $("p").width());
});
check jsfiddle

Cropping an image with a preview using jcrop

I'm using jcrop and trying to make a "live" preview of the cropped area on an image.
The movement of the selected area works perfectly if the "Crop Selection" area is the same height and width as the destination preview div.
Check out the issue here: http://jsfiddle.net/fbaAW/
function showCoords(c)
{
var $this = this.ui.holder;
var original = $this.prev();
var preview = original.parent().find(".image");
var oH = original.height();
var oW = original.width();
var pH = preview.height();
var pW = preview.width();
var sH = c.h;
var sW = c.w;
var differenceH = pH - sH;
var differenceW = pW - sW;
//preview.css('width', c.w);
//preview.css('height', c.h);
//preview.css("background-size", Math.round(oW + differenceW) + "px" + " " + Math.round(oH + differenceH) + "px");
preview.css("background-position", Math.round(c.x) * -1 + "px" + " " + Math.round(c.y) * -1 + "px");
}
As you can see, I've commented out a few of my tests and attempts at getting this code to work properly but I just can't wrap my head around the relationship between the position and the size background properties in order to get this effect to work correctly.
Calculate the horizontal and vertical ratios between the selection size and the preview area size:
var rW = pW / c.w;
var rH = pH / c.h;
Then apply them to the background-size and background-position:
preview.css("background-size", (oW*rW) + "px" + " " + (oH*rH) + "px");
preview.css("background-position", rW * Math.round(c.x) * -1 + "px" + " " + rH * Math.round(c.y) * -1 + "px");
http://jsfiddle.net/fbaAW/1/
So, if the preview size is, say, 3 times the size of your jCrop selection area, it means you have scale the original image by 3, and compensate for the scaling when defining the background position.

Categories

Resources