kineticjs - createImageRegion for pixels with opacity > 0 not only 1 - opacity

So the createImageRegion method ignores all pixels with a tiny bit of alpha/opacity.
How can you make this function so that also pixels with an opacity of .5 or something will be count for hitdetection?
I looked into KineticJS. A colorKey is added to a hitregion, but it transforms the key to a hex key with no alpha. I can't figure out a way how i could make this work.
Help is much appriciated!
this is where the magic happens. But i don't understand how i can include pixels whith any kind of transpanacy but 0
createImageHitRegion: function (callback) {
var canvas = new Kinetic.Canvas(this.attrs.width, this.attrs.height);
var context = canvas.getContext();
context.drawImage(this.attrs.image, 0, 0);
try {
var imageData = context.getImageData(0, 0, canvas.getWidth(), canvas.getHeight());
var data = imageData.data;
var rgbColorKey = Kinetic.Type._hexToRgb(this.colorKey);
// replace non transparent pixels with color key
for (var i = 0, n = data.length; i < n; i += 4) {
data[i] = rgbColorKey.r;
data[i + 1] = rgbColorKey.g;
data[i + 2] = rgbColorKey.b;
// i+3 is alpha (the fourth element)
}
var that = this;
Kinetic.Type._getImage(imageData, function (imageObj) {
that.imageHitRegion = imageObj;
if (callback) {
callback();
}
});
}
catch (e) {
Kinetic.Global.warn('Unable to create image hit region. ' + e.message);
}
}
When i include: data[i + 3] = 255 (rgbColorKey.a) does not excist, none of the imageevents are working anymore

I found the answer:
for (var i = 0, n = data.length; i < n; i += 4) {
data[i] = rgbColorKey.r;
data[i + 1] = rgbColorKey.g;
data[i + 2] = rgbColorKey.b;
if (!ignoreAlpha && data[i + 3] > 0) {
data[i + 3] = 255;
}
}
This way, every pixel which has a bit of transparancy left, it will get a full color. So if you prototype this to kinetixJS it should work:
Kinetic.Image.prototype.createImageHitRegion = function (callback, ignoreTransparantPixels) {
var canvas = new Kinetic.Canvas(this.attrs.width, this.attrs.height);
var context = canvas.getContext();
var _ignoreTransparantPixels;
if(typeof ignoreTransparantPixels == 'undefined'){
_ignoreTransparantPixels = false;
}
context.drawImage(this.attrs.image, 0, 0);
try {
var imageData = context.getImageData(0, 0, canvas.getWidth(), canvas.getHeight());
var data = imageData.data;
var rgbColorKey = Kinetic.Type._hexToRgb(this.colorKey);
// replace non transparent pixels with color key
for (var i = 0, n = data.length; i < n; i += 4) {
data[i] = rgbColorKey.r;
data[i + 1] = rgbColorKey.g;
data[i + 2] = rgbColorKey.b;
if (!_ignoreTransparantPixels && data[i + 3] > 0) {
data[i + 3] = 255;
}
//trace(data[i + 3]);
// i+3 is alpha (the fourth element)
}
var that = this;
Kinetic.Type._getImage(imageData, function (imageObj) {
that.imageHitRegion = imageObj;
if (callback) {
callback();
}
});
}
catch (e) {
Kinetic.Global.warn('Unable to create image hit region. ' + e.message);
}
}

Related

Perceptron Training Issues

I am trying to build a simple perceptron. Right now I am just trying to find the weight values for the training data set to make sure it is working, but it will not converge no matter how many epochs I use.
here's the code:
`
var inputs = [];
inputs[0] = [15, 30, 1];
inputs[1] = [45, 90, -1];
inputs[2] = [64, 120, -1];
inputs[3] = [21, 40, 1];
inputs[4] = [9, 18, 1];
var weights = [0,0];
var epochs = 100;
var lRate = 0.1;
var bias = 12;
function weighted_sum(inputs, weights)
{
var products = [];
var weightedSum = 0;
for (var i = 0; i < weights.length; i++)
{
products.push(inputs[i]*weights[i]);
}
for (var i = 0; i < products.length; i++)
{
weightedSum += products[i];
}
return weightedSum;
}
function activate(weightedSum)
{
if (weightedSum >= 0)
{
return 1;
}
else
{
return -1;
}
}
function adjust(error, weights, input)
{
if (error !== 0)
{
for (var i = 0; i < weights.length; i++)
{
weights[i] += lRate * error * input[i];
}
bias += lRate * error;
}
}
function train(inputs, weights, epochs)
{
for (var n = 0; n < epochs; n++)
{
for (var i = 0; i < inputs.length; i++)
{
var set = inputs[i];
var weightedSum = weighted_sum(set, weights);
var result = activate(weightedSum);
var target = set[2];
var error = target - result;
adjust(error, weights, set);
console.log("result: "+ result + " target: " + target + " error: " + error + " weights: " + weights);
}
for (i = inputs.length; i > 0; i--)
{
var set = inputs[i];
var weightedSum = weighted_sum(set, weights);
var result = activate(weightedSum);
var target = set[2];
var error = target - result;
adjust(error, weights, set);
console.log("result: "+ result + " target: " + target + " error: " + error + " weights: " + weights);
}
}
}
train(inputs, weights, epochs);
console.log(weights);
`
Any help is appreciated, with my problem, or just general improvements. Thanks!

Get two offset points between two points

