In kinetic.js Issue with rotating a kinetic.group - javascript

I am using kinetic js. I am adding image, lines, etc to a kinetic.group and trying to rotate the group and it is getting rotated correctly. But after rotating the group, if I try to draw a line it is not correctly drawing on the present mouse position. It is drawing as it was before rotating.
The problem may be that if I rotate the group, the stage co-ordinates are not getting rotated it seems. What should I do to prevent this?
reference code---
var rootGroup = new Kinetic.Group({
x: stage.getWidth()/3,
y: stage.getWidth()/6,
draggable: true,
offset: [images.darthVader.width/2, images.darthVader.height/2]
});
rootGroup.add(line);
rootGroup.setRotationDeg(rootGroup.getRotationDeg()+90);
IN THIS WAY I AM DRAWING THE LINE.
var activeline = new Kinetic.Line({
points: [{x:0,y:0}],
stroke: "blue",
strokeWidth: 3,
lineCap: "round",
lineJoin: "round",
});
var mousePos = stage.getMousePosition();
points.push({
x: mousePos.x,
y: mousePos.y
});
activeline.setPoints(points);
rootGroup.add(activeline);

I'm not familiar with KineticJS, but it seems that you have to reset the transformation matrix back to its default state. OpenGL has the glLoadIdentity() method. Search for a similiar method on KineticJS.
See this tutorial
http://www.html5canvastutorials.com/advanced/html5-canvas-reset-transform-tutorial/

This should get you fairly close: http://jsfiddle.net/k4qB8/24/
// This rotates that added active line along with your group.
// This makes the draw direction correct
activeline.setRotationDeg(0-rootGroup.getRotationDeg());

Related

Openlayers how do you style drawn linestring different than what you are about to draw

I have a openlayers map which has draw interaction. When user starts drawing a linestring on the map, the portion of linestring drawn should look different than what the user would draw next.
In brief when user drops a point on the map, the line till that point should be block, without dash or any other styling options.
To illustrate what I am trying to do here goes the screenshot -
We can see user is about to add another point on the line so line till that point should turn block in blue color.
I have maintained the collection of points being added to the map, when user opts to delete the last point, it is being removed from the map but the last segment should also disappear from map. Can't find anything to achieve that.
Also I have added the ol.style.RegularShape() to display a square but it is displaying a circle instead don't know what I am doing wrong.
Here is jsbin link to my code - Draw interaction line style problem
You would need to use a style function for your draw style and divide the geometry into two parts for styling:
var drawStyle = function(feature) {
var styles = [];
if (feature.getGeometry().getType() == 'LineString') {
var coordinates = feature.getGeometry().getCoordinates();
styles.push(new ol.style.Style({
geometry: new ol.geom.LineString(coordinates.slice(-2)),
stroke: new ol.style.Stroke({
color: '#0000FF',
lineDash: [1, 20],
width: 5,
lineCap:'square',
lineJoin:'round',
lineDashOffset:10
})
}));
styles.push(new ol.style.Style({
geometry: new ol.geom.MultiPoint(coordinates),
image: new ol.style.RegularShape({
points: 4,
radius: 6,
angle: Math.PI / 4,
fill: new ol.style.Fill({
color: 'blue'
}),
stroke: new ol.style.Stroke({
color: 'blue'
}),
})
}));
if (coordinates.length > 2) {
styles.push(new ol.style.Style({
geometry: new ol.geom.LineString(coordinates.slice(0,-1)),
stroke: new ol.style.Stroke({
color: '#0000FF',
width: 2,
lineCap:'square',
lineJoin:'round'
})
}));
}
}
return styles;
}
To remove the last point from the line interaction simply use
line.removeLastPoint();
making sure var line; is declared so it is in the scope of the button click function

PaperJS updated centre not redrawing

I am using Paper.js to draw a circle on screen.
I update the centre position in update but the screen doesn't display draw the circle with the updated position.
class Ball{
this.graphics = new Path.Circle({
center: [200,200],
radius: 20,
fillColor: 'blue'
});
}
update(){
//test
this.graphics.center = [100,100]
}
}
var ball = new Ball();
//update
view.onFrame = function(event) {
ball.update();
}
The circle is always drawn on 200,200 no matter what values I update this.graphics.centre with.
I have also tried adding view.draw(); in view.onFrame() after ball.update() but it didn't change anything.
I have made sure the rest of the code is working since if I instead create a new Path.Circle() in ball.update() it draws a new circle on the correct position.

