Image rotation in react-konva - react-konva

const bush1Image = new Image();
bush1Image.src = 'bush1.png';
bush1Image.rotate(90);
I need to rotate the image before using this.setState, so why the above code doesn't work?

<img> element created with new Image() doesn't have rotate method.
If you want to rotate it you have two ways:
1 Just rotate created Konva image with
<Image image={this.state.image} rotation={90} />
2 Or draw your image into an external canvas with required rotation, and then use that canvas as image property for Konva nodes
const bush1Image = new Image();
bush1Image.onload = () => {
const canvas = document.createElement('canvas');
// reversed size, because image will be rotated
canvas.width = bush1Image.height;
canvas.height = bush1Image.width;
const ctx = canvas.getContext('2d');
ctx.moveTo(0, canvas.widht);
ctx.rotate(90 * Math.PI / 180);
ctx.drawImage(bush1Image, 0, 0);
this.setState({ image: canvas })
}
bush1Image.src = 'bush1.png';

Related

Centering rectangle with size vs width/height properties

Why will the rectangle be centered, when setting the .size property?
var rect = new Rectangle();
rect.center = view.center;
rect.size = new Size(100, 200);
var path = new Path.Rectangle(rect);
path.fillColor = 'red';
Why will the rectangle not be centered, when setting the .width and .height properties?
var rect = new Rectangle();
rect.center = view.center;
rect.width = 100;
rect.height = 200;
var path = new Path.Rectangle(rect);
path.fillColor = 'red';
I was curious too and took a look to source code.
That happens because updating width / height directly only changes the point where bottomRight point should be. You only tells to "grow" in X and Y direction.
On the other hand, using ".size", which is a setter
(method here)
does more than that. It re-calculates X & Y based on an internal state called "_sx" & "_sy" (which will have 0.5 - center - as value by default. More here).
The key is here:
...
if (sx) {
this.x += (this.width - w) * sx;
}
if (sy) {
this.y += (this.height - h) * sy;
}
...
When "sx" and/or "sy" are 0.5 the rectangle centers (by default).

Rotate CSS 3D generated cube on drag

I have a 3D generated Cube made with CSS and it rotates perfectly when hovered on.
What I need is to add the draggable function to make it rotate with the mouse.
So far I have this:
JSFIDDLE
In order to make the hover work you need to uncomment the following CSS:
/*.box-scene:hover .box {
-webkit-transform: rotateY(-90deg);
}*/
I use draggable function from JQueryUI to try to make it work but somehow it is not working.
PS: I only need it to rotate on Y Axis.
Any help will be appresiated.
Ok so I got it working finally.
Apparently the error was that JSFiddle doesn't load external resources if they are requested without SSL.
The code that was loaded initially is actually correct.
The final working fiddle is:
JSFiddle
Final Javascript:
var offset = 0, startX;
var elem = document.getElementById("box");
$('#box-scene').on('mousedown', function (e) {
startX = e.pageX - offset;
})
.on('mouseup', function() {
startX = null;
})
.on('mousemove', function (e) {
if(startX) {
offset = e.pageX - startX;
elem.style['-webkit-transform'] = 'rotateY(-' + offset + 'deg)';
}
});
Thank you #Andrew and #Armand Maree for your help.
Hope this works for future reference.
I don't think draggable is what you want; that widget allows you to move objects around on the page. It looks like you want to be able to click the mouse and move it, and then see the cube rotate proportionally to how far you've moved the mouse. I don't know of a way to do that in pure CSS, I would suggest javascript similar to the following:
var dragging = false;
var originalX;
cube.mouseDown(function(e){
originalX = e.pageX;
dragging = true;
});
cube.mouseUp(function(e){
dragging = false;
});
cube.mouseMove(function(e){
if (dragging){
var DeltaX = e.pageX - originalX;
var rotation = CalculateRotationDegrees(DeltaX);
cube.css('transform',rotation);
}
});
In this example, the method CalculateRotationDegrees would take the distance the user has moved the mouse and figure out how far the cube should rotate based on that distance.
An idea would be to have a boolean variable that indicates whether the mouse button is pressed down. And then adjust the rotation when the mouse moves.
var mouseDown = false;
var mouseButtonDown = function () {
mouseDown = true;
}
var mouseButtonUp = function () {
mouseDown = false;
}
var mouseMove = function (event) {
if(mouseDown) {
// get mouse coordinates and do rotation in jquery
}
}
The HTML:
<div onmousedown="mouseButtonDown" onmouseup="mouseButtonUp" onmousemove="mouseMove"></div>

Specific .js files for stage, rectangle and other shapes to be used in Canvas

