Camera capture image rotate to portrait - Xamarin android - xamarin

I have a xamarin.android project which have a custom camera Preview. Whenever I initialize the camera , it will open as landscape default. So I changed the orientation from SurfaceChanged method like this.
private int setCameraDisplayOrientation(Activity mContext, int v)
{
var degrees = 0;
var orientation =0;
Display display = mContext.GetSystemService(Context.WindowService).JavaCast<IWindowManager>().DefaultDisplay;
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.GetCameraInfo(v, info);
var rotation = windowManager.DefaultDisplay.Rotation;
DisplayMetrics dm = new DisplayMetrics();
display.GetMetrics(dm);
int width = dm.WidthPixels;
int height = dm.HeightPixels;
//Natural orientation is portrait
if ((rotation == SurfaceOrientation.Rotation0 || rotation == SurfaceOrientation.Rotation180) && height > width ||
(rotation == SurfaceOrientation.Rotation90 || rotation == SurfaceOrientation.Rotation270) && width > height)
{
switch (rotation)
{
case SurfaceOrientation.Rotation0:
degrees = 90;
break;
case SurfaceOrientation.Rotation90:
degrees = 0;
break;
case SurfaceOrientation.Rotation180:
degrees = 270;
break;
case SurfaceOrientation.Rotation270:
degrees = 180;
break;
}
}
return (degrees);
}
It works fine. It will arrange both front and back camera in portrait.
The problem
When I capture photo, in some devices, it will store in landscape mode in some devices it will store portrait. I want the image to be in portrait mode no matter what. In order do that I tried to get the Exif data of image and rotate it to portrait mode accordingly. But in some devices like samsung, VIVO the orientation value gets as "0". I don't know what to do with that value. If I PreRotate 90 , then some devices will solve this issue, while other will save the photo upwards.
**Managing Rotation**
Android.Graphics.Bitmap loadAndResizeBitmap(string filePath)
{
Android.Graphics.Bitmap resizedBitmap = Android.Graphics.BitmapFactory.DecodeFile(filePath);
ExifInterface exif = null;
try
{
exif = new ExifInterface(filePath);
string orientation = exif.GetAttribute(ExifInterface.TagOrientation);
Android.Graphics.Matrix matrix = new Android.Graphics.Matrix();
switch (orientation)
{
case "1":
matrix.PreRotate(-90);
resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
matrix.Dispose();
matrix = null;
break;
case "3":
matrix.PreRotate(180);
resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
matrix.Dispose();
matrix = null;
break;
case "4":
matrix.PreRotate(180);
resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
matrix.Dispose();
matrix = null;
break;
case "5":
matrix.PreRotate(90);
resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
matrix.Dispose();
matrix = null;
break;
case "6": // portrait
matrix.PreRotate(90);
resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
matrix.Dispose();
matrix = null;
break;
case "7":
matrix.PreRotate(-90);
resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
matrix.Dispose();
matrix = null;
break;
case "8":
matrix.PreRotate(-90);
resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
matrix.Dispose();
matrix = null;
break;
case "0":
matrix.PreRotate(-90);
resizedBitmap = Android.Graphics.Bitmap.CreateBitmap(resizedBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height, matrix, false);
matrix.Dispose();
matrix = null;
break;
}
return resizedBitmap;
}
catch (IOException ex)
{
return null;
}
}
I got this Idea from Xamarin.Andoid Image rotation. But somehow I cant relay on it. What will be the problem? Should I pass Stream instead of file path? Does it due to the surfaceview rotation? How can I make the captured image portrait no matter what on any device? Any help is appreciated.

