I would like add arrow to my canvas - user click on canvas, fabric draw line + triangle. Then, when user move mouse line is "moving" and arrow angle is changed. "Drawing mode" is end when mouse up. This works great, but positions and selection area are wrong.
I write that for mouse:down:
// Draw new arrow using move
canvas.fabric.on('mouse:down', function(options){
$scope.lineOptions = {
stroke: '#000',
selectable: true,
strokeWidth: '2',
padding: 5,
hasBorders: false,
hasControls: false,
//originX: 'top',
//originY: 'left',
lockScalingX: true,
lockScalingY: true
};
var zoomFactor = Math.pow(canvas.currentZoom, -1);
var x = (options.e.clientX - canvas.fabric._offset.left) * zoomFactor;
var y = (options.e.clientY - canvas.fabric._offset.top) * zoomFactor;
var points = [ 0, 0, 0, 0 ];
temp_line = new fabric.Line(points, $scope.lineOptions);
temp_arrow = new fabric.Triangle({
left: x,
top: y,
angle: -45,
originX: 'center',
originY: 'center',
width: 20,
height: 20,
fill: '#000'
});
arrowShape = new fabric.Group([ temp_line, temp_arrow ], {
left: x,
top: y
});
canvas.fabric.add(arrowShape);
});
Zoom factor is here negligible.
There is code for mouse:move:
canvas.fabric.on('mouse:move', function(o){
var pointer = canvas.fabric.getPointer(o.e);
arrowShape.item(0).set({ x2: pointer.x, y2: pointer.y });
arrowShape.item(1).set({ left: pointer.x, top: pointer.y });
x1 = arrowShape.item(0).get('x1');
y1 = arrowShape.item(0).get('y1');
x2 = arrowShape.item(0).get('x2');
y2 = arrowShape.item(0).get('y2');
angle = calcArrowAngle(x1, y1, x2, y2);
arrowShape.item(1).set('angle', angle + 90);
//arrowShape.item(0).setCoords();
//arrowShape.item(1).setCoords();
//arrowShape.setCoords();
canvas.fabric.renderAll();
});
function calcArrowAngle(x1, y1, x2, y2) {
var angle = 0,
x, y;
x = (x2 - x1);
y = (y2 - y1);
if (x === 0) {
angle = (y === 0) ? 0 : (y > 0) ? Math.PI / 2 : Math.PI * 3 / 2;
} else if (y === 0) {
angle = (x > 0) ? 0 : Math.PI;
} else {
angle = (x < 0) ? Math.atan(y / x) + Math.PI : (y < 0) ? Math.atan(y / x) + (2 * Math.PI) : Math.atan(y / x);
}
return (angle * 180 / Math.PI);
}
and for mouse:up:
canvas.fabric.on('mouse:up', function(o){
canvas.fabric.setActiveObject(arrowShape);
// My drawing mode
$scope.drawMode = false;
});
Adding works great, change direction works great, change angle works great... but group selection and line start point is wrong:
OriginX/originY are default, so they should be top/left.. but the aren't. Also, group selection area are wrong, too small for both shapes. I forgot about something... but about what?
Related
semi-pie progress, what i want
Hello guys. How can i implement this kind of semi-pie progress bar with highcharts?
I tried alot and my result show as below photo. i want to create dataLabels same as first photo. if there is any way, please let me know.
i use this code for datalables:
dataLabels: {
formatter: function() {
return this.y > 1 ? '<b>' + this.point.name + ': ' + this.y + '%</b>' : null;
}
my result
So I created a guideline with custome functionality how to render a dataLabel which is 'attaching' to the pie point via using the SVGRenderer feature.
See code below and the demo: https://jsfiddle.net/BlackLabel/23ybcdjm/ and the version with path: https://jsfiddle.net/BlackLabel/u843xnoe/
chart: {
events: {
render() {
let chart = this,
series = chart.series[0],
point1 = series.points[0],
point2 = series.points[1],
shape1 = point1.shapeArgs,
shape2 = point2.shapeArgs,
distance,
distance2 = 50,
PI = -Math.PI,
label1,
label2,
x1,
y1,
x2,
y2;
//check if label exist while resize
if (chart.label1) {
chart.label1.destroy()
}
if (chart.label2) {
chart.label2.destroy()
}
//set x and y positions for labels
x1 = shape1.x + (shape1.r * Math.cos(shape1.end));
y1 = shape1.y + (shape1.r * Math.sin(shape1.end));
x2 = shape2.x + shape2.r + distance2;
y2 = shape2.y + chart.plotTop;
//render label1
chart.label1 = chart.renderer.label('Actual: ' + point1.y, x1, y1)
.css({
color: '#FFFFFF'
})
.attr({
fill: 'rgba(0, 0, 0, 0.75)',
padding: 8,
zIndex: 6,
})
.add();
//render label2
chart.label2 = chart.renderer.label('Target: ' + point2.y, x2, y2)
.css({
color: '#FFFFFF'
})
.attr({
fill: 'rgba(0, 0, 0, 0.75)',
padding: 8,
zIndex: 6,
})
.add();
//find distance for label which is moving around the pie
if (shape1.end > PI && shape1.end <= 0.55 * PI) {
distance = -chart.label2.getBBox().width
} else if (shape1.end > 0.55 * PI && shape1.end <= 0.45 * PI) {
distance = -chart.label2.getBBox().width / 2
} else if (shape1.end > 0.5 * PI && shape1.end < 0.25 * PI) {
distance = chart.label2.getBBox().width / 3
} else if (shape1.end > 0.25 * PI && shape1.end <= 0) {
distance = chart.label2.getBBox().width / 2
}
label1 = chart.label1;
label2 = chart.label2;
//translate labels
label1.translate(label1.x + distance + chart.plotLeft, label1.y)
chart.label2.translate(chart.label2.x, chart.label2.y - chart.label2.getBBox().height)
}
}
},
API: https://api.highcharts.com/highcharts/chart.events.render
API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label
I have a canvas with a circle and a triangle with a line connecting them both. I'm attempting to use the triangle as an arrow. I'd like for the arrow to always point away from the center of the circle if either object is moved. I thought I could use the angle of the line to rotate the triangle but the results are unsatisfactory and I'm certain my approach is wrong.
Any suggestions or tips for solving this problem? In my linked JSFiddle you can move either object around and the angle of the triangle is rotated, but it's never quite right:
https://jsfiddle.net/zh1bkfs5/
const c = new fabric.Canvas('c');
c.preserveObjectStacking = true;
function radiansToDegrees (radians) {
return radians * 180 / Math.PI;
}
function calcAngle (opposite, adjacent) {
return radiansToDegrees(Math.atan(opposite / adjacent));
}
function syncObjects (e) {
const x1 = triangle.left;
const y1 = triangle.top;
const x2 = circle.left + circle.radius;
const y2 = circle.top + circle.radius;
line.set('x1', x1);
line.set('y1', y1);
line.set('x2', x2);
line.set('y2', y2);
const angle = calcAngle(y2 - y1, x1 - x2);
triangle.set('angle', -angle);
triangle.setCoords();
c.renderAll();
}
const circle = new fabric.Circle({
fill: 'black',
radius: 20,
top: 100,
left: 100,
hasBorders: false,
hasControls: false
});
const triangle = new fabric.Triangle({
fill: 'orange',
height: 20,
width: 20,
top: 50,
left: 120,
hasBorders: false,
hasControls: false,
originX: 'center',
originY: 'center'
});
const coords = [
triangle.left,
triangle.top,
circle.left + circle.radius,
circle.top + circle.radius
];
const line = new fabric.Line(coords, {
stroke: 'orange',
strokeWidth: 1,
selectable: false
});
c.add(circle, line, triangle);
c.on('object:moving', syncObjects);
Change the part of your syncObject function to this:
const x = x1 - x2;
const y = y2 - y1;
const angle = calcAngle(x, y);
if(x < 0 && y > 0 || x > 0 && y > 0) {
triangle.set('angle', angle);
} else if(x < 0 && y < 0) {
triangle.set('angle', 180 + angle);
} if(x > 0 && y < 0) {
triangle.set('angle', -180 + angle);
}
this should work. Your updated fiddle https://jsfiddle.net/zh1bkfs5/30/
I had my the values for "adjacent" and "opposite" flipped, after updating that I no longer needed to invert the angle. I'm now 99% there, just have a case where the triangle is sometimes flipped the wrong way but should be easy to fix at least my initial approach worked.
Update: https://jsfiddle.net/zh1bkfs5/1/
const c = new fabric.Canvas('c');
c.preserveObjectStacking = true;
function radiansToDegrees (radians) {
return radians * 180 / Math.PI;
}
function calcAngle (opposite, adjacent) {
return radiansToDegrees(Math.atan(opposite / adjacent));
}
function syncObjects (e) {
const x1 = triangle.left;
const y1 = triangle.top;
const x2 = circle.left + circle.radius;
const y2 = circle.top + circle.radius;
line.set('x1', x1);
line.set('y1', y1);
line.set('x2', x2);
line.set('y2', y2);
const angle = calcAngle(x1 - x2, y2 - y1);
triangle.set('angle', angle);
triangle.setCoords();
c.renderAll();
}
const circle = new fabric.Circle({
fill: 'black',
radius: 20,
top: 100,
left: 100,
hasBorders: false,
hasControls: false
});
const triangle = new fabric.Triangle({
fill: 'orange',
height: 20,
width: 20,
top: 50,
left: 120,
hasBorders: false,
hasControls: false,
originX: 'center',
originY: 'center'
});
const coords = [
triangle.left,
triangle.top,
circle.left + circle.radius,
circle.top + circle.radius
];
const line = new fabric.Line(coords, {
stroke: 'orange',
strokeWidth: 1,
selectable: false
});
c.add(circle, line, triangle);
c.on('object:moving', syncObjects);
I am trying to draw a arrow using a line and a triangle which is working fine.
Now, when I resize it , it still works fine and retains the triangle position correctly in order to form a arrow along with the line but when I try to rotate it , the arrow gets disturbed.
I have handled events to make it possible to work but I am missing something I guess.
Here's the fiddle to the work that has been done .
Code :
`
var calcArrowAngle = function(x1, y1, x2, y2) {
var angle = 0, x, y;
x = (x2 - x1);
y = (y2 - y1);
if (x === 0) {
angle = (y === 0) ? 0 : (y > 0) ? Math.PI / 2 : Math.PI * 3 / 2;
} else if (y === 0) {
angle = (x > 0) ? 0 : Math.PI;
} else {
angle = (x < 0) ? Math.atan(y / x) + Math.PI :
(y < 0) ? Math.atan(y / x) + (2 * Math.PI) : Math.atan(y / x);
}
return (angle * 180 / Math.PI + 90);
};
var logs = document.getElementById('logs');
var canvas = this.__canvas = new fabric.Canvas('c');
canvas.selection = false;
var x1=50, y1=50, x2=150, y2=100;
var line = new fabric.Line([x1, y1, x2, y2], {
stroke: 'blue',
opacity: 1,
strokeWidth: 2,
selectable: true,
left : x1,
top : y1
});
//line.setControlsVisibility({'tl' : true,'tr' : true,'bl' : true,'br' : true,'ml' : false, 'mt' : false,'mr' : false,'mb' : false,'mtr' : false});
var centerX = (line.x1 + line.x2) / 2;
var centerY = (line.y1 + line.y2) / 2;
var deltaX = line.left - centerX;
var deltaY = line.top - centerY;
var triangle = new fabric.Triangle({
left : line.left - 10/2,
top : line.top + 10,
fill : 'blue',
width : 20,
height : 20,
angle : calcArrowAngle(x2, y2, x1, y1),
selectable : false
});
canvas.add(line, triangle);
canvas.renderAll();
canvas.observe('object:scaling', function (e) {
var m = canvas.getActiveObject();
logs.innerHTML = m.x1 + ',' + m.y1 + ',' + m.x2 + ', ' + m.y2;
triangle.left = line.left - 10/2;
triangle.top = line.top + 10;
line.width *= line.scaleX;
line.height *= line.scaleY;
line.scaleY = line.scaleX = 1;
});
canvas.observe('object:moving', function (e) {
triangle.left = line.left - 10/2;
triangle.top = line.top + 10;
});
canvas.observe('object:rotating', function (e) {
triangle.left = line.left - 10/2;
triangle.top = line.top + 10;
});`
I've adapted some code to snap a line to a grid using Fabric.js, as in the code below. What I want is for it to instead be an arrow. I can't seem to get the arrowhead (triangle) to move properly. I kept breaking the code by trying to add a triangle as the arrowhead, so I removed all code attempting to add it. Please help me add the arrowhead, thank you!!
var canvas = new fabric.Canvas('c', { selection: false });
var grid = 50;
for (var i = 0; i < (600 / grid); i++) {
canvas.add(new fabric.Line([ i * grid, 0, i * grid, 600], { stroke: '#ccc', selectable: false }));
canvas.add(new fabric.Line([ 0, i * grid, 600, i * grid], { stroke: '#ccc', selectable: false }))
}
var line, isDown;
canvas.on('mouse:down', function(o){
canvas.remove(line);
isDown = true;
var pointer = canvas.getPointer(o.e);
var points = [ Math.round(pointer.x / grid) * grid, Math.round(pointer.y / grid) * grid, pointer.x, pointer.y ];
line = new fabric.Line(points, {
strokeWidth: 5,
fill: 'red',
stroke: 'red',
originX: 'center',
originY: 'center'
});
canvas.add(line);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
line.set({ x2: pointer.x, y2: pointer.y });
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
var pointer = canvas.getPointer(o.e);
isDown = false;
line.set({ x2: Math.round(pointer.x/ grid) * grid, y2: Math.round(pointer.y/ grid) * grid });
canvas.renderAll();
});
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="500" height="500" style="border:1px solid #ccc"></canvas>
Got 'em! For me, the trick was defining the center of the triangle following the method in this fiddle: http://jsfiddle.net/ug2gskj1/
left: line.get('x1') + deltaX;
top: line.get('y1') + deltaY;
where
centerX = (line.x1 + line.x2) / 2;
centerY = (line.y1 + line.y2) / 2;
deltaX = line.left - centerX;
deltaY = line.top - centerY;
window.onload = function() {
var canvas = new fabric.Canvas('c', {
selection: false
});
var grid = 50;
for (var i = 0; i < (600 / grid); i++) {
canvas.add(new fabric.Line([i * grid, 0, i * grid, 600], {
stroke: '#ccc',
selectable: false
}));
canvas.add(new fabric.Line([0, i * grid, 600, i * grid], {
stroke: '#ccc',
selectable: false
}))
}
var line, triangle, isDown;
function calcArrowAngle(x1, y1, x2, y2) {
var angle = 0,
x, y;
x = (x2 - x1);
y = (y2 - y1);
if (x === 0) {
angle = (y === 0) ? 0 : (y > 0) ? Math.PI / 2 : Math.PI * 3 / 2;
} else if (y === 0) {
angle = (x > 0) ? 0 : Math.PI;
} else {
angle = (x < 0) ? Math.atan(y / x) + Math.PI : (y < 0) ? Math.atan(y / x) + (2 * Math.PI) : Math.atan(y / x);
}
return (angle * 180 / Math.PI + 90);
}
canvas.on('mouse:down', function(o) {
canvas.remove(line, triangle);
isDown = true;
var pointer = canvas.getPointer(o.e);
var points = [Math.round(pointer.x / grid) * grid, Math.round(pointer.y / grid) * grid, pointer.x, pointer.y];
line = new fabric.Line(points, {
strokeWidth: 5,
fill: 'red',
stroke: 'red',
originX: 'center',
originY: 'center'
});
centerX = (line.x1 + line.x2) / 2;
centerY = (line.y1 + line.y2) / 2;
deltaX = line.left - centerX;
deltaY = line.top - centerY;
triangle = new fabric.Triangle({
left: line.get('x1') + deltaX,
top: line.get('y1') + deltaY,
originX: 'center',
originY: 'center',
hasBorders: false,
hasControls: false,
lockScalingX: true,
lockScalingY: true,
lockRotation: true,
pointType: 'arrow_start',
angle: -45,
width: 20,
height: 20,
fill: 'red'
});
canvas.add(line, triangle);
});
canvas.on('mouse:move', function(o) {
//function angle(x1,y1,x2,y2){angle=Math.atan((y2-y1)/(x2-x1))*180/Math.PI+90; return angle;}
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
line.set({
x2: pointer.x,
y2: pointer.y
});
triangle.set({
'left': pointer.x + deltaX,
'top': pointer.y + deltaY,
'angle': calcArrowAngle(line.x1, line.y1, line.x2, line.y2)
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
var pointer = canvas.getPointer(o.e);
isDown = false;
snappedxCoordinate = Math.round(pointer.x / grid) * grid;
snappedyCoordinate = Math.round(pointer.y / grid) * grid;
snappedxCoordinateArrowhead = Math.round((pointer.x + deltaX) / grid) * grid;
snappedyCoordinateArrowhead = Math.round((pointer.y + deltaY) / grid) * grid;
line.set({
x2: snappedxCoordinate,
y2: snappedyCoordinate
});
triangle.set({
'left': snappedxCoordinateArrowhead,
'top': snappedyCoordinateArrowhead,
'angle': calcArrowAngle(line.x1, line.y1, line.x2, line.y2)
});
canvas.renderAll();
});
}
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="500" height="500" style="border:1px solid #ccc"></canvas>
I am working on a radial control similar to the HTML5 wheel of fortune example. I've modified the original here with an example of some additional functionality I require: http://jsfiddle.net/fEm9P/ When you click on the inner kinetic wedges they will shrink and expand within the larger wedges. Unfortunately when I rotate the wheel it lags behind the pointer. It's not too bad here but it's really noticeable on a mobile.
I know this is due to the fact that I'm not caching the wheel. When I do cache the wheel (uncomment lines 239-249) the inner wedges no longer respond to mouse/touch but the response on rotation is perfect. I have also tried adding the inner wedges to a separate layer and caching the main wheel only. I then rotate the inner wheel with the outer one. Doing it this way is a little better but still not viable on mobile.
Any suggestions would be greatly appreciated.
Stephen
//constants
var MAX_ANGULAR_VELOCITY = 360 * 5;
var NUM_WEDGES = 25;
var WHEEL_RADIUS = 410;
var ANGULAR_FRICTION = 0.2;
// globals
var angularVelocity = 360;
var lastRotation = 0;
var controlled = false;
var target, activeWedge, stage, layer, wheel,
pointer, pointerTween, startRotation, startX, startY;
var currentVolume, action;
function purifyColor(color) {
var randIndex = Math.round(Math.random() * 3);
color[randIndex] = 0;
return color;
}
function getRandomColor() {
var r = 100 + Math.round(Math.random() * 55);
var g = 100 + Math.round(Math.random() * 55);
var b = 100 + Math.round(Math.random() * 55);
var color = [r, g, b];
color = purifyColor(color);
color = purifyColor(color);
return color;
}
function bind() {
wheel.on('mousedown', function(evt) {
var mousePos = stage.getPointerPosition();
angularVelocity = 0;
controlled = true;
target = evt.targetNode;
startRotation = this.rotation();
startX = mousePos.x;
startY = mousePos.y;
});
// add listeners to container
document.body.addEventListener('mouseup', function() {
controlled = false;
action = null;
if(angularVelocity > MAX_ANGULAR_VELOCITY) {
angularVelocity = MAX_ANGULAR_VELOCITY;
}
else if(angularVelocity < -1 * MAX_ANGULAR_VELOCITY) {
angularVelocity = -1 * MAX_ANGULAR_VELOCITY;
}
angularVelocities = [];
}, false);
document.body.addEventListener('mousemove', function(evt) {
var mousePos = stage.getPointerPosition();
var x1, y1;
if(action == 'increase') {
x1 = (mousePos.x-(stage.getWidth() / 2));
y1 = (mousePos.y-WHEEL_RADIUS+20);
var r = Math.sqrt(x1 * x1 + y1 * y1);
if (r>500){
r=500;
} else if (r<100){
r=100;
};
currentVolume.setRadius(r);
layer.draw();
} else {
if(controlled && mousePos && target) {
x1 = mousePos.x - wheel.x();
y1 = mousePos.y - wheel.y();
var x2 = startX - wheel.x();
var y2 = startY - wheel.y();
var angle1 = Math.atan(y1 / x1) * 180 / Math.PI;
var angle2 = Math.atan(y2 / x2) * 180 / Math.PI;
var angleDiff = angle2 - angle1;
if ((x1 < 0 && x2 >=0) || (x2 < 0 && x1 >=0)) {
angleDiff += 180;
}
wheel.setRotation(startRotation - angleDiff);
}
};
}, false);
}
function getRandomReward() {
var mainDigit = Math.round(Math.random() * 9);
return mainDigit + '\n0\n0';
}
function addWedge(n) {
var s = getRandomColor();
var reward = getRandomReward();
var r = s[0];
var g = s[1];
var b = s[2];
var angle = 360 / NUM_WEDGES;
var endColor = 'rgb(' + r + ',' + g + ',' + b + ')';
r += 100;
g += 100;
b += 100;
var startColor = 'rgb(' + r + ',' + g + ',' + b + ')';
var wedge = new Kinetic.Group({
rotation: n * 360 / NUM_WEDGES,
});
var wedgeBackground = new Kinetic.Wedge({
radius: WHEEL_RADIUS,
angle: angle,
fillRadialGradientStartRadius: 0,
fillRadialGradientEndRadius: WHEEL_RADIUS,
fillRadialGradientColorStops: [0, startColor, 1, endColor],
fill: '#64e9f8',
fillPriority: 'radial-gradient',
stroke: '#ccc',
strokeWidth: 2,
rotation: (90 + angle/2) * -1
});
wedge.add(wedgeBackground);
var text = new Kinetic.Text({
text: reward,
fontFamily: 'Calibri',
fontSize: 50,
fill: 'white',
align: 'center',
stroke: 'yellow',
strokeWidth: 1,
listening: false
});
text.offsetX(text.width()/2);
text.offsetY(WHEEL_RADIUS - 15);
wedge.add(text);
volume = createVolumeControl(angle, endColor);
wedge.add(volume);
wheel.add(wedge);
}
var activeWedge;
function createVolumeControl(angle, colour){
var volume = new Kinetic.Wedge({
radius: 100,
angle: angle,
fill: colour,
stroke: '#000000',
rotation: (90 + angle/2) * -1
});
volume.on("mousedown touchstart", function() {
currentVolume = this;
action='increase';
});
return volume;
}
function animate(frame) {
// wheel
var angularVelocityChange = angularVelocity * frame.timeDiff * (1 - ANGULAR_FRICTION) / 1000;
angularVelocity -= angularVelocityChange;
if(controlled) {
angularVelocity = ((wheel.getRotation() - lastRotation) * 1000 / frame.timeDiff);
}
else {
wheel.rotate(frame.timeDiff * angularVelocity / 1000);
}
lastRotation = wheel.getRotation();
// pointer
var intersectedWedge = layer.getIntersection({x: stage.width()/2, y: 50});
if (intersectedWedge && (!activeWedge || activeWedge._id !== intersectedWedge._id)) {
pointerTween.reset();
pointerTween.play();
activeWedge = intersectedWedge;
}
}
function init() {
stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 500
});
layer = new Kinetic.Layer();
wheel = new Kinetic.Group({
x: stage.getWidth() / 2,
y: WHEEL_RADIUS + 20
});
for(var n = 0; n < NUM_WEDGES; n++) {
addWedge(n);
}
pointer = new Kinetic.Wedge({
fillRadialGradientStartPoint: 0,
fillRadialGradientStartRadius: 0,
fillRadialGradientEndPoint: 0,
fillRadialGradientEndRadius: 30,
fillRadialGradientColorStops: [0, 'white', 1, 'red'],
stroke: 'white',
strokeWidth: 2,
lineJoin: 'round',
angle: 30,
radius: 30,
x: stage.getWidth() / 2,
y: 20,
rotation: -105,
shadowColor: 'black',
shadowOffset: {x:3,y:3},
shadowBlur: 2,
shadowOpacity: 0.5
});
// add components to the stage
layer.add(wheel);
layer.add(pointer);
stage.add(layer);
pointerTween = new Kinetic.Tween({
node: pointer,
duration: 0.1,
easing: Kinetic.Easings.EaseInOut,
y: 30
});
pointerTween.finish();
var radiusPlus2 = WHEEL_RADIUS + 2;
wheel.cache({
x: -1* radiusPlus2,
y: -1* radiusPlus2,
width: radiusPlus2 * 2,
height: radiusPlus2 * 2
}).offset({
x: radiusPlus2,
y: radiusPlus2
});
layer.draw();
// bind events
bind();
var anim = new Kinetic.Animation(animate, layer);
//document.getElementById('debug').appendChild(layer.hitCanvas._canvas);
// wait one second and then spin the wheel
setTimeout(function() {
anim.start();
}, 1000);
}
init();
I made a couple of changes to the script which greatly improved the response time. The first was replacing layer.draw() with layer.batchDraw(). As the draw function was being called on each touchmove event it was making the interaction clunky. BatchDraw on the other hand will stack up draw requests internally "limit the number of redraws per second based on the maximum number of frames per second" (http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-batch-draw).
The jumping around of the canvas I seeing originally when I cached/cleared the wheel was due to the fact that I wasn't resetting the offset on the wheel when I cleared the cache.
http://jsfiddle.net/leydar/a7tkA/5
wheel.clearCache().offset({
x: 0,
y: 0
});
I hope this is of benefit to someone else. It's still not perfectly responsive but it's at least going in the right direction.
Stephen