As in example http://openlayers.org/dev/examples/graphic-name.html ...
I tried drawing my feature geometry as a flag but I realized that OpenLayers always uses the centroid of the geometry to place the feature at the specified point(latitude/longitude), whereas I wish the base of the flag to be placed at the specified point. Changing the value of Renderer.symbol did not make any effect neither did the graphicXOffset/graphicYOffset.
//my flag geometry
OpenLayers.Renderer.symbol.flag = [0, 0, 0, 140, 120, 140, 120, 60, 4, 60, 4, 0, 0, 0];
//create vector layer with default and select styles
myVectorLayer = new OpenLayers.Layer.Vector("Flag Geometry", {
renderers: renderer,
isBaseLayer: true,
graphicName: flag,
rotation: 180,
pointRadius: 15,
projection: new OpenLayers.Projection("EPSG:900913"),
styleMap: new OpenLayers.StyleMap({
"default": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
fillColor: "red",
strokeColor: "gray",
label: "${label}",
fontColor: "${favColor}",
fontSize: "12px",
fontFamily: "Courier New, monospace",
fontWeight: "bold",
labelYOffset: 2 //for flag
}, OpenLayers.Feature.Vector.style["default"])),
"select": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
}, OpenLayers.Feature.Vector.style["select"]))
})
});
var flag = new OpenLayers.Geometry.Point(latitude, longitude);
var flagFeature = new OpenLayers.Feature.Vector(flag);
myVectorLayer.addFeatures([flagFeature]);
To overcome this base point problem I changed the drawing method as follows:
myVectorLayer = new OpenLayers.Layer.Vector("Flag Geometry", {
renderers: renderer,
isBaseLayer: true,
projection: new OpenLayers.Projection("EPSG:900913"),
styleMap: new OpenLayers.StyleMap({
"default": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
fillColor: "red",
strokeColor: "gray",
label: "${label}",
fontColor: "${favColor}",
fontSize: "12px",
fontFamily: "Courier New, monospace",
fontWeight: "bold",
labelYOffset: 2 //for flag
}, OpenLayers.Feature.Vector.style["default"])),
"select": new OpenLayers.Style(OpenLayers.Util.applyDefaults({
}, OpenLayers.Feature.Vector.style["select"]))
})
});
var pointList = [];
var xs = [0, 0, 240, 240, 8, 8, 0];
var ys = [0, 280, 280, 120, 120, 0, 0];
for(var p=0; p<6; ++p) {
var newPoint = new OpenLayers.Geometry.Point(camera.get('latitude') + xs[p],
camera.get('longitude') + ys[p]);
pointList.push(newPoint);
}
pointList.push(pointList[0]);
var linearRing = new OpenLayers.Geometry.LinearRing(pointList);
var flagVector = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Polygon([linearRing]));
flagVector.attributes= {
label: 'label',
favColor: 'blue', //favorite color
align: "cm"
};
myVectorLayer.addFeatures([flagVector]);
This though will make the geometry zoom with map zoom not as the previous way.
Related
I am trying to draw lines around polygon, It should draw different colour of line from one point to the next, I am stuck on attaching line to the last point of polygon, There are also red circles which are being created successfully on polygon corners, Lines are being drawn when box is moved with mouse, using 'modified' event
JSFiddle here
The issue is here:
var lastPoint = (i=>polygon.points.length)?0:i+1;
var fromX = transformedPoints[lastPoint].x;
var fromY = transformedPoints[lastPoint].y;
return new fabric.Line([p.x, p.y, 25, fromX],{
JS code
var canvas = new fabric.Canvas("c", {
selection: false
});
var polygon = new fabric.Polygon([
new fabric.Point(150, 50),
new fabric.Point(250, 50),
new fabric.Point(250, 150),
new fabric.Point(150, 150)
]);
polygon.on("modified", function() {
document.getElementById("p").innerHTML = JSON.stringify(this);
var matrix = this.calcTransformMatrix();
var transformedPoints = this.get("points")
.map(function(p) {
return new fabric.Point(
p.x - polygon.pathOffset.x,
p.y - polygon.pathOffset.y);
})
.map(function(p) {
return fabric.util.transformPoint(p, matrix);
});
var circles = transformedPoints.map(function(p) {
return new fabric.Circle({
left: p.x,
top: p.y,
radius: 3,
fill: "red",
originX: "center",
originY: "center",
hasControls: false,
hasBorders: false,
selectable: false
});
});
document.getElementById("l").innerHTML = JSON.stringify(transformedPoints);
var colors = ['#E5097F', '#00A0E3', '#009846', '#FECC00', '#000', '#000', '#000'];
var lines = transformedPoints.map(function(p, i) {
document.getElementById("r").innerHTML = JSON.stringify(p);
var lastPoint = (i => polygon.points.length) ? 0 : i + 1;
var fromX = transformedPoints[lastPoint].x;
var fromY = transformedPoints[lastPoint].y;
document.getElementById("r").innerHTML = fromX + ' - > ' + fromY;
return new fabric.Line([p.x, p.y, 25, fromX], {
stroke: colors[i],
strokeWidth: 10,
hasBorders: false,
strokeDashArray: [8, 13]
});
});
side_a = new fabric.Line([150, 0, 50, 0], {
stroke: "red",
strokeWidth: 10,
hasBorders: false
});
this.canvas.clear().add(this).add(side_a).add.apply(this.canvas, lines).add.apply(this.canvas, circles).setActiveObject(this).renderAll();
});
canvas.add(polygon).renderAll();
UPDATE:
I am able to generate those lines by providing static values, for demo. before 'modified' event happens I have included some lines where it should go:
side_a = new fabric.Line([250, 50, 150, 50], {
stroke: "red",
strokeWidth: 10,
hasBorders: false
});
side_b = new fabric.Line([150, 150, 150, 50], {
stroke: "green",
strokeWidth: 10,
hasBorders: false
});
side_c = new fabric.Line([250, 150, 250, 50], {
stroke: "blue",
strokeWidth: 10,
hasBorders: false
});
side_d = new fabric.Line([150, 150, 260, 150], {
stroke: "green",
strokeWidth: 10,
hasBorders: false
});
canvas.add(polygon).add(side_a).add(side_b).add(side_c).add(side_d).renderAll();
Now just need to figure out how to create those dynamically. new JSFIDDLE HERE
UPDATE:
finally I was able to solve it by running in loop.
I was able to solve it using looping through the points and than generating lines:
var fromX = transformedPoints[i].x;
var fromY = transformedPoints[i].y;
return new fabric.Line([p.x, p.y , fromX, fromY], {
stroke: colors[i],
strokeWidth: 10,
hasBorders: true,
strokeDashArray: [20, 5]
});
I can create a stage and add shapes. However, if I use the Konva.Node.create command then the stage no longer displays newly added shapes.
In the code below, the first text 'Hello World !' is displayed, but the second text (after the Konva.Node.create) where it should display 'Hello World 2!' does not appear on the stage.
A working fiddle of this code is here.
Any help would be appreciated. Thanks
var stage = new Konva.Stage({
container : "container",
width : 400,
height : 300
});
var layer = new Konva.Layer();
stage.add(layer);
var text = new Konva.Text({
x: 10,
y: 48,
text:'Hello, World!',
align: 'left',
fontSize: 30,
fontFamily: 'Calibri',
fill: 'green',
draggable: true,
name: `text_${Date.now()}`
});
layer.add(text);
layer.draw();
Konva.Node.create(stage, "container");
var text2 = new Konva.Text({
x: 40,
y: 48,
text:'Hello, World 2!',
align: 'left',
fontSize: 30,
fontFamily: 'Calibri',
fill: 'green',
draggable: true,
name: `text_${Date.now()}`
});
layer.add(text2);
layer.draw();
Konva.Node.create overwrites the original stage in div container and creates a new copy. So your changes are not visible.
Probably you just need to remove that line.
It worked!
var stage = new Konva.Stage({
container : "container",
width : 400,
height : 300
});
var layer = new Konva.Layer();
stage.add(layer);
var text = new Konva.Text({
x: 10,
y: 48,
text:'Hello, World!',
align: 'left',
fontSize: 30,
fontFamily: 'Calibri',
fill: 'green',
draggable: true,
name: `text_${Date.now()}`
});
layer.add(text);
layer.draw();
var stage = Konva.Node.create(stage, "container");
var layer = stage.getLayers()[0];
var text2 = new Konva.Text({
x: 40,
y: 48,
text:'Hello, World 2!',
align: 'left',
fontSize: 30,
fontFamily: 'Calibri',
fill: 'green',
draggable: true,
name: `text_${Date.now()}`
});
layer.add(text2);
layer.draw();
i need an input type range in canvas for some purposes, i need to use that to change my fontsize. I already make the shape and also drag able, but the circle controller go beyond the line.
Just preview the bin to see what i mean. Jsbin
i want to limit the draging area to the line only like the input range works.
This is the documentation of KonvaJs library.
this is working, coded by Lavrton
Source
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var layer = new Konva.Layer();
var Track = new Konva.Line({
x: 44,
y: 55,
points: [60, 0, 0, 0, 0, 0, 0, 0],
stroke: '#BDC3C7',
strokeWidth: 6,
visible: true,
name: 'TrackLine',
lineCap: 'sqare',
lineJoin: 'sqare'
});
var TrackBall = new Konva.Circle({
x: 44,
y: 55,
stroke: '#D35400',
fill: '#ddd',
strokeWidth: 2,
name: 'TrackControl',
radius: 8,
draggable: true,
dragOnTop: false,
visible: true,
dragBoundFunc: function(pos) {
console.log(pos.x, Math.min(44, pos.x))
return {
x: Math.min(104, Math.max(44, pos.x)),
y: this.getAbsolutePosition().y
};
}
});
layer.add(Track);
layer.add(TrackBall);
stage.add(layer);
<script src="https://cdn.rawgit.com/konvajs/konva/0.10.0/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container" class="CanCont"></div>
I'm trying to increment text value everytime I click on the rectangle. What am I doing wrong ?
I don't understand because the call to my var works in drawText but doesn't in setLayer.
I looked at "setLayer" source code, who's working with '+=' syntax, but text is a String var and I don't want to make String concatenation.
value=1
$('canvas').drawText({
name: 'count',
fillStyle: '#0f0',
x: 20, y: 20,
fontSize: 22,
fontFamily: 'Verdana, sans-serif',
text: value
})
.drawRect({
strokeStyle: '#000',
fillStyle: '#ccc',
x: 20, y: 50,
width: 20,
height: 20,
layer: true,
click: function(layer) {
// Spin
$(this).animateLayer(layer, {
rotate: '+=180'
});
v=parseInt(value);
$(this).setLayer('count',{
text: value+1 // TRYING to increment over here
});
}})
Removing and recreating layers will make jCanvas unhappy. A much better solution would be to use setLayer() by parsing the current value to a number, incrementing that value, and passing it to the method:
$('canvas').drawText({
layer: true,
name: 'count',
fillStyle: '#0f0',
x: 20, y: 20,
fontSize: 22,
fontFamily: 'Verdana, sans-serif',
text: '1'
})
.drawRect({
strokeStyle: '#000',
fillStyle: '#ccc',
x: 20, y: 50,
width: 20,
height: 20,
layer: true,
click: function(layer) {
var $canvas = $(this),
countLayer = $canvas.getLayer('count');
// Spin
$canvas.animateLayer(layer, {
rotate: '+=180'
});
$canvas.setLayer(countLayer,{
text: parseFloat(countLayer.text) + 1
});
}
});
I found a workaround removing the layer and creating a new one at the same place.
function updateCount(param) {
$('canvas').removeLayer("count")
.drawText({
name: 'count',
fillStyle: '#0f0',
x: 250, y: 180,
fontSize: 22,
fontFamily: 'Verdana, sans-serif',
text: value,
layer: true,
maxWidth: 200
})
.drawLayers();
}
I'm use snapsvg library; Remove <use> element in IE11 doesn't work; How i can fix it?
c = Snap(400, 620);
c.rect(0, 0, 400, 620).attr({
fill : 'white',
stroke : 'black'
});
var pattern25x25;
var createDiodePattern = function () {
var p = c.group(),
selectedColor = "#ff6900",
fillColor = "#b7b7b7";
p.add(c.circle(12, 12, 30, 30).attr({fill: '#FFFFFF', stroke: '#FFFFFF', 'stroke-with': '1', opacity: '0.1'}));
p.add(c.rect(0, 0, 25, 25).attr({fill: fillColor, stroke: '#000000', 'stroke-with': '2'}));
p.add(c.rect(3, 5, 5, 2).attr({fill: '#FFDE00', stroke: '#000000', 'stroke-with': '1'}));
p.add(c.rect(16, 5, 5, 2).attr({fill: '#FFDE00', stroke: '#000000', 'stroke-with': '1'}));
p.add(c.circle(12, 12, 3, 3).attr({fill: '#FFFFFF', stroke: '#000000', 'stroke-with': '1'}));
pattern25x25 = p.toDefs();
};
createDiodePattern();
var items = [];
for(var i = 0; i< 10; i++){
var el = pattern25x25.use().attr({
x: i * 30,
y: i * 30
});
c.append(el);
items.push(el);
}
items.map(function(el){
el.click(function(){
el.remove();
});
})
Live Copy