Createjs, how to use the mouse to draw a rectangle in the stage - createjs

sample
I want to use the mouse to draw a rectangle on the stage,but the rect can't change size.
this is code:
var planetText,selectBox=new createjs.Shape(),x, y, width, height;
stage.on('mousedown',function(event){
x = event.stageX;y = event.stageY;
selectBox.graphics.beginFill('#ffffff').drawRect(x, y, 100, 100);
selectBox.set({alpha:0.5});
planetText = new createjs.Text(x+','+y +','+0+','+0, "16px Arial", "#ffffff");
planetText.set({textAlign:'center',textBaseline:'middle',x:x,y:y});
//console.log(selectBox);
stage.addChild(selectBox);
stage.addChild(planetText);
stage.update();
});
stage.addEventListener('pressmove',function (event){
//console.log(event);
width = event.stageX - x;
height = event.stageY - y;
planetText.text = x + ',' + y +','+width+','+height;
//selectBox.set({w:width,h:height});
createjs.Tween.get(selectBox).to({width:width,height:height},100,createjs.Ease.bounceIn());
stage.update();
});
stage.on('pressup',function(event){
//console.log(self.selectBox);
createjs.Tween.get(selectBox).to({alpha:0},300,createjs.Ease.bounceIn());
stage.removeChild(selectBox);
stage.update();
});
how to fixed it , thx~

Have a look at this question/answer:
Change Color of Shape Mid Tween
Basically, there is no width/height of display objects in EaselJS, but you can change the actual drawing command any time. You can also change the scaleX/scaleY, and set the stroke to ignoreScale:
shape.graphics.setStrokeStyle(1, null, null, null, true); // 5th param
Further reading:
http://blog.createjs.com/new-command-approach-to-easeljs-graphics/
http://blog.createjs.com/update-width-height-in-easeljs/

Related

Align UI lements correctly in SkiaSharp (UWP)

I am trying to align a few buttons in a circular manner using SkiaSharp. My code looks like this
<skia:SKXamlCanvas x:Name="test" PaintSurface="Test_OnPaintSurface" />
Code behind
private void Test_OnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
// the canvas and properties
var canvas = e.Surface.Canvas;
// get the screen density for scaling
var display = DisplayInformation.GetForCurrentView();
var scale = display.LogicalDpi / 96.0f;
var scaledSize = new SKSize(e.Info.Width / scale, e.Info.Height / scale);
// handle the device screen density
canvas.Scale(scale);
// make sure the canvas is blank
canvas.Clear(SKColors.Transparent);
// draw some text
var paintSmallCircle = new SKPaint
{
Color = SKColors.CornflowerBlue,
IsAntialias = true,
Style = SKPaintStyle.Fill,
TextAlign = SKTextAlign.Center,
TextSize = 24
};
var paintCircle = new SKPaint
{
Color = SKColors.LightGray,
IsAntialias = true,
Style = SKPaintStyle.Fill,
TextAlign = SKTextAlign.Center,
TextSize = 24
};
var coord = new SKPoint(
scaledSize.Width / 2,
(scaledSize.Height) / 2);
canvas.DrawCircle(coord, 120, paintCircle);
int r = 100;
int angle = 90;
for (int i = 0; i < 12; i++)
{
double x1 = scaledSize.Width / 2 + r * Math.Cos(Math.PI * angle / 180.0) ;
double y1 = scaledSize.Height / 2 - r * Math.Sin(Math.PI * angle / 180.0) ;
var coord1 = new SKPoint((float) x1, (float)y1);
canvas.DrawCircle(coord1, 10, paintSmallCircle);
Button btn = new Button { Content = i, Height = 25, Width = 25, };
btn.SetValue(SKXamlCanvas.LeftProperty, coord1.X);
btn.SetValue(SKXamlCanvas.TopProperty, coord1.Y);
test.Children.Add(btn);
angle = angle - 30;
}
}
With this code, I am able to draw Blue circles correctly, but the button alignment comes wrong. How can I solve this issue?
right now my output looks like this
As you can see blue small circles are aligned correctly, but not buttons.
The expected behavior is that buttons come in the same place where blue circles are rendered
The point is you place the Button's Left & Top property.
When you use canvas.DrawCircle(coord1, 10, paintSmallCircle); to draw a Circle, the center point is coord1.
And you draw the Buttons Left & Top at the center point of the Circle.
So you can draw Button using
btn.SetValue(SKXamlCanvas.LeftProperty, coord1.X - 25 /2);
btn.SetValue(SKXamlCanvas.TopProperty, coord1.Y - 25 / 2);
25 is the Height and Width of your Button.
See the result.

Three.js, Camera rotation around a point