Hi I need help finding coordinate or points offset from two endpoints of a line. In my program, I would like to specify the two points and the offset. Then I need to calculate the two offset coordinates.
I worked something out using trigonometry but it only works in some cases and when the line is in the positive quadrant.
Here is an image describing what I need to find:
Points on line
Ok so I need to find X3,Y3 and X4,Y4 coordinates.
My method I followed:
Calculate angle:
Ang = atan((Y2 - Y1)/(X2 - X1))
To find X3:
X3 = X1 + Offset * Cos(Ang)
The same concept for Y3
The issue is that if the line is in a different quadrant the point info is not correct... Any help, please.
This question is a clear case for using 2d vector math. The idea is that we subtract p1 from p2 to give us a vector that describes the length and direction of the line. We then normalize this vector, such that it has a length of 1. If you then multiply this normalized vector with the number of units you'd like to move away from the end and add the result to the end-point, you'll have a new point.
Consider an example walking along the x axis:
p1 = 0,0
p2 = 10,0
dif = p2 - p1 = (10,0)
length is 10, so it's 10 times too long - we divide it by 10 to get a vector 1 unit long.
If we then move 5 times (1,0), we end up at 5,0 - 5 units away, bewdy!
Here's a function that achieves the same thing:
function calcOffsetPoint(x1,y1, x2,y2, distTowardsP2fromP1)
{
var p1 = new vec2d(x1,y1);
var p2 = new vec2d(x2,y2);
var delta = p2.sub(p1);
var dirVec = delta.clone();
dirVec.normalize();
dirVec.timesEquals(distTowardsP2fromP1);
var resultPoint = p1.add(dirVec);
return resultPoint;
}
As you can see, this makes use of something I've called vec2d. There's a copy of it in the following snippet:
"use strict";
function byId(id){return document.getElemetById(id)}
function newEl(tag){return document.createElement(tag)}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
var end1 = new vec2d(0,0);
var end2 = new vec2d(10,0);
var midPoint = calcOffsetPoint(end1.x,end1.y, end2.x,end2.y, 5);
console.log( midPoint.toStringN(2) );
}
class vec2d
{
constructor(x=0, y=0)
{
this.mX = x;
this.mY = y;
}
get x(){return this.mX;}
set x(newX){this.mX = newX;}
get y(){return this.mY;}
set y(newY){this.mY = newY;}
add(other)
{
return new vec2d(this.x+other.x, this.y+other.y);
}
sub(other)
{
return new vec2d(this.x-other.x, this.y-other.y);
}
timesEquals(scalar)
{
this.x *= scalar;
this.y *= scalar;
return this;
}
divByEquals(scalar)
{
this.x /= scalar;
this.y /= scalar;
return this;
}
dotProd(other)
{
return this.x*other.x + this.y*other.y;
}
length()
{
return Math.hypot(this.x, this.y);
}
normalize()
{
this.divByEquals( this.length() );
return this;
}
perpendicular()
{
var tmp = this.x;
this.x = -this.y;
this.y = tmp;
return this;
}
clone()
{
return vec2d.clone(this);
}
static clone(other)
{
return new vec2d(other.x, other.y);
}
toString(){return `vec2d {x: ${this.x}, y: ${this.y}}`}
toStringN(n){return `vec2d {x: ${this.x.toFixed(n)}, y: ${this.y.toFixed(n)}}`}
}
function calcOffsetPoint(x1,y1, x2,y2, distTowardsP2fromP1)
{
var p1 = new vec2d(x1,y1);
var p2 = new vec2d(x2,y2);
var delta = p2.sub(p1);
var dirVec = delta.clone();
dirVec.normalize();
dirVec.timesEquals(distTowardsP2fromP1);
var resultPoint = p1.add(dirVec);
return resultPoint;
}
I had some spare time over the weekend, so put together a working demo of the image you posted. Have a play around. Make sure you run it in full-screen, so you can see the sliders that set the offsets for p3 and p4. Disregard the coordinate-system transformation stuff, that's just there to allow me to make an image the same dimensions as your image yet conveniently display it in a window with about 5% the area. The questions come from the exercise section of some old text-book I was reading over the weekend.
"use strict";
class vec2d
{
constructor(x=0,y=0)
{
this.x = x;
this.y = y;
}
abs()
{
this.x = Math.abs(this.x);
this.y = Math.abs(this.y);
return this;
}
add(vec1)
{
return new vec2d(this.x+vec1.x, this.y+vec1.y);
}
sub(vec1)
{
return new vec2d(this.x-vec1.x, this.y-vec1.y);
}
mul(scalar)
{
return new vec2d(this.x*scalar, this.y*scalar);
}
plusEquals(vec1)
{
this.x += vec1.x;
this.y += vec1.y;
return this;
}
minusEquals(vec1)
{
this.x -= vec1.x;
this.y -= vec1.y;
return this;
}
timesEquals(scalar)
{
this.x *= scalar;
this.y *= scalar;
return this;
}
divByEquals(scalar)
{
this.x /= scalar;
this.y /= scalar;
return this;
}
normalize()
{
var len = this.length;
this.x /= len;
this.y /= len;
return this;
}
get length()
{
//return Math.sqrt( (this.x*this.x)+(this.y*this.y) );
return Math.hypot( this.x, this.y );
}
set length(newLen)
{
var invLen = newLen / this.length;
this.timesEquals(invLen);
}
dotProd(vec1)
{
return this.x*vec1.x + this.y*vec1.y;
}
perp()
{
var tmp = this.x;
this.x = -this.y;
this.y = tmp;
return this;
}
wedge(other)
{ // computes an area for parallelograms
return this.x*other.y - this.y*other.x;
}
static clone(other)
{
var result = new vec2d(other.x, other.y);
return result;
}
clone() // clone self
{
return vec2d.clone(this);
}
setTo(other)
{
this.x = other.x;
this.y = other.y;
}
get(){ return {x:this.x, y:this.y}; }
toString(){ return `vec2d {x: ${this.x}, y: ${this.y}}` }
toStringN(n){ return `vec2d {x: ${this.x.toFixed(n)}, y: ${this.y.toFixed(n)}}` }
print(){console.log(this.toString())}
};
class mat3
{
static clone(other)
{
var result = new mat3();
other.elems.forEach(
function(el, index, collection)
{
result.elems[index] = el;
}
);
return result;
}
clone()
{
return mat3.clone(this);
}
constructor(a,b,c,d,e,f)
{
if (arguments.length < 6)
this.setIdentity();
else
this.elems = [a,b,0,c,d,0,e,f,1];
}
setIdentity()
{
this.elems = [1,0,0, 0,1,0, 0,0,1];
}
multiply(other, shouldPrepend)
{
var a, b, c = new mat3();
if (shouldPrepend === true)
{
a = other;
b = this;
}
else
{
a = this;
b = other;
}
c.elems[0] = a.elems[0]*b.elems[0] + a.elems[1]*b.elems[3] + a.elems[2]*b.elems[6];
c.elems[1] = a.elems[0]*b.elems[1] + a.elems[1]*b.elems[4] + a.elems[2]*b.elems[7];
c.elems[2] = a.elems[0]*b.elems[2] + a.elems[1]*b.elems[5] + a.elems[2]*b.elems[8];
// row 1
c.elems[3] = a.elems[3]*b.elems[0] + a.elems[4]*b.elems[3] + a.elems[5]*b.elems[6];
c.elems[4] = a.elems[3]*b.elems[1] + a.elems[4]*b.elems[4] + a.elems[5]*b.elems[7];
c.elems[5] = a.elems[3]*b.elems[2] + a.elems[4]*b.elems[5] + a.elems[5]*b.elems[8];
// row 2
c.elems[6] = a.elems[6]*b.elems[0] + a.elems[7]*b.elems[3] + a.elems[8]*b.elems[6];
c.elems[7] = a.elems[6]*b.elems[1] + a.elems[7]*b.elems[4] + a.elems[8]*b.elems[7];
c.elems[8] = a.elems[6]*b.elems[2] + a.elems[7]*b.elems[5] + a.elems[8]*b.elems[8];
for (var i=0; i<9; i++)
this.elems[i] = c.elems[i];
}
transformVec2s(pointList)
{
var i, n = pointList.length;
for (i=0; i<n; i++)
{
var x = pointList[i].x*this.elems[0] + pointList[i].y*this.elems[3] + this.elems[6];
var y = pointList[i].x*this.elems[1] + pointList[i].y*this.elems[4] + this.elems[7];
pointList[i].x = x;
pointList[i].y = y;
}
}
makeTransformedPoints(pointList)
{
var result = [];
for (var i=0,n=pointList.length;i<n;i++)
{
var x = pointList[i].x*this.elems[0] + pointList[i].y*this.elems[3] + this.elems[6];
var y = pointList[i].x*this.elems[1] + pointList[i].y*this.elems[4] + this.elems[7];
result.push( new vec2d(x,y) );
}
return result;
}
rotate(degrees, shouldPrepend)
{
var tmp = new mat3();
tmp.elems[0] = Math.cos( degrees/180.0 * Math.PI );
tmp.elems[1] = -Math.sin( degrees/180.0 * Math.PI );
tmp.elems[3] = -tmp.elems[1];
tmp.elems[4] = tmp.elems[0];
this.multiply(tmp, shouldPrepend);
}
scaleEach(scaleX, scaleY, shouldPrepend)
{
var tmp = new mat3();
tmp.elems[0] = scaleX;
tmp.elems[4] = scaleY;
this.multiply(tmp, shouldPrepend);
}
scaleBoth(scaleAmount, shouldPrepend)
{
var tmp = new mat3();
tmp.elems[0] = scaleAmount;
tmp.elems[4] = scaleAmount;
this.multiply(tmp, shouldPrepend);
}
translate(transX, transY, shouldPrepend)
{
var tmp = new mat3();
tmp.elems[6] = transX;
tmp.elems[7] = transY;
this.multiply(tmp, shouldPrepend);
}
determinant()
{
var result, a, b;
a = ( (this.elems[0]*this.elems[4]*this.elems[8])
+ (this.elems[1]*this.elems[5]*this.elems[6])
+ (this.elems[2]*this.elems[3]*this.elems[7]) );
b = ( (this.elems[2]*this.elems[4]+this.elems[6])
+ (this.elems[1]*this.elems[3]+this.elems[8])
+ (this.elems[0]*this.elems[5]+this.elems[7]) );
result = a - b;
return result;
}
isInvertible()
{
return (this.determinant() != 0);
}
invert()
{
var det = this.determinant();
if (det == 0)
return;
var a,b,c,d,e,f,g,h,i;
a = this.elems[0]; b = this.elems[1]; c = this.elems[2];
d = this.elems[3]; e = this.elems[4]; f = this.elems[5];
g = this.elems[6]; h = this.elems[7]; i = this.elems[8];
this.elems[0] = (e*i - f*h); this.elems[1] = -((b*i) - (c*h)); this.elems[2] = (b*f)-(c*e);
this.elems[3] = -(d*i - f*g); this.elems[4] = (a*i) - (c*g); this.elems[5] = -( (a*f) - (c*d) );
this.elems[6] = (d*h - e*g); this.elems[7] = -((a*h) - (b*g)); this.elems[8] = (a*e)-(b*d);
var detInv = 1.0 / det;
for (var i=0; i<9; i++)
this.elems[i] *= detInv;
return this;
}
reset()
{
this.setIdentity();
}
print()
{
var str = '';
for (var i=0; i<9; i++)
{
if (i && i%3==0)
str += "\n";
str += " " + this.elems[i].toFixed(5);
}
console.log(str);
}
}
function byId(id){return document.getElementById(id)}
function newEl(tag){return document.createElement(tag)}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('output').addEventListener('mousemove', onMouseMove, false);
byId('slider1').addEventListener('input', onSliderInput, false);
byId('slider2').addEventListener('input', onSliderInput, false);
draw();
}
//(400-48)/400 = 0.88
var invMat, svgInvMat;
function onMouseMove(evt)
{
var mousePos = new vec2d(evt.offsetX,evt.offsetY);
var worldPos = mousePos.clone();
invMat.transformVec2s( [worldPos] );
byId('screenMouse').textContent = `screen: ${mousePos.x},${mousePos.y}`;
byId('worldMouse').textContent = `world: ${worldPos.x.toFixed(1)}, ${worldPos.y.toFixed(1)}`;
}
function onSliderInput(evt)
{
draw();
}
function updateSliderLabels()
{
byId('ofset1Output').textContent = byId('slider1').value;
byId('ofset2Output').textContent = byId('slider2').value;
}
function draw()
{
var can = byId('output');
var ctx = can.getContext('2d');
ctx.clearRect(0,0,can.width,can.height);
var orientMat = evaluateViewOrientationMatrix(0.06*can.width,can.height-24, 0,-1);
var scaleMat = computeWindowToViewPortMatrix(2052,1317, can.width,can.height);
var viewMat = scaleMat.clone();
viewMat.multiply(orientMat);
console.log('viewMat');
viewMat.print();
invMat = viewMat.clone().invert();
for (var i=0; i<9; i++)
invMat.elems[i] /= invMat.elems[8];
ctx.strokeStyle = '#fff';
var axisPts = [ new vec2d(0,1070), new vec2d(0,0), new vec2d(0.88*2052,0) ]; // xAxis line 88% of image width
var axis = viewMat.makeTransformedPoints(axisPts);
drawLine(axis[0].x,axis[0].y, axis[1].x,axis[1].y, ctx);
drawLine(axis[1].x,axis[1].y, axis[2].x,axis[2].y, ctx);
var lineEnds = [new vec2d(330,263), new vec2d(1455,809)];
var pts2 = viewMat.makeTransformedPoints(lineEnds);
drawCircle(pts2[0].x,pts2[0].y, 4, ctx);
drawCircle(pts2[1].x,pts2[1].y, 4, ctx);
drawLine(pts2[0].x,pts2[0].y, pts2[1].x,pts2[1].y, ctx);
var rawP3 = calcOffsetCoords(lineEnds[0].x,lineEnds[0].y, lineEnds[1].x,lineEnds[1].y, byId('slider1').value);
var rawP4 = calcOffsetCoords(lineEnds[1].x,lineEnds[1].y, lineEnds[0].x,lineEnds[0].y, byId('slider2').value);
var ofsPts = viewMat.makeTransformedPoints( [rawP3, rawP4] );
drawCircle(ofsPts[0].x,ofsPts[0].y, 4, ctx);
drawCircle(ofsPts[1].x,ofsPts[1].y, 4, ctx);
updateSliderLabels();
}
function calcOffsetCoords(x1,y1, x2,y2, offset)
{
var dx = x2 - x1;
var dy = y2 - y1;
var lineLen = Math.hypot(dx, dy);
var normDx=0, normDy=0;
if (lineLen != 0)
{
normDx = dx / lineLen;
normDy = dy / lineLen;
}
var resultX = x1 + (offset * normDx);
var resultY = y1 + (offset * normDy);
return {x:resultX,y:resultY};//new vec2d(resultX,resultY); //{x:resultX,y:resultY};
}
// Exercise 6-1:
// Write a procedure to implement the evaluateViewOrientationMatrix function that calculates the elements of the
// matrix for transforming world coordinates to viewing coordinates, given the viewing coordinate origin Porigin and
// the viewUp vector
function evalViewOrientMatrix(screenOriginX,screenOriginY, worldUpVectorX,worldUpVectorY)
{
var worldUp = {x: worldUpVectorX, y: worldUpVectorY};
var len = Math.hypot(worldUp.x, worldUp.y);
if (len != 0)
len = 1.0 / len;
worldUp.x *= len;
worldUp.y *= len;
var worldRight = {x: worldUp.y, y: -worldUp.x};
var rotMat = svg.createSVGMatrix();
rotMat.a = worldRight.x;
rotMat.b = worldRight.y;
rotMat.c = worldUp.x;
rotMat.d = worldUp.y;
var transMat = svg.createSVGMatrix();
transMat = transMat.translate(screenOriginX, screenOriginY);
var result = rotMat.multiply(transMat);
return result;
}
function evaluateViewOrientationMatrix(screenOriginX,screenOriginY, worldUpVectorX,worldUpVectorY)
{
var worldUp = new vec2d(worldUpVectorX, worldUpVectorY);
worldUp.normalize();
var worldRight = worldUp.clone().perp();
var rotMat = new mat3();
rotMat.elems[0] = worldRight.x; rotMat.elems[1] = worldRight.y;
rotMat.elems[3] = worldUp.x; rotMat.elems[4] = worldUp.y;
var transMat = new mat3();
transMat.translate(screenOriginX,screenOriginY);
var result = rotMat.clone();
result.multiply(transMat);
return result;
}
/*
0 1 2
3 4 5
6 7 8
translation
-----------
1 0 0
0 1 0
tX tY 1
scaling
---------
sX 0 0
0 sY 0
0 0 1
rotation
--------
cosX -sinX 0
sinX cosX 0
0 0 1
*/
// Exercise 6-2:
// Derive the window to viewport transformation equations 6-3 by first scaling the window to
// the size of the viewport and then translating the scaled window to the viewport position
function computeWindowToViewPortMatrix(windowWidth,windowHeight,viewPortWidth,viewPortHeight)
{
var result = new mat3();
result.scaleEach(viewPortWidth/windowWidth,viewPortHeight/windowHeight);
return result;
}
// returns an SVGMatrix
function compWnd2ViewMat(windowWidth,windowHeight,viewPortWidth,viewPortHeight)
{
var result = svg.createSVGMatrix();
return result.scaleNonUniform(viewPortWidth/windowWidth,viewPortHeight/windowHeight);
}
function drawLine(x1,y1,x2,y2,ctx)
{
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.stroke();
}
function drawCircle(x,y,radius,ctx)
{
ctx.beginPath();
ctx.arc(x, y, radius, 0, (Math.PI/180)*360, false);
ctx.stroke();
ctx.closePath();
}
canvas
{
background-color: black;
}
.container
{
display: inline-block;
background-color: #888;
border: solid 4px #555;
}
#screenMouse, #worldMouse, .control
{
display: inline-block;
width: calc(513px/2 - 2*8px);
margin-left: 8px;
}
<body>
<div class='container'>
<canvas id='output' width='513' height='329'></canvas><br>
<div id='screenMouse'></div><div id='worldMouse'></div>
<div>
<div class='control'>P2 ofs: <input id='slider1' type='range' min='0' max='500' value='301'><span id='ofset1Output'></span></div>
<div class='control'>P3 ofs: <input id='slider2' type='range' min='0' max='500' value='285'><span id='ofset2Output'></span></div>
</div>
</div>
</body>