I want to currently work on Canvas in HTML5. I am new to canvas and want to start working on it. I am using easeljs for implementing canvas. But can anybody specify any particular .js file to implement Canvas. As when I am using this .js I am getting error : "0x800a1391 - Microsoft JScript runtime error: 'Stage' is undefined If there is a handler for this exception, the program may be safely continued."
Here my piece of code where we getting the above specified error. I have copied this code from internet only:
<script>
//EaselJS Stage instance that wraps the Canvas element
var stage;
//EaselJS Shape instance that we will animate
var circle;
//radius of the circle Graphics that we will draw.
var CIRCLE_RADIUS = 10;
//x position that we will reset Shape to when it goes off
//screen
var circleXReset;
//EaselJS Rectangle instance we will use to store the bounds
//of the Canvas
var bounds;
//initialize function, called when page loads.
function init() {
//check and see if the canvas element is supported in
//the current browser
////http://diveintohtml5.org/detect.html#canvas
if (!(!!document.createElement('canvas').getContext)) {
var wrapper = document.getElementById("canvasWrapper");
wrapper.innerHTML = "Your browser does not appear to support " +
"the HTML5 Canvas element";
return;
}
//get a reference to the canvas element
var canvas = document.getElementById("stageCanvas");
//copy the canvas bounds to the bounds instance.
//Note, if we resize the canvas, we need to reset
//these bounds.
//bounds = new Rectangle();
//bounds.width = canvas.width;
//bounds.height = canvas.height;
//pass the canvas element to the EaselJS Stage instance
//The Stage class abstracts away the Canvas element and
//is the root level display container for display elements.
stage = new Stage(canvas);
//Create an EaselJS Graphics element to create the
//commands to draw a circle
var g = new Graphics();
//stroke of 1 px
g.setStrokeStyle(1);
//Set the stroke color, using the EaselJS
//Graphics.getRGB static method.
//This creates a white color, with an alpha
//of .7
g.beginStroke(Graphics.getRGB(255, 255, 255, .7));
//draw the circle
g.drawCircle(0, 0, CIRCLE_RADIUS);
//note that the circle has not been drawn yet.
//the Graphics instance just has the commands to
//draw the circle.
//It will be drawn when the stage needs to render it
//which is usually when we call stage.tick()
//create a new Shape instance. This is a DisplayObject
//which can be added directly to the stage (and rendered).
//Pass in the Graphics instance that we created, and that
//we want the Shape to draw.
circle = new Shape(g);
//set the initial x position, and the reset position
circle.x = circleXReset = -CIRCLE_RADIUS;
//set the y position
circle.y = canvas.height / 2;
//add the circle to the stage.
stage.addChild(circle);
//tell the stage to render to the canvas
stage.update();
Ticker.setFPS(24);
//Subscribe to the Tick class. This will call the tick
//method at a set interval (similar to ENTER_FRAME with
//the Flash Player)
Ticker.addListener(this);
}
//function called by the Tick instance at a set interval
function tick() {
//check and see if the Shape has gone of the right
//of the stage.
if (circle.x > bounds.width) {
//if it has, reset it.
circle.x = circleXReset;
}
//move the circle over 10 pixels
circle.x += 8;
//re-render the stage
stage.update();
}
</script>
The only thing in the above code is just to add "createjs" before every even.
<script>
//EaselJS Stage instance that wraps the Canvas element
var stage;
//EaselJS Shape instance that we will animate
var circle;
//radius of the circle Graphics that we will draw.
var CIRCLE_RADIUS = 10;
//x position that we will reset Shape to when it goes off
//screen
var circleXReset;
//EaselJS Rectangle instance we will use to store the bounds
//of the Canvas
var bounds;
//initialize function, called when page loads.
function init() {
//check and see if the canvas element is supported in
//the current browser
////http://diveintohtml5.org/detect.html#canvas
if (!(!!document.createElement('canvas').getContext)) {
var wrapper = document.getElementById("canvasWrapper");
wrapper.innerHTML = "Your browser does not appear to support " +
"the HTML5 Canvas element";
return;
}
//get a reference to the canvas element
var canvas = document.getElementById("stageCanvas");
//copy the canvas bounds to the bounds instance.
//Note, if we resize the canvas, we need to reset
//these bounds.
//var s = new Shape();
//s.graphics.setStrokeStyle(1).beginStroke("#f00").drawRect(0, 0, canvas.width, canvas.height);
//stage.addChild(s);
bounds = new **createjs**.Rectangle();
bounds.width = canvas.width;
bounds.height = canvas.height;
//pass the canvas element to the EaselJS Stage instance
//The Stage class abstracts away the Canvas element and
//is the root level display container for display elements.
stage = new createjs.Stage(canvas);
//Create an EaselJS Graphics element to create the
//commands to draw a circle
var g = new **createjs**.Graphics();
//stroke of 1 px
g.setStrokeStyle(1);
//Set the stroke color, using the EaselJS
//Graphics.getRGB static method.
//This creates a white color, with an alpha
//of .7
g.beginStroke(createjs.Graphics.getRGB(255, 255, 255, .7));
//draw the circle
g.drawCircle(0, 0, CIRCLE_RADIUS);
//note that the circle has not been drawn yet.
//the Graphics instance just has the commands to
//draw the circle.
//It will be drawn when the stage needs to render it
//which is usually when we call stage.tick()
//create a new Shape instance. This is a DisplayObject
//which can be added directly to the stage (and rendered).
//Pass in the Graphics instance that we created, and that
//we want the Shape to draw.
circle = new createjs.Shape(g);
//set the initial x position, and the reset position
circle.x = circleXReset = -CIRCLE_RADIUS;
//set the y position
circle.y = canvas.height / 2;
//add the circle to the stage.
stage.addChild(circle);
//tell the stage to render to the canvas
stage.update();
createjs.Ticker.setFPS(24);
//Subscribe to the Tick class. This will call the tick
//method at a set interval (similar to ENTER_FRAME with
//the Flash Player)
createjs.Ticker.addListener(this);
}
//function called by the Tick instance at a set interval
function tick() {
//check and see if the Shape has gone of the right
//of the stage.
if (circle.x > bounds.width) {
//if it has, reset it.
circle.x = circleXReset;
}
//move the circle over 10 pixels
circle.x += 8;
//re-render the stage
stage.update();
}
</script>
I have marked as bold what we have to add before every function or event.

