Bitmap too small for its content - image

I'm creating graphics by the code and placing them into a Bitmap. But they are higher than this Bitmap container.
import flash.display.*;
function getLine(){
var containerWidh:Number =enter code here 300;
var containerHeight:Number = 300;
var borderWidt:Number = 1;
var spriteWrap:Sprite = new Sprite();
var innerContainer:Sprite = new Sprite();
innerContainer.x = 0;
innerContainer.y = 0;
var line1:Shape = new Shape();
line1.graphics.lineStyle(5, 0x6F4356, 1, false, StageScaleMode.SHOW_ALL, CapsStyle.ROUND);
line1.graphics.moveTo(50, 5);
line1.graphics.lineTo(50, 800);
line1.graphics.endFill();
var line2:Shape = new Shape();
line2.graphics.lineStyle(5, 0x6F4356, 1, false, StageScaleMode.SHOW_ALL, CapsStyle.ROUND);
line2.graphics.moveTo(200, 290);
line2.graphics.lineTo(200, 300);
line2.graphics.endFill();
innerContainer.addChild(line1);
innerContainer.addChild(line2);
spriteWrap.addChild(innerContainer);
return spriteWrap;
}
var spriteWrap:Sprite = getLine();
var wrapForBitmap:Sprite = new Sprite();
var drawBitmap:BitmapData = new BitmapData(300, 300, true, 0x00ffaa);
var goOnStage:Bitmap = new Bitmap(drawBitmap);
wrapForBitmap.graphics.beginBitmapFill(drawBitmap);
wrapForBitmap.graphics.lineStyle(1, 0x6F7E84);
wrapForBitmap.graphics.drawRect(0, 0, 300, 300);
wrapForBitmap.graphics.endFill();
wrapForBitmap.x = 10;
wrapForBitmap.y = 10;
drawBitmap.draw(spriteWrap, new Matrix(1, 0, 0, 1, 0, 0));
wrapForBitmap.addChild(goOnStage);
stage.addChild(wrapForBitmap);

Yes of course. Than I redraw my Bitmap using my Sprite
MySprite.graphics.clear();
MySprite.graphics.beginBitmapFill(MyBitmap, new Matrix(1, 0, 0, 1, new_XPos, new_YPos), false, false);
MySprite.graphics.endFill();

Your Shape line1 is higher than your Bitmap's height (300):
line1.graphics.moveTo(50, 5); // begins at x = 50 and y = 5
line1.graphics.lineTo(50, 800); // begins at x = 50 and y = 800
With the following code, you will draw a line from the top to the bottom of your Bitmap:
line1.graphics.moveTo(50, 0);
line1.graphics.lineTo(50, 300);
If you want line1 to be visible without changing it's height, you have to change your Bitmap's height (800) by modifying the second argument of your BitmapData method:
var drawBitmap:BitmapData = new BitmapData(300, 800, true, 0x00ffaa);
You should modify at the same time your rectangle's height:
wrapForBitmap.graphics.drawRect(0, 0, 300, 800);

Related

Skia / SkiaSharp - Rotating shapes around their own vertical axis

