With Kinetic, is it possible to set a mouseover on a text? The code below does not work. If a replace the Text by a Rectangle, it works fine.
...
var layer = new Kinetic.Layer();
var test = new Kinetic.Text({
x: 20,
y: 20,
text: "test",
textFill:"black"
});
test.on("mouseover", function(){
alert("mouseover");
});
layer.add(test);
Thank you for your help!
UPDATE:
Ok, I searched a little bit more and it seems that it is necessary to use pixel detection.
see this tutorial fore more details
The result is not perfect for the moment but it is better than nothing.
I have trouble dealing with a similar text behaviour and after diving in repository history I found that now Text has detectionType setted to 'pixel' by default.
Try to change your Text declaration like following :
var test = new Kinetic.Text({
x: 20,
y: 20,
text: "test",
textFill: 'black',
detectionType: 'path',
draggable: true
});
Related
I want to create a typing game, so my sprites need to be generated in run time, with "labels". a String become a sprite to be typed. Anyone knows how to do this?
You can insert a Q.UI.Text object into a sprite like this:
var Q = Quintus()
.include('Sprites, Scenes, UI')
.setup({ maximize: true })
Q.Sprite.extend('LabelSprite', {
init: function(p) {
this._super(p, {text: 'default text'});
}
});
Q.scene("level1",function(stage) {
var label_sprite = stage.insert(new Q.LabelSprite({
x: 150,
y: 50,
label_text: 'label-text in a sprite',
label_text_color: 'grey',
label_offset_x: 0,
label_offset_y: 0
}));
var label = stage.insert(new Q.UI.Text({
label: label_sprite.p.label_text,
color: label_sprite.p.label_text_color,
x: label_sprite.p.label_offset_x,
y: label_sprite.p.label_offset_y
}), label_sprite);
});
Q.stageScene("level1");
Here is the above code in jsfiddle to demonstrate.
Also, the Scenes page of the Quintus documentation has a section called "Inserting objects into a stage", which is somewhat related to the concept.
Hope that helps!
I am looking for an example application that takes user input and inserts it into a inside canvas with fabric.js. Is this possible? I haven't been able to find a lists in fabric.js example.
canvas.fillText does not accept HTML markup.
A Canvas is a bitmap, it has nothing to do with HTML markup.
You can control font style as described here.
There are libraries that convert XML markup into canvas.fillText calls, maybe you could adapt one.
I realized a better way to solve this issue was to draw a circle at the same height as the text, at radius 2, to emulate a bullet point. for anybody interested its easy as:
var EDU1 = new fabric.IText("SOME TEXT GOES HERE", {fontSize: 20, fontStyle:
'italic',fontFamily: 'Hoefler Text', left: 149, top: 390});
var bullet = new fabric.Circle({
radius: 2, fill: 'black', left: 135, top: 400
});
then group them together and you have a bullet point.
function ListStyle (textObject,type,canvas) {
var styles=['\u25CF','\u25C8','\u25D8','\u25BA','\u25CB','\u25A0','-'];
var allStyles={'bullet':'\u25CF','diamond':'\u25C8','invertedBullet':'\u25D8','triangularBullet':'\u25BA','disced':'\u25CB','squared':'\u25A0','dashed':'-','none':''};
var text = textObject.text;
var textArray = text.split('\n')
var tempStr = [];
textArray.forEach((text, i) => {
if(styles.includes(text.substr(0,1))){
tempStr.push(text.replace(text.substr(0,1),allStyles[type]));
}else{
tempStr.push(allStyles[type]+''+text);
}
})
textObject['text'] = tempStr.join('\n');
canvas.renderAll();
}
ListStyle (canvas.getObjects()[0],'diamond',canvas);
I am new to client-side programming. Thus far I've been writing only asp and php based solutions. But now I need to retrieve data from json and plot on a map (I don't know how to do that yet, but this is later).
After days of searching, I think OpenLayers can give me what I need.
I have gone through the Examples on dev.openlayers site, (such as this one http://dev.openlayers.org/releases/OpenLayers-2.13.1/examples/vector-features-with-text.html), and also searched (and found some) solutions on stackoverflow, but they don't offer solutions to my problems).
Please view what I've done so far:
http://www.nusantech.com/bangkuujian/openlayer.html
The canvas.js is as follows:
// create some sample features
var Feature = OpenLayers.Feature.Vector;
var Geometry = OpenLayers.Geometry;
var features = [
new Feature(new Geometry.Point(-220, -60),attributes = { name: "Mercury",align: "cm",xOffset:10,yOffset:50 }),
new Feature(new Geometry.Point(-70, 120),attributes = { name: "Venus" }),
new Feature(new Geometry.Point(0, 0),attributes = { name: "Earth" }),
new Feature(new Geometry.Point(160, -100),attributes = { name: "Mars",align: "cm",xOffset:10,yOffset:50 })];
// create rule based styles
var Rule = OpenLayers.Rule;
var Filter = OpenLayers.Filter;
var style = new OpenLayers.Style({
pointRadius: 10,
strokeWidth: 3,
strokeOpacity: 0.7,
strokeColor: "#ffdd77",
fillColor: "#eecc66",
fillOpacity: 1,
label : "${name}",
fontColor: "#f0f0f0",
fontSize: "12px",
fontFamily: "Calibri, monospace",
labelAlign: "${align}",
labelXOffset: "${xOffset}",
labelYOffset: "${yOffset}",
labelOutlineWidth : 1
},
{
rules: [
new Rule({
elseFilter: true,
symbolizer: {graphicName: "circle"}
})
]
});
var layer = new OpenLayers.Layer.Vector(null, {
styleMap: new OpenLayers.StyleMap({'default': style,
select: {
pointRadius: 14,
strokeColor: "#e0e0e0",
strokeWidth: 5
}
}),
isBaseLayer: true,
renderers: ["Canvas"]
});
layer.addFeatures(features);
var map = new OpenLayers.Map({
div: "map",
layers: [layer],
center: new OpenLayers.LonLat(50, 45),
zoom: 0
});
var select = new OpenLayers.Control.SelectFeature(layer);
map.addControl(select);
select.activate();
What I have problems with:
Label offset
In the samples, the labels should offset from the centre by labelXOffset: "(xvalue)", labelYOffset: "(yvalue)", but this is not happening in my page. Is there something I forgot?
Zoom-in
When I click the + button on the map, all the features look like they are zoomed in, however, the sizes of the features stay the same. How do I enlarge the features (circles) too?
Hit Detection
i) When I click on a circle, it is selected as designed. However, is it possible when I select a circle, I also change the right side (now there is a red "text here") and fill it up with html? Can you show me an example how to change the red "text here" to the label-name of the selected circle with a different colour?
ii) Secondly, after I select a circle, how do I add a label under all the other circles denoting the distance between each circle and the selected circle?
Thank you in advance, hopefully these questions are not too much.
I have another question about retrieving an array of coordinates from json to plot the circles, but I will do more research on that. If you can point me in the right direction with regards to this, it would be much appreciated too.
I know how to do them server-side asp or php, but client side is very new to me. However client-side can do all of this much-much faster and can reduce a lot of load.
Cheers,
masCh
I think I have managed to most of it.
Labels not offsetting
Not sure what I did, but I declared a WMS layer and made a few changes to offset and now it is offsetting correctly.
var wms = new OpenLayers.Layer.WMS("NASA Global Mosaic",
"http://hendak.seribudaya.com/starmap.jpg",
{
layers: "modis,global_mosaic",
}, {
opacity: 0.5,
singleTile: true
});
var context = {
getSize: function(feature) {
return feature.attributes["jejari"] / map.getResolution() * .703125;
}
};
var template = {
pointRadius: "${getSize}", // using context.getSize(feature)
label : "\n\n\n\n${name}\n${jarak}",
labelAlign: "left",
labelXOffset: "${xoff}",
labelYOffset: "${yoff}",
labelOutlineWidth : 0
};
var style = new OpenLayers.Style(template, {context: context});
And I declared xoff & yoff under new OpenLayers.Geometry.Point(x,y), { jejari:5, xoff: -10, yoff: -15 }
2) Zoom in on point features.
This was a weird problem. Anyway, I declared a radius called jejari as in the code above next to xoff and yoff. Then modified pointRadius from a static number to "${getSize}" And then added the getSize function to var template which retrieves the current radius. I think that was all I did for that. But the labels were running all over the place, I still haven't solved that.
3) Hit detection and changing another in html
This adds what happens to the once a point feature has been selected
layer.addFeatures(features);
layer.events.on({ "featureselected": function(e) {
kemasMaklumat('maklumat', "<FONT FACE='Calibri' color='#f0f0f0' size=5><center>"+
e.feature.attributes.name+
"<p>This is displayed text when a feature has been selected";
maklumat.style.color="black";
layer.redraw();
}
});
map.addLayers([layer]);
And in the html the and the kemasMaklumat function is declared as
<script type="text/javascript">
function kemasMaklumat(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
</script>
<td valign="top"><div id="maklumat" style="border-radius:25px; background-color:#000000;box-shadow: 8px 8px 4px #686868;">
Write Something Here<P>
</div></td>
The second part of this question was changing the labels of all the UNselected features, i.e. modifying attributes of all features that weren't the selected one. To do this, I added a for loop through all the features and check if it has the same label as the feature that was selected, this was done under the layer.events.on "featureselected" as was done in the above part 1 of this question.
layer.addFeatures(features);
layer.events.on({ "featureselected": function(e) {
kemasMaklumat('maklumat', "<FONT FACE='Calibri' color='#f0f0f0' size=5><center>"+
e.feature.attributes.name+
"<p>This is displayed text when a feature has been selected";
maklumat.style.color="black";
for (var i = 0, l = layer.features.length; i < l; i++) {
var feature = layer.features[i];
if (feature.attributes.name!=e.feature.attributes.name) {
feature.attributes.name="I was not selected"; }}
layer.redraw();
}
});
map.addLayers([layer]);
I have some text, that has a class in the form of "link variabletext" (where variabletext is unique to each link). I'm trying to set this up so that when I mouseover the text, the corresponding object changes color, using jQuery.
A jsFiddle of what I have: http://jsfiddle.net/hdJCn/
The code I'm using:
One
Two
Three
<div id="container"></div>
var stage = new Kinetic.Stage({
container: 'container'
});
var layer = new Kinetic.Layer();
var onecircle = new Kinetic.Ellipse({
x: 100,
y: 100,
radius: {
x: 50,
y: 50
},
strokeWidth: 1,
stroke: 'black'
});
layer.add(onecircle);
stage.add(layer);
$('.link').mouseover(function () {
var numclass = $(this).attr('class').split(' ')[1];
(numclass + 'circle').setStroke('orange');
});
The problem is that it says that the object has no method "setStroke". If I take that same object name and hardcode it (so onecircle.setStroke instead of the above) it works fine. I'm not sure why this is and so far am at a loss.
Figured it out. I had to convert the string to an object:
var obj = eval(numclass+'circle');
And then use obj.setStroke....
I'm new to JS and KineticJS, and was wondering if someone could help me understand how the Kinetic.Stage node works. I've used this tutorial as a starting place -- but would like to be able to append objects (such as new Kinetic.Text() or new Kinetic.Group()) to the existing stage on click of a button.
An example of what I'm trying to do is have a form next to the canvas that allows a user to enter text, click "go", and have the "text that they entered" appear inside the canvas.
I've tried to declare "var stage" inside the document.ready and in global scope, thinking that I could access the stage from within a function, for instance:
function writeTextToStage(stage) {
var text = new Kinetic.Text({
x: 190,
y: 15,
text: 'Simple Text',
fontSize: 30,
fontFamily: 'Calibri',
textFill: 'green'
});
var layer = new Kinetic.Layer();
layer.add(text);
stage.add(layer);
stage.draw();
}
window.onload = function(){
var stage = new Kinetic.Stage({
container: "designer",
width: 578,
height: 520
});
var go = document.getElementById('go');
go.addEventListener('mousedown', writeTextToCanvas(stage);
};
Anyways, if the "stage" object is declared within another function -- "initStage()", is it possible to get the stage node after it has been initialized in order to append things to it? I've tried accessing it via the DOM element, $('kineticjs-content').children()[0].
Please assist. The documentation on kineticjs.com is not very verbose.
Thanks!
You need to create the layer outside your function, then in your function just add the text to the layer...
function AddText() {
var text = new Kinetic.Text({
...
});
layer.add(text);
}