Chart.js click on labels, using bar chart

i need help with my Chart.js interactivity. When I click on the label, I need to return the column(index) number at which I clicked.
I tried to use getElementsAtEvent but it only work if I click directly at chart.
This http://jsfiddle.net/yxz2sjam/ is pretty much what I am looking for but getPointsAtEvent is no longer available in the new versions.
canvas.onclick = function (evt) {
var points = chart.getPointsAtEvent(evt);
alert(chart.datasets[0].points.indexOf(points[0]));
};
I also found this http://jsfiddle.net/1Lngmtz7/ but it isn't working with bar chart.
var ctx = document.getElementById("myChart").getContext("2d");
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: data
})
$('#myChart').click(function (e) {
var helpers = Chart.helpers;
var eventPosition = helpers.getRelativePosition(e, myRadarChart.chart);
var mouseX = eventPosition.x;
var mouseY = eventPosition.y;
var activePoints = [];
helpers.each(myRadarChart.scale.ticks, function (label, index) {
for (var i = this.getValueCount() - 1; i >= 0; i--) {
var pointLabelPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max) + 5);
var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, Chart.defaults.global.defaultFontSize);
var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, Chart.defaults.global.defaultFontStyle);
var pointLabeFontFamily = helpers.getValueOrDefault(this.options.pointLabels.fontFamily, Chart.defaults.global.defaultFontFamily);
var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily);
ctx.font = pointLabeFont;
var labelsCount = this.pointLabels.length,
halfLabelsCount = this.pointLabels.length / 2,
quarterLabelsCount = halfLabelsCount / 2,
upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
var width = ctx.measureText(this.pointLabels[i]).width;
var height = pointLabelFontSize;
var x, y;
if (i === 0 || i === halfLabelsCount)
x = pointLabelPosition.x - width / 2;
else if (i < halfLabelsCount)
x = pointLabelPosition.x;
else
x = pointLabelPosition.x - width;
if (exactQuarter)
y = pointLabelPosition.y - height / 2;
else if (upperHalf)
y = pointLabelPosition.y - height;
else
y = pointLabelPosition.y
if ((mouseY >= y && mouseY <= y + height) && (mouseX >= x && mouseX <= x + width))
activePoints.push({ index: i, label: this.pointLabels[i] });
}
}, myRadarChart.scale);
var firstPoint = activePoints[0];
if (firstPoint !== undefined) {
alert(firstPoint.index + ': ' + firstPoint.label);
}
});
Thank for response.
I solve the problem with
document.getElementById("chart").onclick = function(e)
{
var activeElement = weatherMainChart.lastTooltipActive;
console.log(activeElement[0]._index);
};
this solution register clicks on chart and label, then I restricted it with e.layerY to register only clicks on label section.
document.getElementById("chart").onclick = function(e)
{
var activeElement = weatherMainChart.lastTooltipActive;
if(e.layerY > 843 && e.layerY < 866 && activeElement[0] !== undefined)
console.log(activeElement[0]._index);
};
If you add a click handler through the onClick option you can use the following code using the getElementsAtEventForMode() call:
function handleClick(evt) {
var col;
switch(chartType) {
case "horizontalBar":
this.getElementsAtEventForMode(evt, "y", 1).forEach(function(item) { col = item._index });
break;
case "bar":
this.getElementsAtEventForMode(evt, "x", 1).forEach(function(item) { col = item._index });
break;
}
if (!col) {
return;
}
alert("Column " + col + " was selected");
};
You'll probably need to add extra switch checks for other chart types but I'm sure you get the idea.
Using version 2.4.0, i created an onClick Event, and inside it
var activeIndex = localChart.tooltip._lastActive[0]._index;
var clickCoordinates = Chart.helpers.getRelativePosition(e, localChart.chart);
if (clickCoordinates.y >= 530) { //custom value, depends on chart style,size, etc
alert("clicked on " + localChart.data.labels[activeIndex]);
}
I Solved this problem with single or multiple label click you will be find using true/false
First you need to set your chartJs Id click
below code SessionChart = Your ChartJs ID e.g. ("myChart") I was replace it for my Id
document.getElementById("SessionChart").onclick = function (evt) {
var meta = SubscriberSessionChart.getDatasetMeta(0);
if (meta.$filler.chart.legend.legendItems[0].text.toLowerCase() "sessions")
{
if (meta.$filler.chart.legend.legendItems[0].hidden) {
sessionHidden = true;
}
}
}
here "sessions" = first label text
meta.$filler.chart.legend.legendItems[0].text.toLowerCase() = is your first label
from Array so you can get multiple label's click here true / false
if (meta.$filler.chart.legend.legendItems[0].hidden) = your label is not active then
you will get hidden true otherwise you will get false if not tick on label
by default label tick hidden is false in chart js