I generate the scene above using the OnDraw method below:
protected override void OnDraw(SKCanvas canvas, int width, int height)
{
int i = 0;
int step = 0;
List<SKRect> rects = new List<SKRect>();
// get the 2D equivalent of the 3D matrix
var rotationMatrix = rotationView.Matrix;
// get the properties of the rectangle
var length = Math.Min(width / 6, height / 6);
canvas.Clear(EffectMedia.Colors.XamarinLightBlue);
foreach (var n in numbers)
{
var rect = new SKRect(0 + step, 0, 100 + step, 100);
rects.Add(rect);
step += 120;
}
//var sideHoriz = rotationMatrix.MapPoint(new SKPoint(0, 1)).Y > 0;
var sideVert = rotationMatrix.MapPoint(new SKPoint(1, 0)).X > 0;
var paint = new SKPaint
{
Color = sideVert ? EffectMedia.Colors.XamarinPurple : EffectMedia.Colors.XamarinGreen,
Style = SKPaintStyle.Fill,
IsAntialias = true
};
// first do 2D translation to the center of the screen
canvas.Translate((width - (120 * numbers.Count)) / 2, height / 2);
// The following line is disabled because it makes the whole canvas rotate!
// canvas.Concat(ref rotationMatrix);
foreach (var n in numbers)
{
canvas.RotateDegrees((float)-3);
canvas.DrawRoundRect(rects[i], 30, 30, paint);
var shadow = SKShader.CreateLinearGradient(
new SKPoint(0, 0), new SKPoint(0, length * 2),
new[] { paint.Color.WithAlpha(127), paint.Color.WithAlpha(0) },
null,
SKShaderTileMode.Clamp);
var paintShadow = new SKPaint
{
Shader = shadow,
Style = SKPaintStyle.Fill,
IsAntialias = true,
BlendMode = SKBlendMode.SoftLight
};
foreach (var r in rects)
{
r.Offset(0, 105);
canvas.DrawRoundRect(r, 30, 30, paintShadow);
}
i++;
}
}
The idea is to make all those rounded boxes rotate (vertically) around their own axis.
I tried using SKPath + Transform, saving&restoring the rotationMatrix and/or the canvas but I can't find a way to have 6 rotating boxes ( canvas.Concat(ref rotationMatrix); makes the whole canvas rotate [*]).
Do you have any hint on how that can be achieved?
Note [*]: there's a call to rotationView.RotateYDegrees(5) every X milliseconds to update the rotationMatrix used by OnDraw.
This is what I'd like to achieve, any hints / directions would be really appreciated... :-)
The following piece of code rotates those shapes around their Z-axis:
canvas.Save();
canvas.RotateDegrees(degrees, rects[i].MidX, rects[i].MidY);
canvas.DrawRoundRect(rects[i], 30, 30, paint);
canvas.Restore();
Thanks

Three.VideoTexture stretches portrait video