Only for Xamarin.Android, call it in shared project using dependency service
Get the Angle of rotation of image by this.
public int GetImageRotation(string filePath)
{
try
{
ExifInterface ei = new ExifInterface(filePath);
Orientation orientation = (Orientation)ei.GetAttributeInt(ExifInterface.TagOrientation, (int)Orientation.Undefined);
switch (orientation)
{
case Orientation.Rotate90:
return 90;
case Orientation.Rotate180:
return 180;
case Orientation.Rotate270:
return 270;
default:
return 0;
}
}
catch(Exception ex)
{
return 0;
}
}
Now Rotate the image according to the angle value you get.
I perform operation on stream rather than the actual file & return in the form of Byte array.
public byte[] RotateImage(System.IO.Stream imageStream, string filePath)
{
int rotationDegrees = GetImageRotation(filePath)
byte[] byteArray = new byte[imageStream.Length];
try
{
imageStream.Read(byteArray, 0, (int)imageStream.Length);
Bitmap originalImage = BitmapFactory.DecodeByteArray(byteArray, 0, byteArray.Length);
Matrix matrix = new Matrix();
matrix.PostRotate((float)rotationDegrees);
Bitmap rotatedBitmap = Bitmap.CreateBitmap(originalImage, 0, 0, originalImage.Width,
originalImage.Height, matrix, true);
using (MemoryStream ms = new MemoryStream())
{
rotatedBitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, ms);
return ms.ToArray();
}
}
catch(Exception ex)
{
return byteArray;
}
}
Let me know if it worked or not.

Related

Is there a way to draw a matter.js composite with p5?

