I´ve been trying to enable tooltips on some imported 3D models, but it isnt working.
I already enabled tooltips in threbox, and I enabled tooltips in the options for the 3d element, as shown below.
tb = new Threebox(
map,
mbxContext,
{
realSunlight: true,
enableSelectingFeatures: true, //change this to false to disable fill-extrusion features selection
enableTooltips: true // change this to false to disable default tooltips on fill-extrusion and 3D models
}
);
var proptions = {
obj: './models/er.glb',
type: 'gltf',
scale: 10,
units: 'meters',
rotation: { x: 90, y: 0, z: 0 }, //default rotation
anchor: 'center',
adjustment: { x: 0, y: 0, z: 0.4 },
enableToltips: true
}
When i load the object i did the following:
tb.loadObj(proptions, function (model) {
model.setCoords(place);
model.addTooltip("A radar in the middle of nowhere", true);
model.setRotation({ x: 0, y: 0, z: Math.floor(Math.random() * 100) })
tb.add(model);
});
Although the object appears in the render, when I put the mouse above or i click it nothing shows the tooltip.
What am I missing ?
EDIT:
Following #jscastro response i changed the import in the top of my html page to <link href="./threebox-plugin/examples/css/threebox.css" rel="stylesheet" /> (the path is the correct to where the file is)
I also removed the enableTooltip: true in proptions.
Despite that it still does not work, Below i will leave the code as it is:
var origin = [-8.4, 41.20, 1];
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: origin,
zoom: 11,
pitch: 30,
antialias: true
});
//Things related to dateTime ommited
window.tb = new Threebox(
map,
map.getCanvas().getContext('webgl'),
{
realSunlight: true,
enableSelectingFeatures: true, //change this to false to disable fill-extrusion features selection
enableTooltips: true // change this to false to disable default tooltips on fill-extrusion and 3D models
}
);
map.on('style.load', async function () {
await importarLinhas();
// stats
// stats = new Stats();
// map.getContainer().appendChild(stats.dom);
animate();
map.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function (map, mbxContext) {
var eroptions = {
obj: './models/stationBus.fbx',
type: 'fbx',
scale: 0.01,
units: 'meters',
rotation: { x: 90, y: 20, z: 0 }, //default rotation
anchor: 'center',
adjustment: { x: -0.1, y: -0.1, z: 0.4 }
}
var poptions = {
obj: './models/Busstop.fbx',
type: 'fbx',
scale: 0.03,
units: 'meters',
rotation: { x: 90, y: 20, z: 0 }, //default rotation
anchor: 'center',
adjustment: { x: -0.1, y: -0.1, z: 0.1 }
}
var proptions = {
obj: './models/er.glb',
type: 'gltf',
scale: 2.7,
units: 'meters',
rotation: { x: 90, y: 0, z: 0 }, //default rotation
anchor: 'center',
adjustment: { x: 0, y: 0, z: 0.4 }
}
allNos.forEach((element) => { //For each one of a list that i fill first
//center of where the objects are
var place = [element.lng, element.lat, 0];
//cylinder as "base" for each one of the 3d Models
**//in here i cant do the Tooltip for the object**
const geometry = new THREE.CylinderGeometry(0.6, 0.6, 0.15, 32);
const material = new THREE.MeshLambertMaterial({ color: 0x5B5B5B });
const cylinder = new THREE.Mesh(geometry, material);
var baseOptions = {
obj: cylinder,
anchor: 'center',
adjustment: { x: 0, y: 0, z: -0.4 }
}
let base = tb.Object3D(baseOptions);
base.setCoords(place);
base.setRotation({ x: 90, y: 0, z: 0 })
//The text is just for the test
base.addTooltip("A radar in the middle of nowhere", true);
// base.castShadow = true;
window.tb.add(base);
//next i check what type of element it is
//it can only be one at the same time, so i use different models for each type
if (element.tipo === "p") {
window.tb.loadObj(poptions, function (model) {
model.setCoords(place);
model.addTooltip("A radar in the middle of nowhere", true);
model.setRotation({ x: 0, y: 0, z: Math.floor(Math.random() * 100) })
// model.castShadow = true;
window.tb.add(model);
});
}
if (element.tipo === "er") {
window.tb.loadObj(eroptions, function (model) {
model.setCoords(place);
model.addTooltip("A radar in the middle of nowhere", true);
model.setRotation({ x: 0, y: 0, z: Math.floor(Math.random() * 100) })
// model.castShadow = true;
window.tb.add(model);
});
}
if (element.tipo === "pr") {
window.tb.loadObj(proptions, function (model) {
model.setCoords(place);
model.addTooltip("A radar in the middle of nowhere", true);
model.setRotation({ x: 0, y: 0, z: Math.floor(Math.random() * 100) })
// model.castShadow = true;
window.tb.add(model);
});
}
});
},
render: function (gl, matrix) {
window.tb.setSunlight(date, origin.center);
window.tb.update();
}
})
map.addLayer(createCompositeLayer());
map.on('SelectedFeatureChange', onSelectedFeatureChange);
});
EDIT
I downloaded the page you shared in the chat, and I found many different issues and mistakes in your code.
1. You're using the wrong property to enable the selection of 3D objects, you use enableSelectingFeatures: true, //change this to false to disable fill-extrusion features selection, that is for Mapbox fill-extrusions features as said in the comment, but not for 3D models and objects, you have to use enableSelectingObjects: true. Only adding this, your problem with the tooltips on mouse over will be solved.
tb = new Threebox(
map,
mbxContext,
{
realSunlight: true,
enableSelectingObjects: true, //enable 3D models over/selection
enableTooltips: true // enable default tooltips on fill-extrusion and 3D models
}
);
But I have found other issues...
2. Your models scale initialization is too small, so you are hiding them below the big shapes you have created. The scale of your bus stop is scale: 0.01 and you define a place which is on the ground var place = [element.lng, element.lat, 0];, so it's hidden inside this CylinderGeometry
If you use scale: 1 you will see how your bus stops raises from the cylinder.
3. Same with the bus, you initialize them with scale: 1, which make them be hidden below the tubes and cylinders you have created. If you initialize them with scale: 10, and you elevate them 5 meters from the floor let truck = model.setCoords([lngB, latB, 4]); then you will see them raising.
4. Your models have a wrong initialization params mixing anchor and adjustment. anchor: center will center the pivotal center of your object properly, but then you apply negative values to x and y (which means decenter the object), and a z value that elevates the pivotal center adjustment: { x: -0.1, y: -0.1, z: 0.4 }. If you want your model on altitude use the 3rd coord in setCoords.
5. Your Cylinders and Tubes for the bus stops and bus lines are huge, and also they have the wrong init params, as you set them below the ground level -0.4 units adjustment: { x: 0, y: 0, z: -0.4 } (something supported by Mapbox but very bad resolved and producing weird effects. My recommendation would be to make them almost flat and at the ground level with no adjustment param. const geometry = new THREE.CylinderGeometry(0.6, 0.6, 0.01, 32);.
Summarizing, check all of these changes and let me know if it works.
Related
I have a ThreeJS scene with 16 objects that are supposed to end up in a 4 by 4 square grid. However, when I run the code, I only see one of the objects. I wrote a "dump" function to show me all the current XYZ values of the mesh objects's position property, which you can see below. The values all look good to me and I believe I should see a nice 4 by 4 square grid of objects given the positioning those values present.
I am using this ThreeJS Javascript file for ThreeJS:
https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js
I am using this code to create the mesh. The mesh is a cube with initially the side facing the camera is a cat image:
function makeCatCube(catImageUrl, textureBackSide, locX, locY, locZ) {
let errPrefix = '(makeCatCube) ';
// TODO: Should we use BoxBufferGeometry here for greater speed?
let cubeGeometry = new THREE.BoxGeometry(2, 0.1, 2);
let loader = new THREE.TextureLoader();
let materialArray = [
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
// Card face.
new THREE.MeshBasicMaterial( { map: loader.load(catImageUrl) } ),
// Card back side.
new THREE.MeshBasicMaterial(
{
map: textureBackSide
}
),
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
];
cube = new THREE.Mesh( cubeGeometry, materialArray );
if (g_ShowGraphicsDebugInfo) {
console.log(errPrefix + `Setting cube position to - X: ${locX}, Y: ${locY}, Z: ${locZ}`);
}
cube.position.set(locX, locZ, locY);
// TODO: Magic number to set the cube's X rotation so it looks flat facing the viewer.
cube.rotation.x = THREE.Math.radToDeg(60);
return cube;
}
Here is the main promise that builds all the game assets and shows where I add the mesh objects to the scene. The global g_aryCatCards array that contains all the cat cards that were built is prepared in a much larger module elsewhere. It contains each of the cat cards and each card has a meshThreeJS property that contains the ThreeJS mesh object (i.e. - the cube) that was built using the makeCatCube() function shown above :
function initializeGameAssets_promise(gameAreaDomElementID, threeJSCanvasAreaDomElementID, catCardWidth, catCardHeight) {
let errPrefix = '(initializeGameAssets_promise) ';
return new Promise(function(resolve, reject) {
try {
buildAllCatCards_promise(gameAreaDomElementID, threeJSCanvasAreaDomElementID, 1, catCardWidth, catCardHeight)
.then(result => {
g_Scene = new THREE.Scene();
g_Scene.background = new THREE.Color('yellow');
initCamera();
initRenderer();
for (let cardLabelKey in g_aryCatCards) {
let catCard = g_aryCatCards[cardLabelKey];
g_Scene.add(catCard.meshThreeJS);
}
let threeJSCanvasAreaDOMElement = document.getElementById(threeJSCanvasAreaDomElementID);
if (!threeJSCanvasAreaDOMElement)
throw new Error(errPrefix + `Unable to find the DOM element for the cat cards underlay table using ID: ${threeJSCanvasAreaDomElementID}`);
threeJSCanvasAreaDOMElement.appendChild(g_Renderer.domElement);
let catCardsTableElementOffset = getElementOffsetById(ELEMENT_ID_CAT_CARDS_TABLE);
threeJSCanvasAreaDOMElement.left = catCardsTableElementOffset.left;
threeJSCanvasAreaDOMElement.top = catCardsTableElementOffset.top;
// Start the rendering process.
render();
resolve(true);
})
.catch(err => {
reject(err);
});
}
catch(err) {
reject(err);
}
});
}
Here are the functions I use to initialize the camera and the renderer:
function initCamera() {
g_Camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10);
g_Camera.position.set(0, 3.5, 5);
g_Camera.lookAt(g_Scene.position);
}
function initRenderer() {
g_Renderer = new THREE.WebGLRenderer(
{
antialias: true
});
}
This dump shows the XYZ values of the mesh object's position property:
------------- DUMPING MESH POSITIONS -------------
[label: A1] - X: 2, Y: 0, Z: 2
[label: A2] - X: 176, Y: 0, Z: 2
[label: A3] - X: 350, Y: 0, Z: 2
[label: A4] - X: 525, Y: 0, Z: 2
[label: E1] - X: 2, Y: 0, Z: 364
[label: E2] - X: 176, Y: 0, Z: 364
[label: E3] - X: 350, Y: 0, Z: 364
[label: E4] - X: 525, Y: 0, Z: 364
[label: L1] - X: 2, Y: 0, Z: 183
[label: L2] - X: 176, Y: 0, Z: 183
[label: L3] - X: 350, Y: 0, Z: 183
[label: L4] - X: 525, Y: 0, Z: 183
[label: X1] - X: 2, Y: 0, Z: 545
[label: X2] - X: 176, Y: 0, Z: 545
[label: X3] - X: 350, Y: 0, Z: 545
[label: X4] - X: 525, Y: 0, Z: 545
I really don't know what to do at this point to debug this problem. Can anyone give me some general tips on what to inspect, or what diagnostic code I could write to try and figure this out?
Your camera can only see 9 units deep
new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10);
but your objects are up to 545 units away
Try
const near = 1;
const far = 1000;
new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, near, far);
see
You also seem to have the camera looking in the wrong direction.
g_Camera.position.set(0, 3.5, 5);
g_Camera.lookAt(g_Scene.position);
AFAIK g_scene.position is 0, 0, 0 which means the camera is at z = 5 looking toward Z = 0 but your list of objects are almost all behind the camera.
Try
g_Camera.position.set(0, 3.5, -50);
g_Camera.lookAt(g_Scene.position);
As I understand I have to use one canvas for both mapbox Gl and p5.
But how to do this? And what if I have p5 animation will it overwrite the canvas with map?
Any example or hint? Thanks.
My code, but nothing serious
mapboxgl.accessToken = 'pk.***';
var mapGL = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
center: [-120.36603539685188, 50.68667605749022],
zoom: 11.6
});
var mainCanvas;
function setup() {
mainCanvas = createCanvas(720, 400, WEBGL);
}
function draw() {
background(102);
rotate(frameCount / 100.0);
rect(30, 20, 25, 25);
}
Different drawing libraries don't usually play nice with each other on the same canvas. You could try something like overlaying the P5.js canvas on top of the mapbox canvas.
Better yet, use a map library that's already compatible with P5.js, like Mappa or p5.tiledmap. That allows you to draw a map inside P5.js, which makes drawing on top of it much easier.
This is a very old question, but for whoever revisits this question looking for an option... nowadays this could be easily done with the latest version of threebox and a few lines of code. The result looks like this:
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoianNjYXN0cm8iLCJhIjoiY2s2YzB6Z25kMDVhejNrbXNpcmtjNGtpbiJ9.28ynPf1Y5Q8EyB_moOHylw';
var origin = [2.294514, 48.857475];
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/satellite-v9',
center: origin,
zoom: 18,
pitch: 60,
bearing: 0
});
map.on('style.load', function () {
map
.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function (map, mbxContext) {
window.tb = new Threebox(
map,
mbxContext,
{
defaultLights: true,
}
);
// import tower from an external glb file, downscaling it to real size
// IMPORTANT: .glb is not a standard MIME TYPE, you'll have to add it to your web server config,
// otherwise you'll receive a 404 error
var options = {
obj: '/3D/eiffel/eiffel.glb',
type: 'gltf',
scale: 0.01029,
units: 'meters',
rotation: { x: 0, y: 0, z: 0 }, //default rotation
adjustment: { x: -0.5, y: -0.5, z: 0 } // place the center in one corner for perfect positioning and rotation
}
tb.loadObj(options, function (model) {
model.setCoords(origin); //position
model.setRotation({ x: 0, y: 0, z: 45.7 }); //rotate it
tb.add(model);
})
},
render: function (gl, matrix) {
tb.update();
}
});
})
</script>
I am trying to synchronize the move,resize and rotate operations of two fabric objects.
Consider there are two polygons - Poly1 and Poly2.
When Poly1 is modified in any manner, I need to apply the same modification on Poly2 and need to get the updated points for Poly2. Below is the approach being followed :
Get the transform matrices of Poly1 before and after modification.
Use them to get the matrix which modified the transform matrix from
its original to the modified state.
Multiply the matrix from the above step to the current transform
matrix of Poly2 to get the new transform matrix.
Use the new transform matrix and get the updated points and redraw
Poly2.
However, this approach is only working for move operation. If you do resize or rotate on Poly1, the same is not being applied correctly on Poly2. Please let me know what I am doing wrong here.
Thanks in advance for any help!!
Sample code - Blue is Poly1 and Red is Poly2
var oldPoly1Matrix;
var canvas = new fabric.Canvas('c');
var srcOptions = {
stroke: 'blue',
fill: '',
type: 'src'
};
var destOptions = {
stroke: 'red',
fill: '',
selectable: false,
hasControls: false,
hasBorders: false,
type: 'dest'
};
var poly1 = new fabric.Polygon([{
x: 60,
y: 40
}, {
x: 160,
y: 40
}, {
x: 160,
y: 140
}, {
x: 60,
y: 140
}], srcOptions);
var poly2 = new fabric.Polygon([{
x: 60,
y: 300
}, {
x: 160,
y: 300
}, {
x: 160,
y: 400
}, {
x: 60,
y: 400
}], destOptions);
canvas.add(poly1).add(poly2);
oldPoly1Matrix = poly1.calcTransformMatrix();
var originalPoly2Matrix = poly2.calcTransformMatrix();
poly2.matrix = originalPoly2Matrix;
function updatePoly2() {
var newPoly1Matrix = poly1.calcTransformMatrix();
var oldPoly1MatrixInverted = fabric.util.invertTransform(oldPoly1Matrix);
//newMatrix = oldMatrix * someMatrix
//therefore,someMatrix = newMatrix / oldMatrix = newMatrix * inverse(oldMatrix);
var diffMatrix = fabric.util.multiplyTransformMatrices(newPoly1Matrix, oldPoly1MatrixInverted);
var oldPoly2Matrix = poly2.matrix;
//Apply the same someMatrix to find out the new transform matrix for poly2.
var newPoly2Matrix = fabric.util.multiplyTransformMatrices(oldPoly2Matrix, diffMatrix);
var updatedPoints = poly2.get('points')
.map(function(p) {
return new fabric.Point(p.x - poly2.minX - poly2.width / 2, p.y - poly2.minY - poly2.height / 2);
})
.map(function(p) {
return fabric.util.transformPoint(p, newPoly2Matrix);
});
oldPoly1Matrix = newPoly1Matrix;
poly2.remove();
poly2 = new fabric.Polygon(updatedPoints, destOptions);
poly2.matrix = newPoly2Matrix;
canvas.add(poly2);
}
canvas {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.js"></script>
<canvas id="c" height="500" width="600"></canvas>
<button id="update" onclick="updatePoly2()">
Update red shape
</button>
jsfiddle - https://jsfiddle.net/btxp0ck6/
It is working fine after changing the translateX and translateY calculation from matrix mulplication to simple subtraction.Posting the code here for reference.
var oldPoly1Matrix;
var canvas = new fabric.Canvas('c');
var srcOptions = {
stroke: 'blue',
fill: '',
type: 'src'
};
var destOptions = {
stroke: 'red',
fill: '',
selectable: false,
hasControls: false,
hasBorders: false,
type: 'dest'
};
var poly1 = new fabric.Polygon([{
x: 60,
y: 40
}, {
x: 160,
y: 40
}, {
x: 160,
y: 140
}, {
x: 60,
y: 140
}], srcOptions);
var poly2 = new fabric.Polygon([{
x: 60,
y: 300
}, {
x: 160,
y: 300
}, {
x: 160,
y: 400
}, {
x: 60,
y: 400
}], destOptions);
canvas.add(poly1).add(poly2);
oldPoly1Matrix = poly1.calcTransformMatrix();
var originalPoly2Matrix = poly2.calcTransformMatrix();
poly2.matrix = originalPoly2Matrix;
function updatePoly2() {
var newPoly1Matrix = poly1.calcTransformMatrix();
var oldPoly1MatrixInverted = fabric.util.invertTransform(oldPoly1Matrix);
//newMatrix = oldMatrix * someMatrix
//therefore,someMatrix = newMatrix / oldMatrix = newMatrix * inverse(oldMatrix);
var diffMatrix = fabric.util.multiplyTransformMatrices(newPoly1Matrix, oldPoly1MatrixInverted,true);
diffMatrix[4] = newPoly1Matrix[4] - oldPoly1Matrix[4];
diffMatrix[5] = newPoly1Matrix[5] - oldPoly1Matrix[5];
var oldPoly2Matrix = poly2.calcTransformMatrix();
//Apply the same someMatrix to find out the new transform matrix for poly2.
var newPoly2Matrix = fabric.util.multiplyTransformMatrices(oldPoly2Matrix, diffMatrix,true);
newPoly2Matrix[4] = oldPoly2Matrix[4] + diffMatrix[4];
newPoly2Matrix[5] = oldPoly2Matrix[5] + diffMatrix[5];
var updatedPoints = poly2.get('points')
.map(function(p) {
return new fabric.Point(p.x - poly2.minX - poly2.width / 2, p.y - poly2.minY - poly2.height / 2);
})
.map(function(p) {
return fabric.util.transformPoint(p, newPoly2Matrix);
});
oldPoly1Matrix = newPoly1Matrix;
poly2.remove();
poly2 = new fabric.Polygon(updatedPoints, destOptions);
poly2.matrix = newPoly2Matrix;
canvas.add(poly2);
}
canvas {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.js"></script>
<canvas id="c" height="500" width="600"></canvas>
<button id="update" onclick="updatePoly2()">
Update red shape
</button>
Jsfiddle - https://jsfiddle.net/btxp0ck6/1/
I've created a group of cubes and I'm trying to figure out how to set the center so I can rotate them.
Here is the fiddle: https://jsfiddle.net/of1vfhzz/
Here I add the cubes:
side1 = new THREE.Object3D();
addCube({ name: 'side1topleft', x: -8.5, y: 7.5, z: 5 });
addCube({ name: 'side1topmiddle', x: -4, y: 7.5, z: 5 });
addCube({ name: 'side1topright', x: .5, y: 7.5, z: 5 });
addCube({ name: 'side1middleleft', x: -8.5, y: 3, z: 5 });
addCube({ name: 'side1middlemiddle', x: -4, y: 3, z: 5 });
addCube({ name: 'side1middleright', x: .5, y: 3, z: 5 });
addCube({ name: 'side1bottomleft', x: -8.5, y: -1.5, z: 5 });
addCube({ name: 'side1bottommiddle', x: -4, y: -1.5, z: 5 });
addCube({ name: 'side1bottomright', x: .5, y: -1.5, z: 5 });
scene.add(side1);
function addCube(data) {
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.x = data.x
cube.position.y = data.y
cube.position.z = data.z
cube.rotation.set(0, 0, 0);
cube.name = data.name;
side1.add(cube);
}
Then in render scene I rotate it around the y-axis, but I need to set the center. I tried translate, but I'm not getting it.
You want your group of meshes to rotate around the group center.
One option is to translate your mesh geometries so, as a collection, they are centered around the local origin.
If you don't want to do that, then you can create a grand-parent object pivot, and rotate that.
In your case, side1 is the parent of your child meshes. So use this pattern:
var pivot = new THREE.Group();
scene.add( pivot );
pivot.add( side1 );
side1.position.set( 4, - 3, - 5 ); // the negative of the group's center
In your animation loop, rotate the pivot;
pivot.rotation.z += 0.02;
fiddle: https://jsfiddle.net/of1vfhzz/1/
three.js r.77
I am using the following to change the style of the cursor when the mouse is over the circle:
circle1.on('mouseover', function () {
document.body.style.cursor = 'pointer';
});
circle1.on('mouseout', function () {
document.body.style.cursor = 'default';
});
It works great if I draw the circle using:
var circle1 = new Kinetic.Circle({
x: 512,
y: 512,
radius: 140,
stroke: '#00ffff',
strokeWidth: 4,
opacity: 0.5
});
However if I use:
var circle1 = new Kinetic.Circle({
drawFunc: function (canvas) {
var context1 = canvas.getContext();
context1.beginPath();
context1.arc(512, 512, this.getRadius(), 0, 2 * Math.PI, false);
context1.lineWidth = this.getStrokeWidth();
context1.strokeStyle = this.getStroke();
context1.stroke();
},
radius: 140,
stroke: '#00ffff',
strokeWidth: 15,
opacity: 0.5
});
It does not work! The cursor does not change its style; can we just use radius for mouse over. I would appreciate your suggestions, thanks in advance.
As I know you also need to define "drawHitFunc":
circle1.setDrawHitFunc(function (canvas) {
var context2 = canvas.getContext();
context2.beginPath();
context2.arc(100, 100, this.getRadius(), 0, 2 * Math.PI, false);
context2.closePath();
canvas.fillStroke(this);
});
Example: http://jsfiddle.net/lavrton/4DJdU/1/
no, you just need to correctly structure the drawFunc when creating custom shapes. Here's an example:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-shape-tutorial/
The problem is that you're using context.stroke(). You need to use canvas.stroke(this);
Anytime you actually render something, like strokes and fills, you need to use the canvas renderer object because it draws onto both the scene graph (what you see) and a specialized hit graph (used for event detection)
Docs:
http://kineticjs.com/docs/symbols/Kinetic.Canvas.php