I am using Three.VideoTexture(video) to load video on canvas. It's work perfectly fine with landscape videos. But when i tried to load a portrait video, on canvas video gets stretched.
var wrap3D = $("#" + threeJsPreviewHTMLElement);//.find(".wrap3d");
videoTexture = new THREE.VideoTexture(video);
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;
videoTexture.format = THREE.RGBFormat;
scene = new THREE.Scene();
var WIDTH = 520, HEIGHT = 520;
var domID = "videoContext";
if (!isDesktop) {
HEIGHT = $("#modalTumbler3d").height();
WIDTH = $("#modalTumbler3d").width();
domID = "videoContextDevice";
}
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(WIDTH, HEIGHT);
if (!wrap3D.find('#' + domID).length) {
wrap3D.append(renderer.domElement);
}
else {
wrap3D.find('#' + domID).replaceWith(renderer.domElement);
}
renderer.domElement.id = domID;
//Two CAMERA options - perspective is preferred
camera = new THREE.PerspectiveCamera(50, WIDTH / HEIGHT, .1, 20000);
camera.position.set(0, 0, 150);
scene.add(camera);
//Lights
var hemLight = new THREE.HemisphereLight(0x999999, 0xffffff, 1);
scene.add(hemLight);
var spotLight = new THREE.PointLight(0x555555);
spotLight.position.set(0, 15, -20);
scene.add(spotLight);
var spotLight = new THREE.PointLight(0x555555);
spotLight.position.set(0, -15, 20);
scene.add(spotLight);
//size and position of tumbler from camera
var Y = 0;
var A = 0;
var B = 0;
var scale = 1;
//cylinder for the movie preview
//var movieFrame = new THREE.CylinderGeometry(2, 1.8, 2.5, 50, 1, true, -1.59, Math.PI)
var movieFrame = new THREE.CylinderGeometry(1, 1, 2.5, 100, 3, true, -1.59, Math.PI)
//var movieFrame = new THREE.CylinderGeometry(2, 1.9, 2.5, 50, 1, true, -1.59, Math.PI)
var movieMaterial = new THREE.MeshBasicMaterial({ map: videoTexture, overdraw: true, side: THREE.DoubleSide });
var moviePlayer = new THREE.Mesh(movieFrame, movieMaterial);
moviePlayer.position.y = Y;
moviePlayer.rotation.y = A;
moviePlayer.renderOrder = 14;
moviePlayer.scale.set(scale, scale, scale);
scene.add(moviePlayer);
//control with the mouse or two finger pinch
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.minPolarAngle = 0; // radians
controls.maxPolarAngle = 2.5; // radians
controls.minDistance = 5;
controls.maxDistance = 10;
controls.enabled = false;
This is what i have tried to play video. I have used CylinderGeometry to load video in Cylinder form.
In this case, the texture will simply cover the whole CylinderGeometry. So any distortion you see is result of the aspect-ratio of the video not matching the aspect-ratio of the cylinder-fragment..
Based on your code you have there a height of 2.5 and a width of Math.PI, so your aspect-ratio is ~1.25. Now for a portrait-video (aspect-ratio <1) you need to adjust the geometry. (so for a 3:4 potrait-video you'd need a thetaLength of 1.875/radius instead of Math.PI).

SkiaSharp does not fill triangle with StrokeAndFill

I am trying to draw and fill a triangle. I referred an android - question How to draw filled triangle on android Canvas and did the following. It draws the triangle but it doesn’t fill it. How to get it filled? Also, is it possible to get it filled with a different color than the line color?
Xamarin Forms
private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
var surface = e.Surface;
var canvas = surface.Canvas;
canvas.Clear(SKColors.White);
var pathStroke2 = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.StrokeAndFill,
Color = new SKColor(244, 0, 110, 200),
StrokeWidth = 5
};
var path2 = new SKPath { FillType = SKPathFillType.EvenOdd };
path2.MoveTo(0, 0);
path2.LineTo(0, 140);
path2.MoveTo(0, 140);
path2.LineTo(140, 140);
path2.MoveTo(140, 140);
path2.LineTo(0, 0);
path2.Close();
canvas.DrawPath(path2, pathStroke2);
}
you don't need to use both LineTo() and MoveTo() - I suspect doing so is breaking the fill algorithm. Instead, just use
path2.MoveTo(0, 0);
path2.LineTo(0, 140);
path2.LineTo(140, 140);
path2.LineTo(0, 0);
path2.Close();
Removing unwanted MoveTo lines solved it, as per the comment from Jason.
Following is complete code.
private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
var surface = e.Surface;
var canvas = surface.Canvas;
canvas.Clear(SKColors.White);
var w = e.Info.Width;
var h = e.Info.Height;
SKColor[] colors;
colors = new SKColor[] {
new SKColor(244, 0, 110, 200), new SKColor(244, 0, 110, 220),
new SKColor(244, 0, 110, 240),new SKColor(244, 0, 110, 240),
new SKColor(244, 0, 100,240),
new SKColor(244, 0, 100),
new SKColor(255, 0, 70)
};
SKShader shaderLeft = SKShader.CreateLinearGradient(new SKPoint(0, 0), new SKPoint(w, h), colors, null, SKShaderTileMode.Clamp);
var paint = new SKPaint() { Shader = shaderLeft };
canvas.DrawPaint(paint);
var path2 = new SKPath { FillType = SKPathFillType.EvenOdd };
path2.MoveTo(0, 0);
path2.LineTo(0, 140);
path2.LineTo(140, 140);
path2.LineTo(0, 0);
path2.Close();
var pathStroke2 = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.StrokeAndFill,
Color = new SKColor(0, 0, 0, 30),
StrokeWidth = 5
};
using (var cf = SKColorFilter.CreateBlendMode(new SKColor(244, 0, 110, 200), SKBlendMode.DstIn))
{
var transparency = SKColors.White.WithAlpha(127);
pathStroke2.ColorFilter = cf;
// ... draw ...
canvas.DrawPath(path2, pathStroke2);
pathStroke2.ColorFilter = null;
}
var pathStroke3 = new SKPaint
{
IsAntialias = true,
Style = SKPaintStyle.StrokeAndFill,
Color = new SKColor(0, 0, 0, 30),
StrokeWidth = 5
};
var path3 = new SKPath { FillType = SKPathFillType.EvenOdd };
path3.MoveTo(170, 0);
path3.LineTo(170, 140);
path3.LineTo(300, 140);
path3.LineTo(170, 0);
path3.Close();
canvas.DrawPath(path3, pathStroke3);
}

