I have three canvas-elements that lay over the another. the first is a picture the second a filter and the third should be a text. I made the filter resizeable und draggable with the mouse events, but somehow this does not work with the text the same way. and i want to resize the text with four corner buttons and want to make it draggable. The text is added via a self-programmed simple texteditor.
click me please
click me please
The red square is where the rectangles are drawn now, but htey should be around the text, and the blue square is the hitbox to drag the text.
Now my Js-Code for the text.
var colorButton = document.getElementById("primary_color");
var textArea = document.getElementById("text");
var editor = document.getElementById("text");
var overlay = document.getElementById("overlay");
var textFontFamily = document.getElementById("selectForFonts");
var textColor;
var fontStyleFamily = 'Arial';
var boldness = 'normal';
var italicness = 'normal';
var data;
/**Function to get the color and color the text*/
colorButton.onchange = function() {
textColor = colorButton.value;
textArea.style.color = textColor;
}
function showOverlay() {
overlay.style.display = "block";
}
function writeText() {
$(function() {
var canvasText = document.getElementById("canvasText");
var ctxText = canvasText.getContext("2d");
var $canvasText = $("#canvasText");
var canvasOffset;
var offsetX;
var offsetY;
var isDown;
var dx;
var dy;
var lastX = 0;
var lastY = 0;
var iW;
var iH;
var iLeft = 0;
var iTop = 0;
var iRight, iBottom, iOrientation;
canvasText.height = renderableHeight;
canvasText.width = renderableWidth;
overlay.style.display = "none";
data = textArea.value;
canvasText.style.display = "block";
canvasOffset = $canvasText.offset();
offsetX = canvasOffset.left;
offsetY = canvasOffset.top;
isDown = false;
var textWidthtemp = ctxText.measureText(data);
var textWidth = textWidthtemp.width;
var textHeight = parseInt("50");
var font = italicness + " " + boldness + " " + textHeight + "px " + fontStyleFamily;
iW = textWidth;
iH = textHeight;
facW = 1; // canvasText.width / canvasText.offsetWidth;
facH = 1; //canvasText.height / canvasText.offsetHeight;
console.log(facW + " " + facH);
iRight = iLeft + iW;
iBottom = iTop + iH;
console.log(iTop);
console.log(iBottom);
console.log(iRight);
console.log(iBottom);
iOrientation = "Wide"; //(iW >= iH) ? "Wide" : "Tall";
draw(true);
var border = 10;
var isLeft = false;
var isRight = false;
var isTop = false;
var isBottom = false;
var iAnchor;
canvasText.onmousedown = handleMousedown;
canvasText.onmousemove = handleMousemove;
canvasText.onmouseup = handleMouseup;
canvasText.onmouseout = handleMouseup;
function hitResizeAnchor(x, y) {
// which borders are under the mouse
isLeft = (x * facW > iLeft && x * facW < iLeft + border);
isRight = (x * facW < iRight && x * facW > iRight - border);
isTop = (y * facH > iTop && y * facH < iTop + border);
isBottom = (y * facH < iBottom && y * facH > iBottom - border);
isDragged = (x * facW > iLeft && x * facW < iRight && y * facH > iTop && y * facH < iBottom);
// return the appropriate anchor
if (isTop && isLeft) {
return (iOrientation + "TL");
}
if (isTop && isRight) {
return (iOrientation + "TR");
}
if (isBottom && isLeft) {
return (iOrientation + "BL");
}
if (isBottom && isRight) {
return (iOrientation + "BR");
}
if (isDragged) {
return "DR"
}
return (null);
}
var resizeFunctions = {
WideTR: function(x, y) {
iRight = x * facW;
iTop = iBottom - (iH * (iRight - iLeft) / iW);
},
TallTR: function(x, y) {
iTop = y * facH;
iRight = iLeft + (iW * (iBottom - iTop) / iH);
},
WideBR: function(x, y) {
iRight = x * facW;
iBottom = iTop + (iH * (iRight - iLeft) / iW);
},
TallBR: function(x, y) {
iBottom = y * facH;
iRight = iLeft + (iW * (iBottom - iTop) / iH);
},
WideBL: function(x, y) {
iLeft = x * facW;
iBottom = iTop + (iH * (iRight - iLeft) / iW);
},
TallBL: function(x, y) {
iBottom = y * facH;
iLeft = iRight - (iW * (iBottom - iTop) / iH);
},
WideTL: function(x, y) {
iLeft = x * facW;
iTop = iBottom - (iH * (iRight - iLeft) / iW);
},
TallTL: function(x, y) {
iBottom = y * facH;
iLeft = iRight - (iW * (iBottom - iTop) / iH);
},
DR: function(x, y) {
console.log("DX: " + dx + "DY: " + dy);
iLeft += dx;
iRight += dx;
iTop += dy;
iBottom += dy;
}
};
function handleMousedown(e) {
// tell the browser we'll handle this mousedown
e.preventDefault();
e.stopPropagation();
var mouseX = e.clientX - offsetX;
var mouseY = e.clientY - offsetY;
iAnchor = hitResizeAnchor(mouseX, mouseY);
if (iAnchor == "DR") {
lastX = mouseX;
lastY = mouseY;
isDown = (true);
} else {
isDown = (iAnchor);
}
}
function handleMouseup(e) {
// tell the browser we'll handle this mouseup
e.preventDefault();
e.stopPropagation();
if (iAnchor == "DR") {
isDown = false;
} else {
isDown = false;
draw(true);
}
}
function handleMousemove(e) {
// tell the browser we'll handle this mousemove
e.preventDefault();
e.stopPropagation();
// return if we're not dragging
if (!isDown) {
return;
}
// get MouseX/Y
var mouseX = e.clientX - offsetX;
var mouseY = e.clientY - offsetY;
//if Picture is dragged
if (iAnchor == "DR") {
dx = mouseX - lastX;
dy = mouseY - lastY;
// set the lastXY for next time we're here
lastX = mouseX;
lastY = mouseY;
resizeFunctions[iAnchor](mouseX, mouseY);
draw(true);
} else {
// reset iLeft,iRight,iTop,iBottom based on drag
resizeFunctions[iAnchor](mouseX, mouseY);
// redraw the resized image
draw(false);
}
}
function draw(withAnchors) {
ctxText.clearRect(0, 0, canvasText.width, canvasText.height);
ctxText.font = font;
ctxText.fillStyle = textColor;
ctxText.fillText(data, iLeft, iTop - textHeight);
if (withAnchors) {
ctxText.fillRect(iLeft, iTop - textHeight, border, border);
ctxText.fillRect(iRight - border, iTop - textHeight, border, border);
ctxText.fillRect(iRight - border, iBottom - border - textHeight, border, border);
ctxText.fillRect(iLeft, iBottom - border - textHeight, border, border);
}
}
});
}
function bold() {
var temp = textArea.style.fontWeight;
if (temp == 'normal') {
textArea.style.fontWeight = 'bold';
boldness = 'bold';
} else {
textArea.style.fontWeight = 'normal';
boldness = 'normal';
}
}
function italic() {
var temp = textArea.style.fontStyle;
if (temp == 'normal') {
textArea.style.fontStyle = 'italic';
italicness = 'italic';
} else {
textArea.style.fontStyle = 'normal';
italicness = 'normal';
}
}
function changeFont() {
var temp = textFontFamily.options[textFontFamily.selectedIndex].value;
console.log(temp);
textArea.style.fontFamily = temp;
fontStyleFamily = temp;
}
<div id="display" class="flex-workspace-item-big z-depth-2">
<canvas id=canvas style="width:inherit ;height:inherit; position: absolute; z-index: 0;"></canvas>
<canvas id=canvasFilter style="width:inherit ;height:inherit; position: absolute; display: none; z-index: 1"></canvas>
<canvas id=canvasText style="width:inherit ;height:inherit; position: absolute; display: none; z-index: 2"></canvas>
</div>
Related
I want to get the value of clicked portion of the canvas element. The canvas contains multiple elements looks like the below image.
flow chart .
I have tried with the click event of addEventListener but I am unable to get the value. Below I shared the code for reference.
canvas.addEventListener('click',function(evt){
console.log(evt);
});
You should have the position of the each flow chart and when user clicks you should calculate canvas position with flow chart position.This will satisfy your requirement.
enter link description here
var elem = document.getElementById('myCanvas'),
elemLeft = elem.offsetLeft,
elemTop = elem.offsetTop,
context = elem.getContext('2d'),
elements = [];
// Add event listener for `click` events.
elem.addEventListener('click', function (event) {
// var leftWidth = $("#leftPane").css("width")
// var x = event.pageX - (elemLeft + parseInt(leftWidth) + 220),
// y = event.pageY - (elemTop + 15);
var x = event.pageX - elemLeft,
y = event.pageY - elemTop;
elements.forEach(function (element) {
if (y > element.top && y < element.top + element.height && x > element.left && x < element.left + element.width) {
alert(element.text);
}
});
}, false);
// Set the value content (x,y) axis
var x = 15, y = 20, maxWidth = elem.getAttribute("width"),
maxHeight = elem.getAttribute("height"), type = 'TL',
width = 50, height = 60, text = "", topy = 0, leftx = 0;
for (i = 1; i <= 15; i++) {
y = 10;
for (j = 1; j <= 6; j++) {
width = 50, height = 60
switch (j) {
case 1:
type = 'TL'; // Trailer
height = 60;
width = 85;
text = i + 'E';
break;
case 2:
type = 'DR'; // Door
height = 35;
width = 85;
text = i;
break;
case 3:
type = 'FL'; // Floor
height = 30;
width = 40;
break;
case 4:
type = 'FL'; // Floor
height = 30;
width = 40;
y -= 10;
break;
case 5:
type = 'DR'; // Door
height = 35;
width = 85;
text = i*10 + 1;
y = topy;
break;
case 6:
type = 'TL'; // Trailer
height = 60;
width = 85;
text = i + 'F';
y += 5;
break;
}
topy = y;
leftx = x;
if (type == 'FL') {
for (k = 1; k <= 12; k++) {
elements.push({
colour: '#05EFFF',
width: width,
height: height,
top: topy,
left: leftx,
text: k,
textColour: '#fff',
type: type
});
if (k % 2 == 0) {
topy = y + elements[j - 1].height + 5;
leftx = x;
y = topy;
}
else {
topy = y;
leftx = x + elements[j - 1].width + 5;
}
}
x = leftx;
y = topy;
}
else {
elements.push({
colour: '#05EFFF',
width: width,
height: height,
top: y,
left: x,
text: text,
textColour: '#fff',
type: type
});
}
//get the y axis for next content
y = y + elements[j-1].height + 6
if (y >= maxHeight - elements[j-1].height) {
break;
}
}
//get the x axis for next content
x = x + elements[0].width + 15
if (x >= maxWidth - elements[0].width) {
break;
}
}
// Render elements.
elements.forEach(function (element) {
context.font = "14pt Arial";
context.strokeStyle = "#000";
context.rect(element.left, element.top, element.width, element.height);
if (element.type == 'FL') {
context.fillText(element.text, element.left + element.width / 4, element.top + element.height / 1.5);
}
else {
context.fillText(element.text, element.left + element.width / 2.5, element.top + element.height / 1.5);
}
context.lineWidth = 1;
context.stroke()
});
<canvas id="myCanvas" width="1125" height="668" style="border: 3px solid #ccc; margin:0;padding:0;" />
please see this snippet that define do you clicked on rectangle in canvas or not.
var startRectPoint = {
x: 10,
y: 10
};
var endRectPoint = {
x: 100,
y: 50
};
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillRect(startRectPoint.x, startRectPoint.y, endRectPoint.x, endRectPoint.y);
function mouseDown(e) {
var x, y;
x = e.clientX - canvas.offsetLeft - pageXOffset;
y = e.clientY - canvas.offsetTop - pageYOffset;
var minX = Math.min(startRectPoint.x, endRectPoint.x);
var maxX = Math.max(startRectPoint.x, endRectPoint.x);
var minY = Math.min(startRectPoint.y, endRectPoint.y);
var maxY = Math.max(startRectPoint.y, endRectPoint.y);
if (x > minX && x < maxX && y > minY && y < maxY) {
alert("you clicked inside of rectangle");
} else {
alert("you clicked outside of rectangle");
}
}
canvas {
border: 1px solid;
}
<canvas id="myCanvas" width="400" height="200" onmousedown="mouseDown(event)"></canvas>
How can I create an 'infinite' canvas with text boxes dotted around? Like this one at the Desmos site.
I have not managed to implement it myself.
The simplest approach to a pan-able canvas is to draw everything relative to an offset, in this example I have called this panX & panY. Imagine it as a coordinate you use to move the viewport (the area of the infinite board that is currently visible in the canvas).
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
position: absolute;
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
border: solid 1px white;
border-radius: 10px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
var imageWidth = 180;
var imageHeight = 160;
var canvas = null;
var ctx = null;
var bounds = null;
var selectedBox = null;
var panX = 0;
var panY = 0;
var mouseX = 0;
var mouseY = 0;
var oldMouseX = 0;
var oldMouseY = 0;
var mouseHeld = false;
var boxArray = [];
function DraggableBox(x,y,width,height,text) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.text = text;
this.isSelected = false;
}
DraggableBox.prototype.isCollidingWidthPoint = function(x,y) {
return (x > this.x && x < this.x + this.width)
&& (y > this.y && y < this.y + this.height);
}
DraggableBox.prototype.drag = function(newX,newY) {
this.x = newX - this.width * 0.5;
this.y = newY - this.height * 0.5;
}
DraggableBox.prototype.draw = function() {
if (this.isSelected) {
ctx.fillStyle = "darkcyan";
ctx.fillRect(
this.x - panX,
this.y - panY,
this.width,
this.height
);
ctx.fillStyle = "black";
} else {
ctx.fillRect(
this.x - panX,
this.y - panY,
this.width,
this.height
);
}
ctx.fillStyle = "white";
ctx.fillText(
this.text,
this.x + this.width * 0.5 - panX,
this.y + this.height * 0.5 - panY,
this.width
);
ctx.fillStyle = "black";
}
window.onmousedown = function(e) {
mouseHeld = true;
if (!selectedBox) {
for (var i = boxArray.length - 1; i > -1; --i) {
if (boxArray[i].isCollidingWidthPoint(mouseX + panX,mouseY + panY)) {
selectedBox = boxArray[i];
selectedBox.isSelected = true;
requestAnimationFrame(draw);
return;
}
}
}
}
window.onmousemove = function(e) {
mouseX = e.clientX - bounds.left;
mouseY = e.clientY - bounds.top;
if (mouseHeld) {
if (!selectedBox) {
panX += oldMouseX - mouseX;
panY += oldMouseY - mouseY;
} else {
selectedBox.x = mouseX - selectedBox.width * 0.5 + panX;
selectedBox.y = mouseY - selectedBox.height * 0.5 + panY;
}
}
oldMouseX = mouseX;
oldMouseY = mouseY;
requestAnimationFrame(draw);
}
window.onmouseup = function(e) {
mouseHeld = false;
if (selectedBox) {
selectedBox.isSelected = false;
selectedBox = null;
requestAnimationFrame(draw);
}
}
function draw() {
ctx.fillStyle = "gray";
ctx.fillRect(0,0,imageWidth,imageHeight);
var box = null;
var xMin = 0;
var xMax = 0;
var yMin = 0;
var yMax = 0;
ctx.fillStyle = "black";
for (var i = 0; i < boxArray.length; ++i) {
box = boxArray[i];
xMin = box.x - panX;
xMax = box.x + box.width - panX;
yMin = box.y - panY;
yMax = box.y + box.height - panY;
if (xMax > 0 && xMin < imageWidth && yMax > 0 && yMin < imageHeight) {
box.draw();
}
}
}
window.onload = function() {
canvas = document.getElementById("canvas");
canvas.width = imageWidth;
canvas.height = imageHeight;
bounds = canvas.getBoundingClientRect();
ctx = canvas.getContext("2d");
ctx.textAlign = "center";
ctx.font = "15px Arial"
boxArray.push(new DraggableBox(Math.random() * 320,Math.random() * 240,100,25,"This is a draggable text box"));
boxArray.push(new DraggableBox(Math.random() * 320,Math.random() * 240,100,50,"Another text box"));
boxArray.push(new DraggableBox(Math.random() * 320,Math.random() * 240,100,50,"Text in a box"));
boxArray.push(new DraggableBox(Math.random() * 320,Math.random() * 240,100,50,"I find this box quite texing"));
boxArray.push(new DraggableBox(Math.random() * 320,Math.random() * 240,150,50,"You weren't supposed to find this box"));
requestAnimationFrame(draw);
}
window.onunload = function() {
canvas = null;
ctx = null;
bounds = null;
selectedBox = null;
boxArray = null;
}
</script>
</body>
</html>
I found this amazing plugin which simulates the physics of fabric: http://codepen.io/anon/pen/mxjKC
document.getElementById('close').onmousedown = function(e) {
e.preventDefault();
document.getElementById('info').style.display = 'none';
return false;
};
// settings
var physics_accuracy = 3,
mouse_influence = 20,
mouse_cut = 5,
gravity = 1200,
cloth_height = 30,
cloth_width = 50,
start_y = 20,
spacing = 7,
tear_distance = 60;
window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
var canvas,
ctx,
cloth,
boundsx,
boundsy,
mouse = {
down: false,
button: 1,
x: 0,
y: 0,
px: 0,
py: 0
};
var Point = function (x, y) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
this.pin_x = null;
this.pin_y = null;
this.constraints = [];
};
Point.prototype.update = function (delta) {
if (mouse.down) {
var diff_x = this.x - mouse.x,
diff_y = this.y - mouse.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);
if (mouse.button == 1) {
if (dist < mouse_influence) {
this.px = this.x - (mouse.x - mouse.px) * 1.8;
this.py = this.y - (mouse.y - mouse.py) * 1.8;
}
} else if (dist < mouse_cut) this.constraints = [];
}
this.add_force(0, gravity);
delta *= delta;
nx = this.x + ((this.x - this.px) * .99) + ((this.vx / 2) * delta);
ny = this.y + ((this.y - this.py) * .99) + ((this.vy / 2) * delta);
this.px = this.x;
this.py = this.y;
this.x = nx;
this.y = ny;
this.vy = this.vx = 0
};
Point.prototype.draw = function () {
if (!this.constraints.length) return;
var i = this.constraints.length;
while (i--) this.constraints[i].draw();
};
Point.prototype.resolve_constraints = function () {
if (this.pin_x != null && this.pin_y != null) {
this.x = this.pin_x;
this.y = this.pin_y;
return;
}
var i = this.constraints.length;
while (i--) this.constraints[i].resolve();
this.x > boundsx ? this.x = 2 * boundsx - this.x : 1 > this.x && (this.x = 2 - this.x);
this.y < 1 ? this.y = 2 - this.y : this.y > boundsy && (this.y = 2 * boundsy - this.y);
};
Point.prototype.attach = function (point) {
this.constraints.push(
new Constraint(this, point)
);
};
Point.prototype.remove_constraint = function (constraint) {
this.constraints.splice(this.constraints.indexOf(constraint), 1);
};
Point.prototype.add_force = function (x, y) {
this.vx += x;
this.vy += y;
};
Point.prototype.pin = function (pinx, piny) {
this.pin_x = pinx;
this.pin_y = piny;
};
var Constraint = function (p1, p2) {
this.p1 = p1;
this.p2 = p2;
this.length = spacing;
};
Constraint.prototype.resolve = function () {
var diff_x = this.p1.x - this.p2.x,
diff_y = this.p1.y - this.p2.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y),
diff = (this.length - dist) / dist;
if (dist > tear_distance) this.p1.remove_constraint(this);
var px = diff_x * diff * 0.5;
var py = diff_y * diff * 0.5;
this.p1.x += px;
this.p1.y += py;
this.p2.x -= px;
this.p2.y -= py;
};
Constraint.prototype.draw = function () {
ctx.moveTo(this.p1.x, this.p1.y);
ctx.lineTo(this.p2.x, this.p2.y);
};
var Cloth = function () {
this.points = [];
var start_x = canvas.width / 3 - cloth_width * spacing / 2;
for (var y = 0; y <= cloth_height; y++) {
for (var x = 0; x <= cloth_width; x++) {
var p = new Point(start_x + x * spacing, start_y + y * spacing);
x != 0 && p.attach(this.points[this.points.length - 1]);
y == 0 && p.pin(p.x, p.y);
y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)])
this.points.push(p);
}
}
};
Cloth.prototype.update = function () {
var i = physics_accuracy;
while (i--) {
var p = this.points.length;
while (p--) this.points[p].resolve_constraints();
}
i = this.points.length;
while (i--) this.points[i].update(.016);
};
Cloth.prototype.draw = function () {
ctx.beginPath();
var i = cloth.points.length;
while (i--) cloth.points[i].draw();
ctx.stroke();
};
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
cloth.update();
cloth.draw();
requestAnimFrame(update);
}
function start() {
canvas.onmousedown = function (e) {
mouse.button = e.which;
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
mouse.down = true;
e.preventDefault();
};
canvas.onmouseup = function (e) {
mouse.down = false;
e.preventDefault();
};
canvas.onmousemove = function (e) {
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
e.preventDefault();
};
canvas.oncontextmenu = function (e) {
e.preventDefault();
};
boundsx = canvas.width - 1;
boundsy = canvas.height - 1;
ctx.strokeStyle = 'red';
cloth = new Cloth();
update();
}
window.onload = function () {
canvas = document.getElementById('c');
ctx = canvas.getContext('2d');
canvas.width = 1120;
canvas.height = 700;
canvas.style.width = '560px';
canvas.style.height = '350px';
ctx.scale(2,2);
start();
};
<div id=info>
<input type="button" value="close" id="close"></input>
<canvas id="c"></canvas>
</div>
I would love to know how to use it for an image instead of the net but I don't know where to start at all.
What is the theory behind that - where could I place the image?
You can not put an image on that mesh because the resulting squares are not 2d. This answer gives a little detail as to why.
To do what you want you need to use webGL. It is a straightforward conversion, the cloth is a mesh (vertices and polygons connecting the vertices) where each vertex will hold a texture coordinate and you let the sim run as is. There should be plenty of examples of how to map a image onto a mesh in stackoverflow. You might consider using three.js if you are new to 3D and coding.
Here is an example using three.js and a verlet cloth with texture mapped onto it.
I'm creating one drawing app, there I have option to zoom in/out of the canvas image which I have drawn using drawImage() method, after zoom the image I am trying to save the image using toDataUrl() method but its showing blank page after assigning width and height of zoomed image to canvas.
Below code is to save the image after zoomed
destinationCanvas.width = 500; // actual size given with integer values
destinationCanvas.height = 500;
destinationCanvas.style.width = '500px'; // show at 50% on screen
destinationCanvas.style.height = '500px';
var destinationCanvasURL = destinationCanvas.toDataURL();
console.log("markerNormalStyleChange() destinationCanvasURL - "+destinationCanvasURL);
function drawImage(_onScreenMarkingImagePath) {
var canvas = document.getElementById('drawOnScreen');
var ctx = canvas.getContext("2d");
var imageObject = new Image();
var div = $('#drawOnScreenContext'),
w = $(window).width() - 1,
h = $(window).height() - 150;
canvas.width = w;
canvas.height = h ;
$(imageObject).load(function () {
ctx.drawImage(imageObject, 0, 0, w,h);
});
}
Below code is for rawing and zooming the image, here after draw on canvas if I try to zoom then drawn contents will removed because its drawing image only, so for zooming I want to zoom drawn contents also
var requestID;
(function() {
var root = this; //global object
var ImgTouchCanvas = function(options) {
if( !options || !options.canvas || !options.path) {
throw 'ImgZoom constructor: missing arguments canvas or path';
}
this.canvas = options.canvas;
this.canvas.width = this.canvas.clientWidth;
this.canvas.height = this.canvas.clientHeight;
this.context = this.canvas.getContext('2d');
console.log("ImgTouchCanvas() initiated this.canvas.width - "+this.canvas.width);
console.log("ImgTouchCanvas() initiated this.canvas.height - "+this.canvas.height);
this.desktop = options.desktop || false; //non touch events
this.position = {
x: 0,
y: 0
};
this.scale = {
x: 0.5,
y: 0.5
};
this.imgTexture = new Image();
this.imgTexture.src = options.path;
this.lastZoomScale = null;
this.lastX = null;
this.lastY = null;
this.init = false;
this.checkRequestAnimationFrame();
requestID = requestAnimationFrame(this.animate.bind(this));
this.setEventListeners();
};
ImgTouchCanvas.prototype = {
animate: function() {
console.log("ImgTouchCanvas requestAnimationFrame()");
//set scale such as image cover all the canvas
if(!this.init) {
if(this.imgTexture.width) {
var scaleRatio = null;
if(this.canvas.clientWidth > this.canvas.clientHeight) {
scaleRatio = this.canvas.clientWidth / this.imgTexture.width;
}
else {
scaleRatio = this.canvas.clientHeight / this.imgTexture.height;
}
this.scale.x = scaleRatio;
this.scale.y = scaleRatio;
this.init = true;
}
}
//this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
//canvas.width = w;
//canvas.height = h ;
/*this.canvas.width = zoomWidth;
this.canvas.height = zoomHeight;*/
this.context.drawImage(
this.imgTexture,
this.position.x, this.position.y,
this.scale.x * this.imgTexture.width,
this.scale.y * this.imgTexture.height);
console.log("this.scale.x * this.imgTexture.width -- "+this.scale.x * this.imgTexture.width);
console.log("this.scale.y * this.imgTexture.height -- "+this.scale.y * this.imgTexture.height);
mWidth = this.scale.x * this.imgTexture.width;
mHeight = this.scale.y * this.imgTexture.height;
console.log("mWidth -- "+mWidth);
console.log("mHeight -- "+mHeight);
//if($('#pinchZoomInZoomOut').find('#pinchZoomInZoomOutBg').hasClass('btnIconHighLight')) {
//requestAnimationFrame(this.animate.bind(this));
//}else{
//cancelAnimationFrame(this.animate.bind(this));
//}
},
gesturePinchZoom: function(event) {
var zoom = false;
if( event.targetTouches.length >= 2 ) {
var p1 = event.targetTouches[0];
var p2 = event.targetTouches[1];
var zoomScale = Math.sqrt(Math.pow(p2.pageX - p1.pageX, 2) + Math.pow(p2.pageY - p1.pageY, 2)); //euclidian distance
if( this.lastZoomScale ) {
zoom = zoomScale - this.lastZoomScale;
}
this.lastZoomScale = zoomScale;
}
return zoom;
},
doZoom: function(zoom) {
if(!zoom) return;
//new scale
var currentScale = this.scale.x;
var newScale = this.scale.x + zoom/100;
//some helpers
var deltaScale = newScale - currentScale;
var currentWidth = (this.imgTexture.width * this.scale.x);
var currentHeight = (this.imgTexture.height * this.scale.y);
var deltaWidth = this.imgTexture.width*deltaScale;
var deltaHeight = this.imgTexture.height*deltaScale;
//by default scale doesnt change position and only add/remove pixel to right and bottom
//so we must move the image to the left to keep the image centered
//ex: coefX and coefY = 0.5 when image is centered <=> move image to the left 0.5x pixels added to the right
var canvasmiddleX = this.canvas.clientWidth / 2;
var canvasmiddleY = this.canvas.clientHeight / 2;
var xonmap = (-this.position.x) + canvasmiddleX;
var yonmap = (-this.position.y) + canvasmiddleY;
var coefX = -xonmap / (currentWidth);
var coefY = -yonmap / (currentHeight);
var newPosX = this.position.x + deltaWidth*coefX;
var newPosY = this.position.y + deltaHeight*coefY;
//edges cases
var newWidth = currentWidth + deltaWidth;
var newHeight = currentHeight + deltaHeight;
zoomWidth = newWidth;
zoomHeight = newHeight;
//console.log("doZoom() newWidth -- "+newWidth);
//console.log("doZoom() newHeight -- "+newHeight);
if( newWidth < this.canvas.clientWidth ) return;
if( newPosX > 0 ) { newPosX = 0; }
if( newPosX + newWidth < this.canvas.clientWidth ) { newPosX = this.canvas.clientWidth - newWidth;}
if( newHeight < this.canvas.clientHeight ) return;
if( newPosY > 0 ) { newPosY = 0; }
if( newPosY + newHeight < this.canvas.clientHeight ) { newPosY = this.canvas.clientHeight - newHeight; }
//finally affectations
this.scale.x = newScale;
this.scale.y = newScale;
this.position.x = newPosX;
this.position.y = newPosY;
},
doMove: function(relativeX, relativeY) {
if(this.lastX && this.lastY) {
var deltaX = relativeX - this.lastX;
var deltaY = relativeY - this.lastY;
var currentWidth = (this.imgTexture.width * this.scale.x);
var currentHeight = (this.imgTexture.height * this.scale.y);
//console.log("doZoom() currentWidth -- "+currentWidth);
//console.log("doZoom() currentHeight -- "+currentHeight);
this.position.x += deltaX;
this.position.y += deltaY;
//edge cases
if( this.position.x > 0 ) {
this.position.x = 0;
}
else if( this.position.x + currentWidth < this.canvas.clientWidth ) {
this.position.x = this.canvas.clientWidth - currentWidth;
}
if( this.position.y > 0 ) {
this.position.y = 0;
}
else if( this.position.y + currentHeight < this.canvas.clientHeight ) {
this.position.y = this.canvas.clientHeight - currentHeight;
}
}
this.lastX = relativeX;
this.lastY = relativeY;
},
Draw222: function(x, y, isDown) {
//console.log("Draw222() -- "+isDown);
if (isDown) {
this.context.beginPath();
this.context.strokeStyle="#FF0000";
this.context.lineWidth = 5;
this.context.lineJoin = "round";
this.context.moveTo(lx, ly);
this.context.lineTo(x, y);
this.context.closePath();
this.context.stroke();
}
lx = x; ly = y;
},
setEventListeners: function() {
// touch
this.canvas.addEventListener('touchstart', function(e) {
this.lastX = null;
this.lastY = null;
this.lastZoomScale = null;
//newCtx = this.canvas.getContext("2d");
var relativeX = e.targetTouches[0].pageX - this.canvas.getBoundingClientRect().left;
var relativeY = e.targetTouches[0].pageY - this.canvas.getBoundingClientRect().top;
if($('#pinchZoomInZoomOut').find('#pinchZoomInZoomOutBg').hasClass('btnIconHighLight')) {
//requestAnimationFrame(this.animate.bind(this));
}else{
$( '#undoIcon' ).css({
opacity: 1,
pointerEvents: 'auto'
});
cancelAnimationFrame(this.animate.bind(this));
canvasPressed = true;
this.Draw222(parseInt(relativeX), parseInt(relativeY), false);
}
}.bind(this));
this.canvas.addEventListener('touchmove', function(e) {
e.preventDefault();
if(e.targetTouches.length == 2 && $('#pinchZoomInZoomOut').find('#pinchZoomInZoomOutBg').hasClass('btnIconHighLight')) { //pinch
console.log("pinch zoom")
requestID = requestAnimationFrame(this.animate.bind(this));
this.doZoom(this.gesturePinchZoom(e));
}
else {
//console.log("touchmove --- 1")
var relativeX = e.targetTouches[0].pageX - this.canvas.getBoundingClientRect().left;
var relativeY = e.targetTouches[0].pageY - this.canvas.getBoundingClientRect().top;
if($('#pinchZoomInZoomOut').find('#pinchZoomInZoomOutBg').hasClass('btnIconHighLight')) {
//console.log("hasClass btnIconHighLight --- ");
requestID = requestAnimationFrame(this.animate.bind(this));
this.doMove(relativeX, relativeY);
}else{
//console.log("touchmove --- canvasPressed -- "+canvasPressed)
if (canvasPressed) {
cancelAnimationFrame(this.animate.bind(this));
this.Draw222(parseInt(relativeX), parseInt(relativeY), true);
}
}
}
}.bind(this));
this.canvas.addEventListener('touchend', function(e) {
e.preventDefault();
//cPush();
canvasPressed = false;
/*var base64String = null;
var canvas = document.getElementById('drawOnScreen');
var context = canvas.getContext('2d');
// save canvas image as data url (png format by default)
var dataURL = canvas.toDataURL();
console.log("dataURL - "+dataURL);*/
//base64ByteString = dataURL;
//dataURL = dataURL.substr(dataURL.lastIndexOf(',') + 1);
}.bind(this));
},
checkRequestAnimationFrame: function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}
}
};
root.ImgTouchCanvas = ImgTouchCanvas;
}).call(this);
And for pinch zoom in/out the image, I am using this https://github.com/rombdn/img-touch-canvas
I got this problem: I found a very cool pen on codepen, I take it, modified, but when I put this in my html page doesn't work with other divs.
Here the pen https://jsfiddle.net/jtz21sz3/
<canvas id="stage" width="400" height="400">
<p>Your browser doesn't support canvas.</p>
</canvas>
everything work, but when i try to insert a sticky menu in the top the canvas draws the circle, but I can't drag them.
https://jsfiddle.net/Lp9w34sd/1/
<div class="sticky-menu-wrapper">
<nav class="main-menu clear">
<div class="menu-menu-1-container"><ul id="menu-menu-1" class="menu" style="text-align:center">
<li id="menu-item-135" class="menu-item menu-item-type-custom menu-item-object-custom" style=" text-align:left; float: left; padding-top:16px;"><a>RELEASE</a></li>
</ul></div>
</nav>
</div>
<canvas id="stage" width="400" height="400">
<p>Your browser doesn't support canvas.</p>
</canvas>
Any idea how to fix it?
Change function getMouseXY(e) { to this
function getMouseXY(e) {
mouseX = e.offsetX;
mouseY = e.offsetY;
if (mouseX < 0) mouseX = 0;
if (mouseY < 0) mouseY = 0;
}
Just add position:absolute (or fixed) to the nav.
var stage = document.getElementById('stage');
var browserX = window.screenX;
var browserY = window.screenY;
var balls = [];
var total = 6;
var currentDrag = null;
var mouseX = 0;
var mouseY = 0;
var stageWidth = $(document).width();
var stageHeight = $(document).height();
stage.width = stageWidth;
stage.height = stageHeight;
var IE = document.all ? true : false;
if (!IE) document.addEventListener(Event.MOUSEMOVE, getMouseXY, false);
document.onmousemove = getMouseXY;
window.onresize = function(event) {
stage.width = 10;
stage.height = 10;
stageWidth = $(document).width();
stageHeight = $(document).height();
stage.width = stageWidth;
stage.height = stageHeight;
}
generate();
var drawingCanvas = document.getElementById('stage');
if (drawingCanvas.getContext) {
var context = drawingCanvas.getContext('2d');
setInterval(render, 20);
}
jQuery(document).ready(function() {
$(document).mousedown(function(e) {
onMouseDown();
});
$(document).mouseup(function(e) {
onMouseUp();
});
})
function onMouseDown() {
var j = balls.length;
while (--j > -1) {
var dx = mouseX - balls[j].x;
var dy = mouseY - balls[j].y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < balls[j].size / 2) {
currentDrag = balls[j];
currentDrag.dragging = true;
return;
}
}
}
function onMouseUp() {
if (currentDrag != null) currentDrag.dragging = false;
}
function generate() {
for (var i = 0; i < total; i++) {
var ball = {};
ball.color = "#" + genHex();
ball.bounce = .5 + (Math.random() * .5);
ball.vx = Math.random() * 50 - 25;
ball.vy = Math.random() * 50 - 25;
ball.size = 75 - (ball.bounce * 25);
ball.x = Math.random() * stageWidth;
ball.y = Math.random() * stageHeight;
balls[balls.length] = ball;
}
}
function genHex() {
colors = new Array(14)
colors[0] = "0"
colors[1] = "1"
colors[2] = "2"
colors[3] = "3"
colors[4] = "4"
colors[5] = "5"
colors[5] = "6"
colors[6] = "7"
colors[7] = "8"
colors[8] = "9"
colors[9] = "a"
colors[10] = "b"
colors[11] = "c"
colors[12] = "d"
colors[13] = "e"
colors[14] = "f"
digit = new Array(5)
color = ""
for (i = 0; i < 6; i++) {
digit[i] = colors[Math.round(Math.random() * 14)]
color = color + digit[i]
}
return color;
}
function render() {
var isChange = (browserX != window.screenX || browserY != window.screenY);
if (isChange) {
var diffX = browserX - window.screenX;
browserX = window.screenX;
var diffY = browserY - window.screenY;
browserY = window.screenY;
}
var j = balls.length;
while (--j > -1) {
update(balls[j]);
if (isChange) {
balls[j].vx += (diffX * .05);
balls[j].vy += (diffY * .1);
}
}
draw();
}
function draw() {
context.clearRect(0, 0, stageWidth, stageHeight);
var i = balls.length;
while (--i > -1) {
context.fillStyle = balls[i].color;
context.beginPath();
context.arc(balls[i].x, balls[i].y, balls[i].size, 0, Math.PI * 2, true);
context.closePath();
context.fill();
}
}
function update(ball) {
collisionCheck();
var gravity = 0;
var drag = .98;
if (ball.dragging) {
ball.vx = ball.x - ball.ox;
ball.vy = ball.y - ball.oy;
ball.ox = ball.x;
ball.oy = ball.y;
ball.x = mouseX;
ball.y = mouseY;
if ((ball.x + ball.size) > stageWidth) {
ball.x = stageWidth - ball.size;
} else if ((ball.x - ball.size) < 0) {
ball.x = 0 + ball.size;
}
if ((ball.y + ball.size) > stageHeight) {
ball.y = stageHeight - ball.size;
} else if ((ball.y - ball.size) < 0) {
ball.y = 0 + ball.size;
}
} else {
ball.x += ball.vx;
ball.y += ball.vy;
if ((ball.x + ball.size) > stageWidth) {
ball.x = stageWidth - ball.size;
ball.vx = -ball.vx * ball.bounce;
} else if ((ball.x - ball.size) < 0) {
ball.x = 0 + ball.size;
ball.vx = -ball.vx * ball.bounce;
}
if ((ball.y + ball.size) > stageHeight) {
ball.y = stageHeight - ball.size;
ball.vy = -ball.vy * ball.bounce;
} else if ((ball.y - ball.size) < 0) {
ball.y = 0 + ball.size;
ball.vy = -ball.vy * ball.bounce;
}
ball.vx = ball.vx * drag;
ball.vy = ball.vy * drag + gravity;
}
}
function collisionCheck() {
var spring = .5;
for (var i = 0; i < (total - 1); ++i) {
var ball0 = balls[i];
for (var j = i + 1; j < total; ++j) {
var ball1 = balls[j];
var dx = ball1.x - ball0.x;
var dy = ball1.y - ball0.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var minDist = ball0.size + ball1.size;
if (dist < minDist) {
var angle = Math.atan2(dy, dx);
var tx = ball0.x + dx / dist * minDist;
var ty = ball0.y + dy / dist * minDist;
var ax = (tx - ball1.x);
var ay = (ty - ball1.y);
ball0.x -= ax;
ball0.y -= ay;
ball1.x += ax;
ball1.y += ay;
ball0.vx -= (ax * spring);
ball0.vy -= (ay * spring);
ball1.vx += (ax * spring);
ball1.vy += (ay * spring);
}
}
}
}
function getMouseXY(e) {
if (IE) {
mouseX = event.clientX + document.body.scrollLeft
mouseY = event.clientY + document.body.scrollTop
} else {
mouseX = e.pageX
mouseY = e.pageY
}
if (mouseX < 0) {
mouseX = 0;
}
if (mouseY < 0) {
mouseY = 0;
}
return true;
}
#stage { margin:0; padding:0; background-color:#DDD; }
.sticky-menu-wrapper {
position:absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="sticky-menu-wrapper">
<nav class="main-menu clear">
<div class="menu-menu-1-container"><ul id="menu-menu-1" class="menu" style="text-align:center">
<li id="menu-item-135" class="menu-item menu-item-type-custom menu-item-object-custom" style=" text-align:left; float: left; padding-top:16px;"><a>RELEASE</a></li>
</ul></div>
</nav>
</div>
<div>
<canvas id="stage" width="400" height="400">
<p>Your browser doesn't support canvas.</p>
</canvas>
</div>