jsPDF multi page PDF with HTML renderer

I am using jsPDF in my site to generate PDFs. But now I have multiple DIVs to print in a single PDF. which may take 2 to 3 pages.
For example:
<div id="part1">
content
</div>
<div id="part2">
content
</div>
<div id="part2">
content
</div>
my JS code
This works but not as I expected, It add a part of the content(which cannot be included in more than one page).
It removes html tags like br, h1 etc.
function formtoPDF() {
jsPDF.API.mymethod = function() {
// 'this' will be ref to internal API object. see jsPDF source
// , so you can refer to built-in methods like so:
// this.line(....)
// this.text(....)
};
var doc = new jsPDF();
doc.mymethod();
var pdfPart1 = jQuery('#genPDFpart1');
var pdfPart2 = jQuery(".ltinerary");
var pdfPart3 = jQuery("#domElementHTML");
var specialElementHandlers = {
'#loadVar': function(element, renderer) {
return true;
}
};
doc.fromHTML(pdfPart1.html() + pdfPart3.html() + pdfPart3.html(), 15, 15, {
'width': 170,
'elementHandlers': specialElementHandlers
});
doc.output('save', 'Download.pdf');
}
What's the solution for this?
I have the same working issue. Searching in MrRio github I found this: https://github.com/MrRio/jsPDF/issues/101
Basically, you have to check the actual page size always before adding new content
doc = new jsPdf();
...
pageHeight= doc.internal.pageSize.height;
// Before adding new content
y = 500 // Height position of new content
if (y >= pageHeight)
{
doc.addPage();
y = 0 // Restart height position
}
doc.text(x, y, "value");
here's an example using html2canvas & jspdf, although how you generate the canvas doesn't matter--we're just going to use the height of that as the breakpoint on a for loop, in which a new page is created and content added to it.
after the for loop, the pdf is saved.
function makePDF() {
var quotes = document.getElementById('container-fluid');
html2canvas(quotes).then((canvas) => {
//! MAKE YOUR PDF
var pdf = new jsPDF('p', 'pt', 'letter');
for (var i = 0; i <= quotes.clientHeight/980; i++) {
//! This is all just html2canvas stuff
var srcImg = canvas;
var sX = 0;
var sY = 980*i; // start 980 pixels down for every new page
var sWidth = 900;
var sHeight = 980;
var dX = 0;
var dY = 0;
var dWidth = 900;
var dHeight = 980;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', 900);
onePageCanvas.setAttribute('height', 980);
var ctx = onePageCanvas.getContext('2d');
// details on this usage of this function:
// https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images#Slicing
ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);
// document.body.appendChild(canvas);
var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);
var width = onePageCanvas.width;
var height = onePageCanvas.clientHeight;
//! If we're on anything other than the first page,
// add another page
if (i > 0) {
pdf.addPage(612, 791); //8.5" x 11" in pts (in*72)
}
//! now we declare that we're working on that page
pdf.setPage(i+1);
//! now we add content to that page!
pdf.addImage(canvasDataURL, 'PNG', 20, 40, (width*.62), (height*.62));
}
//! after the for loop is finished running, we save the pdf.
pdf.save('Test.pdf');
});
}
I found the solution on this page: https://github.com/MrRio/jsPDF/issues/434
From the user: wangzhixuan
I copy the solution here:
// suppose your picture is already in a canvas
var imgData = canvas.toDataURL('image/png');
/*
Here are the numbers (paper width and height) that I found to work.
It still creates a little overlap part between the pages, but good enough for me.
if you can find an official number from jsPDF, use them.
*/
var imgWidth = 210;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'mm');
var position = 0;
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save( 'file.pdf');
var doc = new jsPDF('p', 'mm');
var imgData = canvas.toDataURL('image/png');
var pageHeight= doc.internal.pageSize.getHeight();
var pageWidth= doc.internal.pageSize.getWidth();
var imgheight = $('divName').height() * 25.4 / 96; //px to mm
var pagecount = Math.ceil(imgheight / pageHeight);
/* add initial page */
doc.addPage('l','mm','a4');
doc.addImage(imgData, 'PNG', 2, 0, pageWidth-4, 0);
/* add extra pages if the div size is larger than a a4 size */
if (pagecount > 0) {
var j = 1;
while (j != pagecount) {
doc.addPage('l','mm','a4');
doc.addImage(imgData, 'PNG', 2, -(j * pageHeight), pageWidth-4, 0);
j++;
}
}
You can use html2canvas plugin and jsPDF both. Process order:
html to png & png to pdf
Example code:
jQuery('#part1').html2canvas({
onrendered: function( canvas ) {
var img1 = canvas.toDataURL('image/png');
}
});
jQuery('#part2').html2canvas({
onrendered: function( canvas ) {
var img2 = canvas.toDataURL('image/png');
}
});
jQuery('#part3').html2canvas({
onrendered: function( canvas ) {
var img3 = canvas.toDataURL('image/png');
}
});
var doc = new jsPDF('p', 'mm');
doc.addImage( img1, 'PNG', 0, 0, 210, 297); // A4 sizes
doc.addImage( img2, 'PNG', 0, 90, 210, 297); // img1 and img2 on first page
doc.addPage();
doc.addImage( img3, 'PNG', 0, 0, 210, 297); // img3 on second page
doc.save("file.pdf");
$( document ).ready(function() {
$('#cmd').click(function() {
var options = {
pagesplit: true //include this in your code
};
var pdf = new jsPDF('p', 'pt', 'a4');
pdf.addHTML($("#pdfContent"), 15, 15, options, function() {
pdf.save('Menu.pdf');
});
});
});
This is my first post which support only a single page http://www.techumber.com/html-to-pdf-conversion-using-javascript/
Now, the second one will support the multiple pages.
http://www.techumber.com/how-to-convert-html-to-pdf-using-javascript-multipage/
Below is my code but the problem is that the document doesn't split to display the other part of the document in a new page.
Please improve this code.
<script type='text/javascript'>
$(document).on("click", "#btnExportToPDF", function () {
var table1 =
tableToJson($('#table1')[0]),
cellWidth =42,
rowCount = 0,
cellContents,
leftMargin = 2,
topMargin = 12,
topMarginTable =5,
headerRowHeight = 13,
rowHeight = 12,
l = {
orientation: 'p',
unit: 'mm',
format: 'a3',
compress: true,
fontSize: 11,
lineHeight: 1,
autoSize: false,
printHeaders: true
};
var doc = new jsPDF(l,'pt', 'letter');
doc.setProperties({
title: 'Test PDF Document',
subject: 'This is the subject',
author: 'author',
keywords: 'generated, javascript, web 2.0, ajax',
creator: 'author'
});
doc.cellInitialize();
$.each(table1, function (i, row)
{
rowCount++;
$.each(row, function (j, cellContent) {
if (rowCount == 1) {
doc.margins = 1;
doc.setFont("Times New Roman");
doc.setFontType("bold");
doc.setFontSize(11);
doc.cell(leftMargin, topMargin, cellWidth, headerRowHeight, cellContent, i)
}
else if (rowCount == 2) {
doc.margins = 1;
doc.setFont("Times ");
doc.setFontType("normal");
// or for normal font type use ------ doc.setFontType("normal");
doc.setFontSize(11);
doc.cell(leftMargin, topMargin, cellWidth, rowHeight, cellContent, i);
}
else {
doc.margins = 1;
doc.setFont("Times ");
doc.setFontType("normal ");
doc.setFontSize(11);
doc.cell(leftMargin, topMargin, cellWidth, rowHeight, cellContent, i);
// 1st=left margin 2nd parameter=top margin, 3rd=row cell width 4th=Row height
}
})
})
doc.save('sample Report.pdf');
});
function tableToJson(table) {
var data = [];
// first row needs to be headers
var headers = [];
for (var i=0; i<table.rows[0].cells.length; i++) {
headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
}
// go through cells
for (var i=1; i<table.rows.length; i++) {
var tableRow = table.rows[i];
var rowData = {};
for (var j=0; j<tableRow.cells.length; j++) {
rowData[ headers[j] ] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
return data;
}
</script>
Automatically not split data to multi pages. You may split manually.
If your ( rowCount * rowHeight ) > 420mm ( A3 Height in mm ) add new page function. ( Sorry I can't edit your code without run )
After add new page leftMargin, topMargin = 0; ( start over )
I added sample code with yours. I hope it's right.
else {
doc.margins = 1;
doc.setFont("Times ");
doc.setFontType("normal ");
doc.setFontSize(11);
if ( rowCount * rowHeight > 420 ) {
doc.addPage();
rowCount = 3; // skip 1 and 2 above
} else {
// now rowcount = 3 ( top of new page for 3 )
// j is your x axis cell index ( j start from 0 on $.each function ) or you can add cellCount like rowCount and replace with
// rowcount is your y axis cell index
left = ( ( j ) * ( cellWidth + leftMargin );
top = ( ( rowcount - 3 ) * ( rowHeight + topMargin );
doc.cell( leftMargin, top, cellWidth, rowHeight, cellContent, i);
// 1st=left margin 2nd parameter=top margin, 3rd=row cell width 4th=Row height
}
}
You can convert html directly to pdf lossless. Youtube video for html => pdf example
html2canvas(element[0], {
onrendered: function (canvas) {
pages = Math.ceil(element[0].clientHeight / 1450);
for (i = 0; i <= pages; i += 1) {
if (i > 0) {
pdf.addPage();
}
srcImg = canvas;
sX = 0;
sY = 1450 * i;
sWidth = 1100;
sHeight = 1450;
dX = 0;
dY = 0;
dWidth = 1100;
dHeight = 1450;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', 1100);
onePageCanvas.setAttribute('height', 1450);
ctx = onePageCanvas.getContext('2d');
ctx.drawImage(srcImg, sX, sY, sWidth, sHeight, dX, dY, dWidth, dHeight);
canvasDataURL = onePageCanvas.toDataURL("image/png");
width = onePageCanvas.width;
height = onePageCanvas.clientHeight;
pdf.setPage(i + 1);
pdf.addImage(canvasDataURL, 'PNG', 35, 30, (width * 0.5), (height * 0.5));
}
pdf.save('testfilename.pdf');
}
});
var a = 0;
var d;
var increment;
for(n in array){
d = a++;
if(n % 6 === 0 && n != 0){
doc.addPage();
a = 1;
d = 0;
}
increment = d == 0 ? 10 : 50;
size = (d * increment) <= 0 ? 10 : d * increment;
doc.text(array[n], 10, size);
}

How to rotate image from cameraUI for iOS in actionscript 3.0

I'm building an App with actionscript 3.0 in my Flash builder. This is a followup question to this question, It works but when I take the picture, the image comes out rotated to the left. how can I check which way the user is holding the phone? and then what code do I use to rotate the image to it's corresponding place?
Thanks in advanced!
EDIT:
I'm using this code to rotate the image, but it seems to only rotate the image being displayed not the image file, any ideas?
var mat:Matrix = new Matrix();
mat.translate(-W/2, -H/2);
mat.rotate(Math.PI/2);
mat.translate(+W/2, +H/2);
mat.concat(myObj.transform.matrix);
myObj.transform.matrix = mat;
~Myy
You can't get stage.orientation data when you have the cameraUI view active, so here's how i solved the same issue, please note that this controller has many reusable functions, i first get the raw image data from media promise (this raw data has EXIF data that i will read to get image orientation from the camera) i then convert this byteArray to BitmapData and then resize and scale as i need. One thing to note is that if you convert the raw image data to Bitmap data you will lose EXIF data so read it before you modify the image, hope this helps and i posted it here late i know but there's no other solution in the web and maybe someone will need this sometime. Cheers
SnapshotController.as
package controllers
{
import flash.display.BitmapData;
import flash.display.JPEGEncoderOptions;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IEventDispatcher;
import flash.events.MediaEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.media.CameraUI;
import flash.media.MediaPromise;
import flash.media.MediaType;
import flash.utils.ByteArray;
import flash.utils.IDataInput;
import mx.utils.Base64Encoder;
import classes.APIupload;
public class SnapshotController
{
private var cameraUI:CameraUI = new CameraUI();
private var dataSource:IDataInput;
private var tempDir:File = new File();
private var imageOrientation:int = 0 ;
public function SnapshotController()
{
}
public function LaunchCameraUI():void
{
if( CameraUI.isSupported ) {
trace( "Initializing camera..." );
cameraUI.addEventListener( MediaEvent.COMPLETE, imageSelected );
cameraUI.launch( MediaType.IMAGE );
} else {
trace( "CameraUI is not supported.");
}
}
private function imageSelected( event:MediaEvent ):void {
trace( "Media selected..." );
var imagePromise:MediaPromise = event.data;
dataSource = imagePromise.open();
if( imagePromise.isAsync ) {
trace( "Asynchronous media promise." );
var eventSource:IEventDispatcher = dataSource as IEventDispatcher;
eventSource.addEventListener( Event.COMPLETE, onMediaLoaded );
} else {
trace( "Synchronous media promise." );
readMediaData();
}
}
private function onMediaLoaded( event:Event ):void {
trace("Media load complete");
readMediaData();
}
private function readMediaData():void {
var imageBytes:ByteArray = new ByteArray();
dataSource.readBytes( imageBytes );
imageOrientation = getOrientation(imageBytes);
//saveImageFile(imageBytes);
//Saving this byteArray will save a big file with the EXIF in it.
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, onMediaPromiseLoaded);
loader.loadBytes(imageBytes);
}
private function onMediaPromiseLoaded(e:Event):void
{
trace("Media file loaded");
var base64Enc:Base64Encoder = new Base64Encoder();
var mpLoaderInfo:LoaderInfo = e.target as LoaderInfo;
mpLoaderInfo.removeEventListener(Event.COMPLETE, onMediaPromiseLoaded);
var scale:Number = 0.25;
var matrix:Matrix = new Matrix();
matrix.scale(scale, scale);
var jpgQuality:int = 80;
var bmd:BitmapData = new BitmapData(mpLoaderInfo.width*scale, mpLoaderInfo.height*scale);
bmd.draw(mpLoaderInfo.content,matrix,null,null,null,true);
var rotatedBMD:BitmapData = rotateBitmapData(bmd, imageOrientation);
var bytes:ByteArray = rotatedBMD.encode(new Rectangle(0,0, rotatedBMD.width , rotatedBMD.height), new JPEGEncoderOptions(jpgQuality), bytes);
saveImageFile(bytes); //this is the smaller file saved. it does not have EXIF data but you can write your own using AS3 eXIF class.
}
private function rotateBitmapData( bitmapData:BitmapData, degree:int = 0 ) :BitmapData
{
var newBitmap:BitmapData;
var matrix:Matrix = new Matrix();
matrix.rotate( degree * (Math.PI / 180) );
if ( degree == 90 ) {
newBitmap = new BitmapData( bitmapData.height, bitmapData.width, true );
matrix.translate( bitmapData.height, 0 );
} else if ( degree == -90 || degree == 270) {
newBitmap = new BitmapData( bitmapData.height, bitmapData.width, true );
matrix.translate( 0, bitmapData.width );
} else if ( degree == 180 ) {
newBitmap = new BitmapData( bitmapData.width, bitmapData.height, true );
matrix.translate( bitmapData.width, bitmapData.height );
}else if(degree == 0){
newBitmap = new BitmapData( bitmapData.width, bitmapData.height, true );
//matrix.translate( bitmapData.width, bitmapData.height );
}
newBitmap.draw( bitmapData, matrix, null, null, null, true )
return newBitmap;
}
private function saveImageFile(ba:ByteArray):void{
var now:Date = new Date();
var filename:String = "IMG" + now.fullYear + now.month + now.day + now.hours + now.minutes + now.seconds + ".jpg";
var temp:File = File.documentsDirectory.resolvePath( filename );
var stream:FileStream = new FileStream();
stream.open( temp, FileMode.WRITE );
stream.writeBytes( ba );
stream.close();
}
private function getOrientation(jpeg:ByteArray):int{
if (jpeg == null) {
return 0;
}
var offset:int = 0;
var length:int = 0;
while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) {
var marker:int = jpeg[offset] & 0xFF;
// Check if the marker is a padding.
if (marker == 0xFF) {
continue;
}
offset++;
// Check if the marker is SOI or TEM.
if (marker == 0xD8 || marker == 0x01) {
continue;
}
// Check if the marker is EOI or SOS.
if (marker == 0xD9 || marker == 0xDA) {
break;
}
// Get the length and check if it is reasonable.
length = pack(jpeg, offset, 2, false);
if (length < 2 || offset + length > jpeg.length) {
trace("Invalid length");
return 0;
}
// Break if the marker is EXIF in APP1.
if (marker == 0xE1 && length >= 8 &&
pack(jpeg, offset + 2, 4, false) == 0x45786966 &&
pack(jpeg, offset + 6, 2, false) == 0) {
offset += 8;
length -= 8;
break;
}
// Skip other markers.
offset += length;
length = 0;
}
if (length > 8) {
// Identify the byte order.
var tag:int = pack(jpeg, offset, 4, false);
if (tag != 0x49492A00 && tag != 0x4D4D002A) {
trace("Invalid byte order");
return 0;
}
var littleEndian:Boolean = (tag == 0x49492A00);
// Get the offset and check if it is reasonable.
var count:int = pack(jpeg, offset + 4, 4, littleEndian) + 2;
if (count < 10 || count > length) {
trace( "Invalid offset");
return 0;
}
offset += count;
length -= count;
// Get the count and go through all the elements.
count = pack(jpeg, offset - 2, 2, littleEndian);
while (count-- > 0 && length >= 12) {
// Get the tag and check if it is orientation.
tag = pack(jpeg, offset, 2, littleEndian);
if (tag == 0x0112) {
// We do not really care about type and count, do we?
var orientation:int = pack(jpeg, offset + 8, 2, littleEndian);
switch (orientation) {
case 1:
return 0;
case 3:
return 180;
case 6:
return 90;
case 8:
return 270;
}
trace( "Unsupported orientation");
return 0;
}
offset += 12;
length -= 12;
}
}
trace( "Orientation not found");
return 0;
}
private function pack(bytes:ByteArray,offset:int,length:int,
littleEndian:Boolean):int {
var step:int = 1;
if (littleEndian) {
offset += length - 1;
step = -1;
}
var value:int = 0;
while (length-- > 0) {
value = (value << 8) | (bytes[offset] & 0xFF);
offset += step;
}
return value;
}
}
}
You can use Stage.deviceOrientation or Stage.orientation* to determine which way round the phone is.
*not sure if this one works on iOS
Is it the BitmapData result itself that you want to rotate (ie create a new BitmapData with rotated image) or just rotate a Bitmap on the display list?
Edit:
Ok, heres some code to rotate a BitmapData object:
function rotateBitmapData(angle:int, source:BitmapData):BitmapData
{
var newWidth:int = source.rect.width;
var newHeight:int = source.rect.height;
if (angle==90 || angle==270)
{
newWidth = source.rect.height;
newHeight = source.rect.width;
}
var newBmd:BitmapData = new BitmapData(newWidth, newHeight, source.transparent);
var tx:Number = 0;
var ty:Number = 0;
if (angle==90 || angle==180)
{
tx = newWidth;
}
if (angle==180 || angle==270)
{
ty = newHeight;
}
var matrix:Matrix = new Matrix();
matrix.createBox(1, 1, Math.PI*angle/180, tx, ty);
newBmd.draw(source, matrix);
return newBmd;
}
angle should be 0,90,180 or 270. It will return a new BitmapData object rotated by specified angle.
You can use StageOrientationEvent.ORIENTATION_CHANGING Event :
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGING, OrientationChangeHandler);
private function OrientationChangeHandler(e:StageOrientationEvent):void
{
switch (e.afterOrientation)
{
case StageOrientation.DEFAULT :
break;
case StageOrientation.ROTATED_RIGHT :
break;
case StageOrientation.ROTATED_LEFT :
break;
case StageOrientation.UPSIDE_DOWN :
break;
}
}
this can help you.