I recently saw the matter.js on the coding train channel from 2017, I've managed to replicate the examples shown on those videos but now I wanted to do something more advanced. There is a Composite module called stack in the documentation used to create a soft body in the matter.js demos but I wonder if there is a way to draw this using p5 instead.
This is what I've gotten so far, any help is appreciated
I think the main issue with your code was that you weren't adding the Composite to the world. Here's a working example with a few other tweaks:
const {
Bodies,
Common,
Composites,
Constraint,
Engine,
Runner,
World
} = Matter;
var engine;
var world;
var particles = [];
var boundaries = [];
var composi1;
var composi2;
function setup() {
createCanvas(400, 400);
engine = Engine.create();
world = engine.world;
// Use a runner to actually run the simulation
const runner = Runner.create();
Runner.run(runner, engine);
// Add two composites so we can see them interact
composi1 = new softbodi(100, 50, 4, 4, 0, 0, true, 20);
composi2 = new softbodi(50, 300, 4, 2, 0, 0, true, 20);
boundaries.push(new Boundary(200, height, width, 50, 0));
}
function draw() {
background(51);
for (var i = 0; i < boundaries.length; i++) {
boundaries[i].show();
}
composi1.show();
composi2.show();
}
function softbodi(
xx,
yy,
columns,
rows,
columnGap,
rowGap,
crossBrace,
particleRadius) {
this.r = particleRadius;
this.composite = Composites.stack(
xx,
yy,
columns,
rows,
columnGap,
rowGap,
function(x, y) {
return Bodies.circle(x, y, particleRadius);
}
);
this.mesh = Composites.mesh(this.composite, columns, rows, crossBrace);
// Dont forget to add you composite to the world
World.add(world, this.composite);
this.show = function() {
var parr = [];
parr = Matter.Composite.allBodies(this.composite);
for (var i = 0; i < parr.length; i++) {
var pos = parr[i].position;
var angle = parr[i].angle;
push();
translate(pos.x, pos.y);
rotate(angle);
rectMode(CENTER);
strokeWeight(1);
stroke(255);
fill(127);
ellipse(0, 0, this.r * 2);
pop();
}
};
}
function Boundary(x, y, w, h, a) {
var options = {
friction: 0,
restitution: 0.95,
angle: a,
isStatic: true
};
this.body = Bodies.rectangle(x, y, w, h, options);
this.w = w;
this.h = h;
World.add(world, this.body);
this.show = function() {
var pos = this.body.position;
var angle = this.body.angle;
push();
translate(pos.x, pos.y);
rotate(angle);
rectMode(CENTER);
strokeWeight(1);
noStroke();
fill(0);
rect(0, 0, this.w, this.h);
pop();
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.17.1/matter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

iPhone image orientation wrong when resizing with SkiaSharp

I'm using the SKBitmap.Resize() method in SkiaSharp on a Xamarin.Forms project to resize images for display. The problem I'm encountering is when taking a photo on iOS, when a photo is taken in portrait, the image is displayed with the right side up. Taking a photo on Android, importing from the photo gallery on both an Android and iOS device maintains orientation, but taking a photo in iOS does not. If I don't resize the image using SkiaSharp (just display the image without any resizing), then the image displays with the proper orientation. However that is not a solution as the images need to be resized. Below is my code -
private byte[] GetResizedImageData(string imageName)
{
float resizeFactor = 0.5f;
var filePath = PathUtil.GetImagePath(imageName);
var ogBitmap = SKBitmap.Decode(filePath);
float fWidth = ogBitmap.Width * resizeFactor;
int width = (int) Math.Round(fWidth);
float fHeight = ogBitmap.Height * resizeFactor;
int height = (int) Math.Round(fHeight);
if (height >= 4096 || width >= 4096)
{
width = width * (int)resizeFactor;
height = height * (int)resizeFactor;
}
var scaledBitmap = ogBitmap.Resize(new SKImageInfo( width, height), SKBitmapResizeMethod.Box);
var image = SKImage.FromBitmap(scaledBitmap);
var data = image.Encode(SKEncodedImageFormat.Jpeg, 100);
return data.ToArray();
}
PathUtil.GetImagePath() is just a helper to get platform-specific paths for where the photos are being stored.
For those with the same issue I did the following and would gladly accept input on improvements.
public static SKBitmap HandleOrientation(SKBitmap bitmap, SKCodecOrigin orientation)
{
SKBitmap rotated;
switch (orientation)
{
case SKCodecOrigin.BottomRight:
using (var surface = new SKCanvas(bitmap))
{
surface.RotateDegrees(180, bitmap.Width / 2, bitmap.Height / 2);
surface.DrawBitmap(bitmap.Copy(), 0, 0);
}
return bitmap;
case SKCodecOrigin.RightTop:
rotated = new SKBitmap(bitmap.Height, bitmap.Width);
using (var surface = new SKCanvas(rotated))
{
surface.Translate(rotated.Width, 0);
surface.RotateDegrees(90);
surface.DrawBitmap(bitmap, 0, 0);
}
return rotated;
case SKCodecOrigin.LeftBottom:
rotated = new SKBitmap(bitmap.Height, bitmap.Width);
using (var surface = new SKCanvas(rotated))
{
surface.Translate(0, rotated.Height);
surface.RotateDegrees(270);
surface.DrawBitmap(bitmap, 0, 0);
}
return rotated;
default:
return bitmap;
}
And then use the following to get the original orientation.
// TODO: Improve this.. I do not know how to "reset"
// the inputStream, so new it up twice. :/
using (var inputStream = new SKManagedStream(imageIn))
{
using (var codec = SKCodec.Create(inputStream))
{
orientation = codec.Origin;
}
}
.......
Then
SKBitmap orientedWExif = HandleOrientation(resized, orientation);
SkiaSharp didn't actually provide a method for me to manipulate and change the orientation of the image. In the end I ended up altering the orientation as I captured and saved the image using platform specific code.
Thank you #ttugates Your answer helped me to fix issue with the orientation rotation. Just want to update your answer as there is some deprecated code.
using (var inputStream = new SKManagedStream(await file.ReadAllStreamAsync()))
{
using (var codec = SKCodec.Create(inputStream))
{
orientation = codec.EncodedOrigin;
}
}
public static SKBitmap HandleOrientation(SKBitmap bitmap, SKEncodedOrigin orientation)
{
SKBitmap rotated;
switch (orientation)
{
case SKEncodedOrigin.BottomRight:
using (var surface = new SKCanvas(bitmap))
{
surface.RotateDegrees(180, bitmap.Width / 2, bitmap.Height / 2);
surface.DrawBitmap(bitmap.Copy(), 0, 0);
}
return bitmap;
case SKEncodedOrigin.RightTop:
rotated = new SKBitmap(bitmap.Height, bitmap.Width);
using (var surface = new SKCanvas(rotated))
{
surface.Translate(rotated.Width, 0);
surface.RotateDegrees(90);
surface.DrawBitmap(bitmap, 0, 0);
}
return rotated;
case SKEncodedOrigin.LeftBottom:
rotated = new SKBitmap(bitmap.Height, bitmap.Width);
using (var surface = new SKCanvas(rotated))
{
surface.Translate(0, rotated.Height);
surface.RotateDegrees(270);
surface.DrawBitmap(bitmap, 0, 0);
}
return rotated;
default:
return bitmap;
}
}
Workable solution for resize and handle orientation
public class ImageResizer : IImageResizer
{
private const int Quality = 75;
public byte[] Resize(byte[] data, int newWidth, int newHeight)
{
using (var inputStream = new SKMemoryStream(data))
{
using (var codec = SKCodec.Create(inputStream))
{
using (var original_old = SKBitmap.Decode(codec))
{
int sourceWidth = original_old.Width;
int sourceHeight = original_old.Height;
float nPercentW = ((float) newWidth / (float) sourceWidth);
float nPercentH = ((float) newHeight / (float) sourceHeight);
float nPercent = nPercentH < nPercentW ? nPercentH : nPercentW;
int destWidth = (int) (sourceWidth * nPercent);
int destHeight = (int) (sourceHeight * nPercent);
using (SKBitmap original = original_old.Resize(new SKImageInfo(destWidth, destHeight), SKFilterQuality.Medium))
{
var useWidth = original.Width;
var useHeight = original.Height;
Action<SKCanvas> transform = canvas => { };
switch (codec.EncodedOrigin)
{
case SKEncodedOrigin.TopLeft:
break;
case SKEncodedOrigin.TopRight:
// flip along the x-axis
transform = canvas => canvas.Scale(-1, 1, useWidth / 2, useHeight / 2);
break;
case SKEncodedOrigin.BottomRight:
transform = canvas => canvas.RotateDegrees(180, useWidth / 2, useHeight / 2);
break;
case SKEncodedOrigin.BottomLeft:
// flip along the y-axis
transform = canvas => canvas.Scale(1, -1, useWidth / 2, useHeight / 2);
break;
case SKEncodedOrigin.LeftTop:
useWidth = original.Height;
useHeight = original.Width;
transform = canvas =>
{
// Rotate 90
canvas.RotateDegrees(90, useWidth / 2, useHeight / 2);
canvas.Scale(useHeight * 1.0f / useWidth, -useWidth * 1.0f / useHeight, useWidth / 2, useHeight / 2);
};
break;
case SKEncodedOrigin.RightTop:
useWidth = original.Height;
useHeight = original.Width;
transform = canvas =>
{
// Rotate 90
canvas.RotateDegrees(90, useWidth / 2, useHeight / 2);
canvas.Scale(useHeight * 1.0f / useWidth, useWidth * 1.0f / useHeight, useWidth / 2, useHeight / 2);
};
break;
case SKEncodedOrigin.RightBottom:
useWidth = original.Height;
useHeight = original.Width;
transform = canvas =>
{
// Rotate 90
canvas.RotateDegrees(90, useWidth / 2, useHeight / 2);
canvas.Scale(-useHeight * 1.0f / useWidth, useWidth * 1.0f / useHeight, useWidth / 2, useHeight / 2);
};
break;
case SKEncodedOrigin.LeftBottom:
useWidth = original.Height;
useHeight = original.Width;
transform = canvas =>
{
// Rotate 90
canvas.RotateDegrees(90, useWidth / 2, useHeight / 2);
canvas.Scale(-useHeight * 1.0f / useWidth, -useWidth * 1.0f / useHeight, useWidth / 2, useHeight / 2);
};
break;
}
var info = new SKImageInfo(useWidth, useHeight);
using (var surface = SKSurface.Create(info))
{
using (var paint = new SKPaint())
{
// high quality with antialiasing
paint.IsAntialias = true;
paint.FilterQuality = SKFilterQuality.High;
// rotate according to origin
transform.Invoke(surface.Canvas);
// draw the bitmap to fill the surface
surface.Canvas.DrawBitmap(original, info.Rect, paint);
surface.Canvas.Flush();
using (SKImage image = surface.Snapshot())
{
return image.Encode(SKEncodedImageFormat.Jpeg, Quality).ToArray();
}
}
}
}
}
}
}
}
}

i would like enhanced that code by loading textures from image and using textures in the scene

I'm french and newbie in open and webgl...nobody's perfect:)
I try to enhanced a code from Evan Wallace to make a little game.
But I try to load textures from images to texturing object with no success...
An idea?
Thank you
here's the code:
function loadImage(url, callback) {
var image = new Image();
image.src = url;
image.onload = callback;
return image;
}
function loadImages(urls, callback) {
var images = [];
var imagesToLoad = urls.length;
// Called each time an image finished
// loading.
var onImageLoad = function() {
--imagesToLoad;
// If all the images are loaded call the callback.
if (imagesToLoad == 0) {
callback(images);
}
};
for (var ii = 0; ii < imagesToLoad; ++ii) {
var image = loadImage(urls[ii], onImageLoad);
images.push(image);
}
}
if (gl) {
loadImages([
"178.jpg",
"football.png",
], PathTracer);
}
function PathTracer(images) {
var vertices = [
-1, -1,
-1, +1,
+1, -1,
+1, +1
];
// create vertex buffer
this.vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// create framebuffer
this.framebuffer = gl.createFramebuffer();
// create textures
var type = gl.getExtension('OES_texture_float') ? gl.FLOAT : gl.UNSIGNED_BYTE;
this.textures = [];
for(var i = 0; i < 3; i++) {
this.textures.push(gl.createTexture());
gl.bindTexture(gl.TEXTURE_2D, this.textures[i]);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 512, 512, 0, gl.RGB, type, null);
if (i == 2){
//gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, images); nothing append
//gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,new Uint8Array([0, 255, 255, 0])); with that screen blinking
}
}
gl.bindTexture(gl.TEXTURE_2D, null);
// create render shader
this.renderProgram = compileShader(renderVertexSource, renderFragmentSource);
this.renderVertexAttribute = gl.getAttribLocation(this.renderProgram, 'vertex');
gl.enableVertexAttribArray(this.renderVertexAttribute);
// objects and shader will be filled in when setObjects() is called
this.objects = [];
this.sampleCount = 0;
this.tracerProgram = null;
}

Enumeration values 'UIImageOrientationUp' and 'UIImageOrientationUpMirrored' not handled in switch

Fixing Warnings in Enumeration values 'UIImageOrientationUp' and 'UIImageOrientationUpMirrored' not handled in switch
- (UIImage *)fixOrientation {
// No-op if the orientation is already correct
if (self.imageOrientation == UIImageOrientationUp) return self;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (self.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
}
switch (self.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
What chould I do ?
To fix this warning, You should simply add at the end of each switch:
default:break;

Why won't my canvas clear between animation frames?

I decided to start playing around with dart again today and for some reason I can't get my viewport to clear between frames. I've tried to use clearRect and fillRect to draw a white rectangle over the entire canvas element. Here is my code.
import 'dart:html';
void main() {
var canvasFun = new CanvasFun(query("#Game"));
}
class CanvasFun{
CanvasElement canvas;
num _width;
num _height;
Square square;
CanvasFun(this.canvas){
this.square = new Square(10,10, new Point(50,50));
requestRedraw();
}
void draw(num _){
var ctx = canvas.context2d;
//clear the viewport
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillStyle = "white";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
//draw the square
this.square.draw(ctx);
requestRedraw();
}
void requestRedraw() {
window.requestAnimationFrame(draw);
}
}
class Point {
num x, y;
Point(this.x, this.y);
}
class Square{
num width;
num height;
num vectorX;
num vectorY;
Point location;
Square(this.width, this.height, this.location){
vectorX = 1;
vectorY = 1;
}
void draw(CanvasRenderingContext2D context){
context.save(); //I thought this might fix the blue viewport problem
this.update(context);
context.rect(this.location.x, this.location.y, this.width, this.height);
context.fillStyle = "blue";
context.fill();
}
void update(CanvasRenderingContext2D context)
{
num xBound = context.canvas.width;
num yBound = context.canvas.height;
if((this.location.x + this.width) > xBound){
this.vectorX = -1;
}
else if(this.location.x < 0){
this.vectorX = 1;
}
if((this.location.y + this.height) > yBound){
this.vectorY = -1;
}
else if(this.location.y < 0){
this.vectorY = 1;
}
this.location.x += (this.vectorX * 10);
this.location.y += (this.vectorY * 20);
}
}
The resulting animation draws a rectangle at the correct location but as it moves about the canvas the previous instance of the rectangle is still drawn. I'd like the rectangle to only appear once on the canvas and to look like it is moving about the screen.
Here is a screenshot of the output (notice the blue square is never cleared):
I simplified your code to get it working:
In CanvasFun:
void draw(num _){
var ctx = canvas.context2d;
//clear the viewport
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
//draw the square
this.square.draw(ctx);
requestRedraw();
}
In Square:
void draw(CanvasRenderingContext2D context){
this.update(context);
context.fillStyle = "blue";
context.fillRect(this.location.x, this.location.y, this.width, this.height);
}
I'm not sure what the exact problem was with the original version though. :)

Resources