I have to make drag-able svg element (viewport).
$('.zoom_panel').mousedown(function(e) {
if (!drag.state && e.which == 1) {
drag.elem = $('#graph_stage svg .viewport');
drag.state = true;
currentX = $(drag.elem).offset().left;
currentY = $(drag.elem).offset().top;
}
return false;
});
$('.zoom_panel').mousemove(function(e) {
if (drag.state) {
var attrs = $(drag.elem).attr('transform').split(' ')[1];
dx = e.offsetX - $(drag.elem).offset().left;
dy = e.pageY - $(drag.elem).offset().top;
newMatrix = 'translate('+( dx )+','+( dy )+') '+attrs;
$(drag.elem).attr('transform',newMatrix);
}
});
svg not move its blinking.
jsfiddle
Try this jsfiddle
Try to set dx by using relative positions.
dx = e.offsetX - currentX + currentdx;
dy = e.offsetY - currentY + currentdy;
Related
I have a weird problem. I'm creating a test game.Which uses touch events and canvas.There is a ball that you can push it and when you release your finger it must go(something like angry birds).
I made that in mouse and it work correctly.I wanna make it on android. But it doesn't run.But when you use 2 finger it works correctly.
I'm sure the problem is here :
canvas.addEventListener("touchstart",function(event){
event.preventDefault();
if (event.touches[0].clientX >= x && event.touches[0].clientX <= x + (radius * 2) && event.touches[0].clientY >= y && event.touches[0].clientY <= y + (radius * 2)) {
dx = 0;
dy = 0;
isindrag = true;
oldx = x;
oldy = y;
}
});
canvas.addEventListener("touchmove", function (event) {
event.preventDefault();
if (isindrag) {
x = event.touches[0].clientX;
y = event.touches[0].clientY;
}
});
canvas.addEventListener("touchend", function (event) {
var touchX = event.touches[0].clientX;
var touchY = event.touches[0].clientY;
if (isindrag && touchX < canvas.width && touchY < canvas.height && touchX > 0 && touchY > 0) {
isindrag = false;
dx = -(x - oldx) / 30;
dy = -(y - oldy) / 30;
ismoving = true;
}
});
canvas.addEventListener("touchcancel", function(event){
event.preventDefault();
});
x : x of ball
y : y of ball
dx : Delta x of ball
dy : delta y of ball
radius : radius of ball
Can you help me?
The touches object of a touch event contains a collection of points currently on the screen. Now imagine that you put a single finger onto the surface and release it. This will trigger a touchend event but as the touches object just contains information on the active 'fingers', it will come up empty thus there is no clientX or clientY property to query. In a touchend event handler you need to use changedTouches instead of touches.
So try changing
var touchX = event.touches[0].clientX;
var touchY = event.touches[0].clientY;
to
var touchX = event.changedTouches[0].clientX;
var touchY = event.changedTouches[0].clientY;
I have recently been asked to learn about Two.js, and specificaly to modify this example. I have tried for few day to alter this code ..
var two = new Two({
fullscreen: true,
autostart: true
}).appendTo(document.body);
var stage = new Two.Group();
for (var i = 0; i < 100; i++) {
var x = Math.random() * two.width * 2 - two.width;
var y = Math.random() * two.height * 2 - two.height;
var size = 50;
var shape = new Two.Rectangle(x, y, size, size);
shape.rotation = Math.random() * Math.PI * 2;
shape.noStroke().fill = '#ccc';
stage.add(shape);
}
shape.fill = 'red';
shape.position.set(two.width / 2, two.height / 2);
two.add(stage);
addZUI();
function addZUI() {
var domElement = two.renderer.domElement;
var zui = new Two.ZUI(stage);
var mouse = new Two.Vector();
var touches = {};
var distance = 0;
var dragging = false;
zui.addLimits(0.06, 8);
domElement.addEventListener('mousedown', mousedown, false);
domElement.addEventListener('mousewheel', mousewheel, false);
domElement.addEventListener('wheel', mousewheel, false);
domElement.addEventListener('touchstart', touchstart, false);
domElement.addEventListener('touchmove', touchmove, false);
domElement.addEventListener('touchend', touchend, false);
domElement.addEventListener('touchcancel', touchend, false);
function mousedown(e) {
mouse.x = e.clientX;
mouse.y = e.clientY;
var rect = shape.getBoundingClientRect();
dragging = mouse.x > rect.left && mouse.x < rect.right
&& mouse.y > rect.top && mouse.y < rect.bottom;
window.addEventListener('mousemove', mousemove, false);
window.addEventListener('mouseup', mouseup, false);
}
function mousemove(e) {
var dx = e.clientX - mouse.x;
var dy = e.clientY - mouse.y;
if (dragging) {
shape.position.x += dx / zui.scale;
shape.position.y += dy / zui.scale;
} else {
zui.translateSurface(dx, dy);
}
mouse.set(e.clientX, e.clientY);
}
function mouseup(e) {
window.removeEventListener('mousemove', mousemove, false);
window.removeEventListener('mouseup', mouseup, false);
}
function mousewheel(e) {
var dy = (e.wheelDeltaY || - e.deltaY) / 1000;
zui.zoomBy(dy, e.clientX, e.clientY);
}
function touchstart(e) {
switch (e.touches.length) {
case 2:
pinchstart(e);
break;
case 1:
panstart(e)
break;
}
}
function touchmove(e) {
switch (e.touches.length) {
case 2:
pinchmove(e);
break;
case 1:
panmove(e)
break;
}
}
function touchend(e) {
touches = {};
var touch = e.touches[ 0 ];
if (touch) { // Pass through for panning after pinching
mouse.x = touch.clientX;
mouse.y = touch.clientY;
}
}
function panstart(e) {
var touch = e.touches[ 0 ];
mouse.x = touch.clientX;
mouse.y = touch.clientY;
}
function panmove(e) {
var touch = e.touches[ 0 ];
var dx = touch.clientX - mouse.x;
var dy = touch.clientY - mouse.y;
zui.translateSurface(dx, dy);
mouse.set(touch.clientX, touch.clientY);
}
function pinchstart(e) {
for (var i = 0; i < e.touches.length; i++) {
var touch = e.touches[ i ];
touches[ touch.identifier ] = touch;
}
var a = touches[ 0 ];
var b = touches[ 1 ];
var dx = b.clientX - a.clientX;
var dy = b.clientY - a.clientY;
distance = Math.sqrt(dx * dx + dy * dy);
mouse.x = dx / 2 + a.clientX;
mouse.y = dy / 2 + a.clientY;
}
function pinchmove(e) {
for (var i = 0; i < e.touches.length; i++) {
var touch = e.touches[ i ];
touches[ touch.identifier ] = touch;
}
var a = touches[ 0 ];
var b = touches[ 1 ];
var dx = b.clientX - a.clientX;
var dy = b.clientY - a.clientY;
var d = Math.sqrt(dx * dx + dy * dy);
var delta = d - distance;
zui.zoomBy(delta / 250, mouse.x, mouse.y);
distance = d;
}
}
.. in order to make it work this way :
Zoom : on wheel, no change.
Dragging : only if mousedown in space between shapes.
Shape click : execute a function.
I tried many things base on answers found here and doc, but nothing work at all, an some pieces of code could be seen as a damn blasphemy.
I don't ask for a complete working code (if someone can provide it I will study it gladly), but any explanations or hints will be greatly appreciate.
After resizing the square, there is a collision problem, GIF animation problem, sample https://jsfiddle.net/8jkxdhfv/. What can i do? Should i untransformed mouse coordinates to transformed coordinates ? But how? How can i update x and y in my collision function?
HTML
<canvas id="test" width="480" height="380"></canvas>
<div id="text">Use mouse wheel to change square size</div>
JAVASCRIPT
var ctx = test.getContext('2d');
var obj = { x:100,y: 100,width: 100,height: 100}
var mouse = {x:0, y:0, width:10, height:10};
var zoom = 1;
setInterval(function(){
ctx.clearRect(0,0,test.width,test.height);
ctx.save();
var cx = obj.x+obj.width/2;
var cy = obj.y+obj.height/2;
// draw
ctx.translate(cx, cy);
ctx.scale(zoom,zoom);
ctx.translate(-cx,-cy);
ctx.fillRect(obj.x,obj.y,obj.width,obj.height);
ctx.restore();
// check collision
if(collision(obj,mouse)){
ctx.fillText("===== COLLISION =====", 110,90);
}
},1000/60);
function collision(obj1,obj2){
if(obj1.x < obj2.x + obj2.width * zoom &&
(obj1.x + obj1.width * zoom) > obj2.x &&
obj1.y < obj2.y + obj2.height * zoom &&
(obj1.height * zoom + obj1.y) > obj2.y){
return true;
}
return false;
}
window.addEventListener('mousewheel', function(e){
if(e.deltaY>0 && zoom<2){
zoom+=0.5;
}
if(e.deltaY<0 && zoom>0.5){
zoom-=0.5;
}
}, false);
window.addEventListener('mousemove', function(e){
mouse.x = e.pageX;
mouse.y = e.pageY;
}, false);
You are getting mouse position based on entire window, not canvas. Some math and you will get what you want.
test.addEventListener("mousemove", function(evt) {
var mousePos = getMousePos(test, evt);
mouse.x = mousePos.x;
mouse.y = mousePos.y;
});
function getMousePos(canvas, event) {
var rect = canvas.getBoundingClientRect();
return {
x: event.clientX - rect.left,
y: event.clientY - rect.top
};
}
I have updated the function and it works:
function collision(obj1,obj2){
var eW = (obj1.width-(obj1.width*zoom))/2;
var eH = (obj1.height-(obj1.height*zoom))/2;
//console.log(eW);
if(obj1.x+eW < obj2.x + obj2.width * zoom &&
(obj1.x + obj1.width * zoom) + eW> obj2.x &&
obj1.y + eH < obj2.y + obj2.height * zoom &&
(obj1.height * zoom + obj1.y) + eH > obj2.y){
return true;
}
return false;
}
I have written the code but it's for drawing a rectangle, i need to draw triangle shape by dragging the mouse while onClick, like in windows paint App. how to drag the mouse so that triangle forms automatically?
initDraw(document.getElementById('canvas'));
function initDraw(canvas) {
var mouse = {
x: 0,
y: 0,
startX: 0,
startY: 0
};
function setMousePosition(e) { // setting the postion for mouse
var ev = e || window.event;
if (ev.pageX) {
mouse.x = ev.pageX + window.pageXOffset;
mouse.y = ev.pageY + window.pageYOffset;
} else if (ev.clientX) {
mouse.x = ev.clientX + document.body.scrollLeft;
mouse.z = ev.clientZ + document.body.scrollLeft;
} };
var element = null;
canvas.onmousemove = function (e) {// on move
setMousePosition(e);
if (element !== null) {
element.style.width = Math.abs(mouse.x - mouse.startX) + 'px';
element.style.height = Math.abs(mouse.y - mouse.startY) + 'px';
element.style.left = (mouse.x - mouse.startX < 0) ? mouse.x + 'px' : mouse.startX + 'px';
element.style.top = (mouse.y - mouse.startY < 0) ? mouse.y + 'px' : mouse.startY + 'px';
}}};
canvas.onclick = function (e) {// on click function
if (element !== null) {
element = null;
canvas.style.cursor = "default";
console.log("finsihed.");
} else {
console.log("begun.");
mouse.startX = mouse.x;
mouse.startY = mouse.y;
element = document.createElement('div');
element.className = 'triangle'
element.style.left = mouse.x + 'px';
element.style.top = mouse.y + 'px';
canvas.appendChild(element)
canvas.style.cursor = "crosshair";
}}}
So ... I created canvas element with jquery:
var canvasElement = $("<canvas id='map' width='" + CANVAS_WIDTH + "' height='" + CANVAS_HEIGHT + "'></canvas");
var canvas = canvasElement.get(0).getContext("2d");
canvasElement.appendTo('body');
And now i want to get mouse coordinates, but the next code doesn't work:
canvasElement.onmousemove = mousemove;
function mousemove(evt) {
var mouseX = evt.pageX - canvasElement.offsetLeft;
var mouseY = evt.pageY - canvasElement.offsetTop;
alert(mouseX+":"+mouseY);
}
canvasElement.offsetLeft is not work, evt.pageX too... Help !
Those properties aren't cross-browser.
I know of two solutions to get the canvas position :
the easy one : use jQuery offset
another one : use a custom and complex code :
if (!canvasElement.offsetX) {
// firefox
var obj = canvasElement;
var oX = obj.offsetLeft;var oY = obj.offsetTop;
while(obj.parentNode){
oX=oX+obj.parentNode.offsetLeft;
oY=oY+obj.parentNode.offsetTop;
if(obj==document.getElementsByTagName('body')[0]){break}
else{obj=obj.parentNode;}
}
canvas_position_x = oX;
canvas_position_y = oY;
} else {
// chrome
canvas_position_x = canvasElement.offsetX;
canvas_position_y = canvasElement.offsetY;
}
As there is a loop, you'd better store canvas_position_x and canvas_position_y and have them recomputed at each document resize instead of at each mousemove.
Demonstration
Live Demo
Its pretty easy actually without jQuery. Below is the important part from the fiddle. cX and cY are the coordinates of the clicked canvas.
function clicked(e) {
var cX = 0,
cY = 0;
if (event.pageX || event.pageY) {
cX = event.pageX;
cY = event.pageY;
}
else {
cX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
cY = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
cX -= canvas.offsetLeft;
cY -= canvas.offsetTop;
ctx.fillRect(cX, cY, 2, 2);
}
Demo with mouse move