How come this image won't resize to fit the sprite?

I have this snippet of ActionScript code that is supposed to resize an image to fit the sprite: (as in rescale the image not just clip it)
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.Event;
public class Main extends Sprite
{
[Embed(source = 'img.png')]
private var TheImage:Class;
public static const TheImageWidth:Number = 1300;
public static const TheImageHeight:Number = 1300;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var image:Bitmap = new TheImage();
addChild(image);
image.scaleX = width / TheImageWidth;
image.scaleY = height / TheImageHeight;
}
}
}
Why isn't it working? The image isn't getting the right dimensions.
try
image.image.content.width = TheImageWidth;
image.image.content.height = TheImageHeight;
I had to do the something like this for imagery. We had issue with using MapImage and the MapImageLayer using ArcGIS for Flex 2.5. It seems to be fix in 3.5, Anyways I had to put an image into a sprite and paint the image based on the sprites width. If you want to scale the image to the sprite's dimensions you will need to use the Matrix API and use the scale method. The values passed into this should be the sprite's width divided by the image's width assuming the image is bigger than your sprite. Do the same with the height. Here is the code I used to accomplish the task.
const point:MapPoint = geometry as MapPoint;
sprite.x = toScreenX(map, point.x);
sprite.y = toScreenY(map, point.y);
// grab left x point for upper left then for lower right
// actua
var bottomLeftX:Number = toScreenX(map, geomertyWrapper.extent.xmin);
var topRightX:Number = toScreenX(map, geomertyWrapper.extent.xmax);
var bottomLeftY:Number = toScreenY(map, geomertyWrapper.extent.ymin);
var topRightY:Number = toScreenY(map, geomertyWrapper.extent.ymax);
iconWidth = Math.abs(topRightX - bottomLeftX);
iconHeight = Math.abs(topRightY - bottomLeftY);
sprite.width = iconWidth;
sprite.height = iconHeight;
var scaleX:Number = iconWidth/bitmapData.width;
var scaleY:Number = iconHeight/bitmapData.height;
m_matrix.a = 1.0;
m_matrix.d = 1.0;
m_matrix.scale(scaleX, scaleY);
m_matrix.tx = -iconWidth / 2;
m_matrix.ty = -iconHeight / 2;
//Values needed for drawing AlertNotificationInstance
sprite.graphics.beginBitmapFill(m_bitmapData, m_matrix, false, false);
sprite.graphics.drawRect(m_matrix.tx, m_matrix.ty,
iconWidth,
iconHeight);
sprite.graphics.endFill();
Hope this helps.

UIComponent's width and height have no effect on Sprite

Given this code:
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0xFFCC00);
circle.graphics.drawCircle(0, 0, 20);
var uiComp:UIComponent = new UIComponent();
uiComp.x = 100;
uiComp.y = 100;
uiComp.measuredHeight = 0;
uiComp.measuredWidth = 0;
uiComp.addChild(circle);
addChild(uiComp);
Why does changing the width and height of uiComp not affect the Sprite? Wouldn't UIComponent provide Sprite with a Graphics object, which limits that area where Sprite can draw?
As I said in the other thread, use unscaledWidth and unscaledHeight as the bounds for drawing.

Resources