I'm trying to make a camera rotation and zoom around a point.
I don't want to use THREE.TrackBallControls because as i see, it only modify the fov when zooming, it is not what i want.
I'm using this simple equation : http://en.wikipedia.org/wiki/Sphere#Equations_in. To compute a point on the sphere, this point will be the position of the camera.
In three.js
var point = new THREE.Vector3(
radius * Math.cos(theta) * Math.sin(phi),
radius * Math.sin(theta) * Math.sin(phi),
radius * Math.cos(phi)
);
point.add(center);
To manipulate it, i use :
left mouse, for rotation : x coord === theta and y coord === phi
middle mouse, for zooming : zoom in/out === radius
It doesn't work well, especially for 'phi' rotation, maybe because it's define between 0 and PI.
Maybe there is a better solution using Quaternion.Slerp ?
edit :
My camera :
aspectRatio = container.offsetWidth / container.offsetHeight;
camera = new THREE.OrthographicCamera( -aspectRatio * viewSize / 2, aspectRatio * viewSize / 2, viewSize / 2, -viewSize / 2, -10, 10 );
camera.position.x = 0.004;
camera.position.y = 0.004;
camera.position.z = 0.004;
camera.lookAt(new THREE.Vector3(0, 0, 0))
scene.add(camera);
My OrbitControls :
controls = new THREE.OrbitControls ( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.keyPanSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
when using left mouse (rotation) the camera.position change.
when using middle mouse (zoom) the camera.position is still the same.
check made in the render function :
function render() {
// update camera controls
controls.update();
console.log(camera.position);
// actually render the scene
renderer.render( scene, camera );
}

Windows Store Apps: measure many pixels a TextBlock width will be?

Is there a way to measure many pixels will a TextBlock width will occupy?
let's say I have a string with length of 10 characters.
and I have a text block (without an assigned width value), I'll set the string to the Text property of that textblock.
Is there a way to measure the actual width of the textblock before adding it to the layout?
Until any control is added to the VisualTree, it has a Width and Height of zero.
You have two options, the first is this:
var newTextBlock = new TextBlock() { Opacity = 0.001, Text = "Test" };
RoutedEventHandler handler = null;
handler = (s, e) =>
{
newTextBlock.Loaded -= handler;
Panel.Children.Remove(newTextBlock);
};
newTextBlock.Loaded += handler;
Panel.Children.Add(newTextBlock);
And in the handler make all the operations you need, because now you have ActualWidth and ActualHeight.
The other one is using Win2D, you can do the following:
var test = new CanvasTextFormat() { WordWrapping = CanvasWordWrapping.WholeWord };
session.DrawText(largeloremipsum, new Rect(0, 0, 480, 0), Colors.Black, test);
var size = new CanvasTextLayout(canvasControl, text, test, 480, float.MaxValue);
But this is a more complex way, you can define the TextFormat for the Size, Font, etc.
Well, the only way I got is to create a new -in memory- text block- then assign it the same text, style and attributes as my target TextBlock, I assumed that my text block has a fixed height, to calculate it's desired width to fit the text, I made the following function:
private double CalculateDesiredWidth(string text, TextBlock targetText)
{
int MIN_TEXT_WIDTH=200;
//create a new text block to calculate how much space will the string occupy
TextBlock txt = new TextBlock();
txt.Text = text;
txt.FontSize = 16;
txt.Margin = targetText.Margin;
Size desiredSize = new Size(0, targetText.ActualHeight);
Rect desiredRect = new Rect(new Point(0, 0), desiredSize);
//measure the desired size
txt.Measure(desiredSize);
txt.Arrange(desiredRect);
//if the desired width is small, use the minimum default width
if (txt.ActualWidth <= MIN_TEXT_WIDTH)
return MIN_TEXT_WIDTH;
//calculate the desired area
double desiredArea = txt.ActualWidth * txt.ActualHeight;
//calculate the the width required to fit the desired area to my text box
double width = desiredArea / (targetText.Height - txt.Margin.Top - txt.Margin.Bottom);
return width;
}

Rotating camera around the X-axis (three.js)

I am trying to rotate the camera around to X-axis of the scene.
At this point my code is like this:
rotation += 0.05;
camera.position.y = Math.sin(rotation) * 500;
camera.position.z = Math.cos(rotation) * 500;
This makes the camera move around but during the rotation something weird happens and either the camera flips, or it skips some part of the imaginary circle it's following.
You have only provided a snippet of code, so I have to make some assumptions about what you are doing.
This code:
rotation += 0.05;
camera.position.x = 0;
camera.position.y = Math.sin(rotation) * 500;
camera.position.z = Math.cos(rotation) * 500;
camera.lookAt( scene.position ); // the origin
will cause the "flipping" you refer to because the camera is trying to remain "right side up", and it will quickly change orientation as it passes over the "north pole."
If you offset the camera's x-coordinate like so,
camera.position.x = 200;
the camera behavior will appear more natural to you.
Three.js tries to keep the camera facing up. When you pass 0 along the z-axis, it'll "fix" the camera's rotation. You can just check and reset the camera's angle manually.
camera.lookAt( scene.position ); // the origin
if (camera.position.z < 0) {
camera.rotation.z = 0;
}
I'm sure this is not the best solution, but if anyone else runs across this question while playing with three.js (like I just did), it'll give one step further.
This works for me, I hope it helps.
Rotating around X-Axis:
var x_axis = new THREE.Vector3( 1, 0, 0 );
var quaternion = new THREE.Quaternion;
camera.position.applyQuaternion(quaternion.setFromAxisAngle(x_axis, rotation_speed));
camera.up.applyQuaternion(quaternion.setFromAxisAngle(x_axis, rotation_speed));
Rotating around Y-Axis:
var y_axis = new THREE.Vector3( 0, 1, 0 );
camera.position.applyQuaternion(quaternion.setFromAxisAngle(y_axis, angle));
Rotating around Z-Axis:
var z_axis = new THREE.Vector3( 0, 0, 1 );
camera.up.applyQuaternion(quaternion.setFromAxisAngle(z_axis, angle));
I wanted to move my camera to a new location while having the camera look at a particular object, and this is what I came up with [make sure to load tween.js]:
/**
* Helper to move camera
* #param loc Vec3 - where to move the camera; has x, y, z attrs
* #param lookAt Vec3 - where the camera should look; has x, y, z attrs
* #param duration int - duration of transition in ms
**/
function flyTo(loc, lookAt, duration) {
// Use initial camera quaternion as the slerp starting point
var startQuaternion = camera.quaternion.clone();
// Use dummy camera focused on target as the slerp ending point
var dummyCamera = camera.clone();
dummyCamera.position.set(loc.x, loc.y, loc.z);
// set the dummy camera quaternion
var rotObjectMatrix = new THREE.Matrix4();
rotObjectMatrix.makeRotationFromQuaternion(startQuaternion);
dummyCamera.quaternion.setFromRotationMatrix(rotObjectMatrix);
dummyCamera.up.set(camera)
console.log(camera.quaternion, dummyCamera.quaternion);
// create dummy controls to avoid mutating main controls
var dummyControls = new THREE.TrackballControls(dummyCamera);
dummyControls.target.set(loc.x, loc.y, loc.z);
dummyControls.update();
// Animate between the start and end quaternions
new TWEEN.Tween(camera.position)
.to(loc, duration)
.onUpdate(function(timestamp) {
// Slerp the camera quaternion for smooth transition.
// `timestamp` is the eased time value from the tween.
THREE.Quaternion.slerp(startQuaternion, dummyCamera.quaternion, camera.quaternion, timestamp);
camera.lookAt(lookAt);
})
.onComplete(function() {
controls.target = new THREE.Vector3(scene.children[1].position-0.001);
camera.lookAt(lookAt);
}).start();
}
Example usage:
var pos = {
x: -4.3,
y: 1.7,
z: 7.3,
};
var lookAt = scene.children[1].position;
flyTo(pos, lookAt, 60000);
Then in your update()/render() function, call TWEEN.update();
Full example

Raphael -- How to fit the paper size to the browser's window size?

I want to change the paper(objects base) size of Raphael to fit the window resizing. [ using Firefox_13.0, Raphael_2.1.0, WindowsXP ]
If it is available, I would like to fit full-screen-mode.
==================================================
(steps)
I created the paper : paper = Raphael(0, 50, 800, 600); // initial width and height are 800 and 600.
I placed objects on the paper.
The window size of browser is checked by windowW = window.innerWidth and winnowH = window.innerHeight (on Firefox).
Scaling value is calculated by sv = windowW/800;
And scaling the paper by paper.scale(sv, sv);
==================================================
(the script)
window.onload = function () {
paper = Raphael(0, 50, 800, 600);
var background = paper.rect(0, 0, 800, 600).attr({fill:'#669999'});
// placing the objects
var circle = ...;
var rect = ...;
var ellipse = ...;
winowW = window.innerWidth;
winowH = window.innerHeight;
sv = winowW/800.
paper.scale(sv, sv);
}
==================================================
(result)
Though circle.scale(sv), rect.scale(sv, sv) and ellipse.scale(sv, sv) are valid, paper.scale(sv, sv) and background.scale(sv, sv) are not.
Why this case is happen ? I can get the window size by window.onresize = function() {...} on real-time. If there are better methods, please tell me.
Thanks,
I've succeeded by following two points:
1) "paper" itself is not manipulative object. I think we should look it as billboard.
2) use st = paper.set() and put the objects(circle, rect, ...) in it. And use st.scale(sv, sv, 0, 0);
* third and fourth parameter (0, 0) are very impotent.
(caution)
Serial resizing operation is not good for the function "scale()". Because each of resizing coefficient is piled as the
power of a number. So when one have done 1.1 times resizing operation 5 times, the scale will be 1.1^5.
Use setViewBox()
It should do the work
http://raphaeljs.com/reference.html#Paper.setViewBox