Google maps text for circles

Drawing a circle on a map is easy:
https://developers.google.com/maps/documentation/javascript/examples/circle-simple
But if I draw a circle around a point I also want to indicate to the user how big is the radius, is there a way to add text on the circle (for example on the perimeter) that indicate what the radius is?
The simple way for addit a good stylish text to google maps is use the google maps utilty and in your case yh js-map-label
https://github.com/googlemaps/js-map-label
see this sample page view-source:https://googlemaps.github.io/js-map-label/examples/maplabel.html
var mapLabel = new MapLabel({
text: 'Test',
position: new google.maps.LatLng(34.03, -118.235),
map: map,
fontSize: 35,
align: 'right'
});
mapLabel.set('position', new google.maps.LatLng(34.03, -118.235));
var marker = new google.maps.Marker();
marker.bindTo('map', mapLabel);
marker.bindTo('position', mapLabel);
marker.setDraggable(true);

Paper.js eraser tool made using layers and blendMode

I am making simple drawing app using Paper.js and Node.js. There are 2 layers:
- bottom layer with images
- top layer for drawing.
Layer with images is background to drawing layer.
I want to make a simple eraser tool which will erase drawing on a path. I'm trying to do it adding second path in my top layer which has blendMode set to "destination-out".
drawingLayer.activate();
path = new Path();
path.strokeColor = 'black';
path.strokeWidth = 5;
if (mode == "erase") {
path.strokeWidth = 15;
path.blendMode = 'destination-out';
}
My problem is that this "destination-out" path erases not only everything on top layer (drawing layer) but also everything on the bottom layer (images). Of course I want images to stay untouched by eraser. When I set some background in css for my page it is not erased by the eraser path.
Do you know a way to make eraser to modify one top layer while not modyfing bottom layer?
The solution is to activate the layer you want to erase in just before using the eraser tool, like this:
var firstLayer = paper.project.activeLayer; //This one is used to erase
var shapesLayer = new Layer(); // We don't want to erase on this one
so basically, when eraser tool is selected I do
firstLayer.activate();
Then when I want to draw shapes just activate the 'shapesLayer' the same way. This avoids the tool (the one used for erasing) touch anything from 'shapesLayer'
In order to do this, you have to encapsulate your drawings items and your eraser items into a group which has the blend mode source-over.
This way, the background items won't be affected by the eraser items destination-out blend mode.
Here's a simple sketch demonstrating this.
const backgroundCircle = new Path.Circle({
center: view.center,
radius: 50,
fillColor: 'orange'
});
const foregroundCircle = new Path.Circle({
center: view.center + 20,
radius: 50,
fillColor: 'blue'
});
const eraserCircle = new Path.Circle({
center: view.center + [10, 0],
radius: 50,
fillColor: 'black',
blendMode: 'destination-out'
});
const foreground = new Group({
children: [foregroundCircle, eraserCircle],
blendMode:'source-over'
});

Make kineticjs use existing canvas

I am attempting to use kinetic.js with an existing canvas. The problem is that the kinetic.js API requires that you specify the id of the container element and then kinetic.js creates a Kinetic.Stage (which creates and uses its own canvas).
For instance:
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 239,
y: 75,
width: 100,
height: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
// add the shape to the layer
layer.add(rect);
// add the layer to the stage
stage.add(layer);
</script>
I want to be able to use an existing canvas element with kinetic.js instead of it creating its own. Is this possible?
A similar question has been asked before, however it doesn't seem to provide a correct answer.
Any ideas? Thanks!
An html canvas is just a bunch of pixels.
You can convert those pixels into an image and then use that image as the source for a Kinetic.Image.
// create an image from the existing canvas
var canvas2Image=new Image();
canvas2Image.onload=function(){
// create a Kinetic.Image using that image
var kImage=new Kinetic.Image({
x:0,
y:0,
width:canvas2Image.width,
height:canvas2Image.height,
image:canvas2Image
});
}
canvas2Image.src=canvas.toDataURL();

Categories

Resources