Drawing custom shapes in Babylon.js

I have been searching all over the web for a way to draw custom 3d shapes in babylon.js. I would be grateful if somebody could provide a working example. For instance, a 3d irregular pentagon, triangle fan, or a wedge.
you can find a lot of info about parametric shapes in Babylon.js here:
http://doc.babylonjs.com/page.php?p=24847
And mainly for the ribbon here:
http://doc.babylonjs.com/page.php?p=25088
Here is a wedge using the ribbon object:
var createScene = function() {
var scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(0.8, 0.8, 0.8);
var camera = new BABYLON.ArcRotateCamera("Camera", 3 *Math.PI / 2, Math.PI / 2, 20, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, false);
// lights
var light = new BABYLON.HemisphericLight("hemi", new BABYLON.Vector3(0, 1, 0), scene);
light.groundColor = new BABYLON.Color3(0.2, 0.2, 0.5);
light.intensity = 0.6;
var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(-20, 0, -20), scene);
light2.diffuse = BABYLON.Color3.White();
light2.specular = BABYLON.Color3.Green();
light2.intensity = 0.6;
// material
var mat = new BABYLON.StandardMaterial("mat1", scene);
mat.alpha = 1.0;
mat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 1.0);
//mat.backFaceCulling = false;
mat.wireframe = true;
// tubular ribbon
path1 = [];
path2 = [];
path1.push( new BABYLON.Vector3(0, 0, 0) );
path2.push( new BABYLON.Vector3(0, 2, 0) );
path1.push( new BABYLON.Vector3(1, 0, 0) );
path2.push( new BABYLON.Vector3(1, 2, 0) );
path1.push( new BABYLON.Vector3(0, 0, 1) );
path2.push( new BABYLON.Vector3(0, 2, 1) );
var ribbon = BABYLON.Mesh.CreateRibbon("ribbon", [path1, path2], false, true, 0, scene);
ribbon.material = mat;
scene.registerBeforeRender(function(){
light2.position = camera.position;
});
return scene;};

html 5 pattern repeat for canvas

<canvas id="textureCanvas" width="3" height="1">what kind of cheap ass browser are you using? (I'm joking... something went wrong)</canvas>
window.onload = function () {
var mainCanvas = document.getElementById('mainCanvas');
var textureCanvas = document.getElementById('textureCanvas');
var mainContext = mainCanvas.getContext('2d');
var textureContext = textureCanvas.getContext('2d');
textureContext.fillStyle = 'grey';
textureContext.fillRect(0, 0, 1, 1);
textureContext.fillStyle = 'lightgrey';
textureContext.fillRect(1, 0, 1, 1);
textureContext.fillStyle = 'grey';
textureContext.fillRect(2, 0, 1, 1);
var pattern = mainCanvas.createPattern(textureCanvas, 'repeat');
mainCanvas.fillStyle = pattern;
mainCanvas.fillRect(0, 0, 198, 99);
};
I'm trying to use the first canvas as a pattern in the second canvas. It's an example from the Dummies guide. It's just a blank page that appears. I tried setting the background for the mainCanvas as green and it does show up. I guess I am a dummy.
The problem is that you are referring to mainCanvas and not mainContext when drawing on the mainCanvas. (I'm assuming you have a canvas element with and id of mainCanvas)
Change your code to:
var mainCanvas = document.getElementById('mainCanvas');
var textureCanvas = document.getElementById('textureCanvas');
var mainContext = mainCanvas.getContext('2d');
var textureContext = textureCanvas.getContext('2d');
textureContext.fillStyle = 'grey';
textureContext.fillRect(0, 0, 1, 1);
textureContext.fillStyle = 'lightgrey';
textureContext.fillRect(1, 0, 1, 1);
textureContext.fillStyle = 'grey';
textureContext.fillRect(2, 0, 1, 1);
var pattern = mainContext.createPattern(textureCanvas, 'repeat'); // <====
mainContext.fillStyle = pattern; // <====
mainContext.fillRect(0, 0, 198, 99); // <====
Example

Resources