I'm trying to use an image upload/cropping plugin simple cropper. I have it working fine but I'm dynamically inserting elements with the class .cropme that aren't getting the event binding. I've changed most of the click events to use .on() instead of .click(). Is there something I'm missing?
(function($) {
$.fn.simpleCropper = function () {
var image_dimension_x = 600;
var image_dimension_y = 600;
var scaled_width = 0;
var scaled_height = 0;
var x1 = 0;
var y1 = 0;
var x2 = 0;
var y2 = 0;
var current_image = null;
var aspX = 1;
var aspY = 1;
var file_display_area = null;
var ias = null;
var jcrop_api;
var bottom_html = "<input type='file' id='fileInput' name='files[]'/><canvas id='myCanvas' style='display:none;'></canvas><div id='modal'></div><div id='preview'><div class='buttons'><div class='cancel'></div><div class='ok'></div></div></div>";
$('body').append(bottom_html);
//add click to element
this.on('click', function () {
aspX = $(this).width();
aspY = $(this).height();
file_display_area = $(this);
$('#fileInput').click();
});
$(document).on('ready', function () {
//capture selected filename
$('#fileInput').on('change', function (click) {
imageUpload($('#preview').get(0));
// Reset input value
$(this).val("");
});
//ok listener
$('.ok').on('click', function () {
preview();
$('#preview').delay(100).hide();
$('#modal').hide();
jcrop_api.destroy();
reset();
});
//cancel listener
$('.cancel').on('click', function (event) {
$('#preview').delay(100).hide();
$('#modal').hide();
jcrop_api.destroy();
reset();
});
});
function reset() {
scaled_width = 0;
scaled_height = 0;
x1 = 0;
y1 = 0;
x2 = 0;
y2 = 0;
current_image = null;
aspX = 1;
aspY = 1;
file_display_area = null;
}
function imageUpload(dropbox) {
var file = $("#fileInput").get(0).files[0];
//var file = document.getElementById('fileInput').files[0];
var imageType = /image.*/;
if (file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function (e) {
// Clear the current image.
$('#photo').remove();
// Create a new image with image crop functionality
current_image = new Image();
current_image.src = reader.result;
current_image.id = "photo";
current_image.style['maxWidth'] = image_dimension_x + 'px';
current_image.style['maxHeight'] = image_dimension_y + 'px';
current_image.onload = function () {
// Calculate scaled image dimensions
if (current_image.width > image_dimension_x || current_image.height > image_dimension_y) {
if (current_image.width > current_image.height) {
scaled_width = image_dimension_x;
scaled_height = image_dimension_x * current_image.height / current_image.width;
}
if (current_image.width < current_image.height) {
scaled_height = image_dimension_y;
scaled_width = image_dimension_y * current_image.width / current_image.height;
}
if (current_image.width == current_image.height) {
scaled_width = image_dimension_x;
scaled_height = image_dimension_y;
}
}
else {
scaled_width = current_image.width;
scaled_height = current_image.height;
}
// Position the modal div to the center of the screen
$('#modal').css('display', 'block');
var window_width = $(window).width() / 2 - scaled_width / 2 + "px";
var window_height = $(window).height() / 2 - scaled_height / 2 + "px";
// Show image in modal view
$("#preview").css("top", window_height);
$("#preview").css("left", window_width);
$('#preview').show(500);
// Calculate selection rect
var selection_width = 0;
var selection_height = 0;
var max_x = Math.floor(scaled_height * aspX / aspY);
var max_y = Math.floor(scaled_width * aspY / aspX);
if (max_x > scaled_width) {
selection_width = scaled_width;
selection_height = max_y;
}
else {
selection_width = max_x;
selection_height = scaled_height;
}
ias = $(this).Jcrop({
onSelect: showCoords,
onChange: showCoords,
bgColor: '#747474',
bgOpacity: .4,
aspectRatio: aspX / aspY,
setSelect: [0, 0, selection_width, selection_height]
}, function () {
jcrop_api = this;
});
};
// Add image to dropbox element
dropbox.appendChild(current_image);
};
reader.readAsDataURL(file);
} else {
dropbox.innerHTML = "File not supported!";
}
}
function showCoords(c) {
x1 = c.x;
y1 = c.y;
x2 = c.x2;
y2 = c.y2;
}
function preview() {
// Set canvas
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
// Delete previous image on canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// Set selection width and height
var sw = x2 - x1;
var sh = y2 - y1;
// Set image original width and height
var imgWidth = current_image.naturalWidth;
var imgHeight = current_image.naturalHeight;
// Set selection koeficient
var kw = imgWidth / $("#preview").width();
var kh = imgHeight / $("#preview").height();
// Set canvas width and height and draw selection on it
canvas.width = aspX;
canvas.height = aspY;
context.drawImage(current_image,(x1 * kw),(y1 * kh),(sw * kw),(sh * kh), 0, 0, aspX, aspY);
// Convert canvas image to normal img
var dataUrl = canvas.toDataURL();
var imageFoo = document.createElement('img');
imageFoo.src = dataUrl;
// Append it to the body element
$('#preview').delay(100).hide();
$('#modal').hide();
file_display_area.html('');
file_display_area.append(imageFoo);
}
$(window).resize(function () {
// Position the modal div to the center of the screen
var window_width = $(window).width() / 2 - scaled_width / 2 + "px";
var window_height = $(window).height() / 2 - scaled_height / 2 + "px";
// Show image in modal view
$("#preview").css("top", window_height);
$("#preview").css("left", window_width);
});
};
}(jQuery));
I need to clean my code up but this is what I changed to make this work:
this.on('click', function () {
aspX = $(this).width();
aspY = $(this).height();
file_display_area = $(this);
$('#fileInput').click();
});
to
$('body').on('click', '.cropme', function () {
aspX = $(this).width();
aspY = $(this).height();
file_display_area = $(this);
$('#fileInput').click();
});
Related
I want know how to figure out if the puzzle is solved.
I am creating an app for creating custom 6-piece puzzle.
Here's the code:
function approved(){
// Get the canvas and context
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// Load the image
var img = new Image();
img.src = document.getElementById('puzzleprieview').src;
img.onload = function() {
// Set the canvas size
canvas.width = img.width;
canvas.height = img.height;
// Draw the image on the canvas
ctx.drawImage(img, 0, 0);
// Split the image into parts
var w = img.width / 3;
var h = img.height / 2;
for (var i = 0; i < 7; i++) {
var x = (i % 3) * w;
var y = Math.floor(i / 3) * h;
// Create a new canvas for each part
var partCanvas = document.createElement("canvas");
partCanvas.draggable="true";
partCanvas.className="sampcanvas"
$(".sampcanvas").draggable({snap: true});
partCanvas.width = w;
partCanvas.height = h;
var partCtx = partCanvas.getContext("2d");
// Draw the part of the image on the new canvas
partCtx.drawImage(canvas, x, y, w, h, 0, 0, w, h);
var number=Math.floor(Math.random() * 100);
// Do something with each part, such as append it to the document
const getRandom = (min, max) => Math.floor(Math.random()*(max-min+1)+min);
partCanvas.style.left= getRandom(0, 300 - 200)+'px'; // 👈🏼 Horizontally
partCanvas.style.top = getRandom(0, 300 - 200)+'px'; // 👈🏼 Vertically
document.getElementById('pieces').appendChild(partCanvas);
}
}
}
That code is used to create puzzle pieces and append them.
What I need to do is somehow compare the puzzle piece solving to the canvas that is created
Well, great task in general and question in particular !
To achieve this purpose you could, f.e. put into each puzzlePart block it's initial position using "data-" attributes:
var x = (i % 3) * w;
var y = Math.floor(i / 3) * h;
// Create a new canvas for each part
let partCanvas = document.createElement('canvas');
partCanvas.dataset.xx = x;
partCanvas.dataset.yy = y;
Next, whenever needed, you are able to compare current position of puzzle parts with their initial ones. I took initial position from .dataset and current using .getBoundingClientRect():
var canvasOffsets = canvas.getBoundingClientRect();
var elementScreenOffsets = partCanvas.getBoundingClientRect();
var elementOffsets = {
x: elementScreenOffsets.left - canvasOffsets.left,
y: elementScreenOffsets.top - canvasOffsets.top,
};
var initialOffsets = {
x: partCanvas.dataset.xx,
y: partCanvas.dataset.yy,
};
As an option, you could for example "freeze" puzzle parts on the screen when they're moreless in their initial position:
var FREEZE_DISTASNCE = 30;
if (
Math.abs(elementOffsets.x - initialOffsets.x) <
FREEZE_DISTASNCE &&
Math.abs(elementOffsets.y - initialOffsets.y) <
FREEZE_DISTASNCE
) {
makeNotDraggable(partCanvas);
partCanvas.style.left = partCanvas.dataset.xx;
partCanvas.style.top = partCanvas.dataset.yy;
partCanvas.style.zIndex = -1;
}
So eventually I decided to modify initial question's code to make it fully working using my ideas above. Plus I decided to implement this POC with "generic" image which you could pick
For drag-n-drop implementation I referenced this article: https://www.w3schools.com/howto/howto_js_draggable.asp
File inputs Api: https://developer.mozilla.org/ru/docs/Web/HTML/Element/Input/file
document
.querySelector('.js-puzzle-image')
.addEventListener('change', function () {
document.querySelector('.js-puzzle-image').style.display = 'none';
document.querySelector('#pieces').style.display = 'inline-block';
var imageSrc = window.URL.createObjectURL(this.files[0]);
approved(imageSrc);
});
function approved(imageSrc) {
const el_wrap = document.querySelector('#pieces');
// Get the canvas and context
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Load the image
var img = new Image();
img.src = imageSrc;
img.onload = function () {
// Set the canvas size
canvas.width = img.width;
canvas.height = img.height;
el_wrap.style.width = `${img.width}px`;
el_wrap.style.height = `${img.height}px`;
// Draw the image on the canvas
ctx.drawImage(img, 0, 0);
// Split the image into parts
var w = img.width / 3;
var h = img.height / 2;
for (var i = 0; i < 6; i++) {
var x = (i % 3) * w;
var y = Math.floor(i / 3) * h;
// Create a new canvas for each part
let partCanvas = document.createElement('canvas');
partCanvas.dataset.xx = x;
partCanvas.dataset.yy = y;
partCanvas.draggable = 'true';
partCanvas.className = 'sampcanvas';
//$('.sampcanvas').draggable({ snap: true });
partCanvas.width = w;
partCanvas.height = h;
var partCtx = partCanvas.getContext('2d');
// Draw the part of the image on the new canvas
partCtx.drawImage(canvas, x, y, w, h, 0, 0, w, h);
// Do something with each part, such as append it to the document
const getRandom = (min, max) =>
Math.floor(Math.random() * (max - min + 1) + min);
partCanvas.style.left = getRandom(0, img.width - w) + 'px'; // 👈🏼 Horizontally
partCanvas.style.top = getRandom(0, img.height - h) + 'px'; // 👈🏼 Vertically
document.getElementById('pieces').appendChild(partCanvas);
// making elements "draggable", but "freeze" them when they're on the correct position
makeDraggable(partCanvas, () => {
var canvasOffsets = canvas.getBoundingClientRect();
var elementScreenOffsets = partCanvas.getBoundingClientRect();
var elementOffsets = {
x: elementScreenOffsets.left - canvasOffsets.left,
y: elementScreenOffsets.top - canvasOffsets.top,
};
var initialOffsets = {
x: partCanvas.dataset.xx,
y: partCanvas.dataset.yy,
};
var FREEZE_DISTASNCE = 30;
if (
Math.abs(elementOffsets.x - initialOffsets.x) <
FREEZE_DISTASNCE &&
Math.abs(elementOffsets.y - initialOffsets.y) <
FREEZE_DISTASNCE
) {
makeNotDraggable(partCanvas);
partCanvas.style.left = partCanvas.dataset.xx + 'px';
partCanvas.style.top = partCanvas.dataset.yy + 'px';
partCanvas.style.zIndex = -1;
}
});
}
canvas.style.display = 'none';
};
}
// https://www.w3schools.com/howto/howto_js_draggable.asp
var zIndexTracker = 0;
function makeNotDraggable(elmnt) {
elmnt.onmousedown = undefined;
}
function makeDraggable(elmnt, onDrop) {
var pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
elmnt.onmousedown = dragMouseDown;
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
elmnt.style.zIndex = ++zIndexTracker;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.top = elmnt.offsetTop - pos2 + 'px';
elmnt.style.left = elmnt.offsetLeft - pos1 + 'px';
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
onDrop();
}
}
#pieces {
position: relative;
border: 1px dashed red;
display: inline-block;
}
.sampcanvas {
position: absolute;
}
<input type="file" accept=".png, .jpg, .jpeg" class="js-puzzle-image" />
<div id="pieces" style="display: none">
<canvas id="canvas"></canvas>
</div>
Of course, this code snippet is "not ideal" from code quality perspective and should be re-worked to be more object-oriented, to have better code responsibility splitting, etc... But for demostration purposes, I believe, that's a good start
Try adding this
partCanvas.dataset.index = i;
and then you can in your drop function do something like this
const finished = () => {
const indexes = document.querySelectorAll('.sampcanvas')
.map(imgPart => imgPart.dataset.index)
.join('');
console.log(indexes);
return indexes === '0123456';
}
I should draw a rectangle inside a pdf document in canvas, but it cleans the background of document.
I want a way to draw a rectangle in it without cleaning the background. Please can anyone help me with this.
Below is the code i am using:
$("#div").mouseover(function () {
$("canvas").on('click', function (e) {
console.log(nr)
id = ($(this).attr("id"));
console.log(id)
const baseImage = loadImage("");
var canvas = document.getElementById(id);
var ctx = canvas.getContext('2d');
Canvas = ctx;
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = 0;
var prev_x = prev_y = prev_w = prev_h = 0;
var mousex = mousey = 0;
var mousedown = false;
$(canvas).on('mousedown', function (e) {
if (rectanglearray.length < 2) {
last_mousex = parseInt(e.clientX - canvasx);
last_mousey = parseInt(e.clientY - canvasy);
mousedown = true;
}
});
$(canvas).on('mouseup', function (e) {
mousedown = false;
});
$(canvas).on('mousemove', function (e) {
mousex = parseInt(e.clientX - canvasx);
mousey = parseInt(e.clientY - canvasy);
if (mousedown) {
//if (rectanglearray.length < 2) {
ctx.clearRect(0, 0, canvas.width, canvas.height); //clear canvas
ctx.beginPath();
var width = mousex - last_mousex;
var height = mousey - last_mousey;
ctx.rect(last_mousex, last_mousey, width, height);
a = last_mousex;
b = last_mousey;
c = last_mousex + width;
d = last_mousey + height;
gjer = width;
lart = height;
t = a;
h = b;
gjere = gjer;
larte = lart;
nfq = id.substring(3, 4);
ctx.strokeStyle = 'black';
ctx.lineWidth = 1;
ctx.stroke();
rectanglearray.push(ctx);
//}
}
});
execute++;
});
});
so when i click in one of the pages of pdf it takes pages id and allows to only draw a rectangle in that page, but when i draw it cleans the background.
I want to have a function that draws a box in the coordinates x and y.
I can't find a guide that doesn't answer more/less than what i want.
Thank's in advance.
I wrote this script some time ago so there may be ways to update it, but the idea is to get the position of the cursor onmousedown and attach an onmousemove listener. Each time you move the mouse you adjust th size of the box based on the position. Then on mouseup you remove the onmousemove listener.
https://jsfiddle.net/47nmp90w/
dragBox = (function() {
var _curX;
var _curY;
var _workingEl;
var _docEl = document.documentElement;
if (_docEl.scrollTop === 0) {
var testDocEl = _docEl.scrollTop;
_docEl.scrollTop++;
_docEl = testDocEl+1 === _docEl.scrollTop-- ? _docEl : document.body;
}
return {
drag: function(e) {
var evt = e ? e : window.event;
_width = Math.abs(_curX - evt.clientX);
_height = Math.abs(_curY - evt.clientY);
if (evt.shiftKey) {
var minDimension = Math.min(_width, _height) + 'px';
_workingEl.style.width = minDimension;
_workingEl.style.height = minDimension;
} else {
_workingEl.style.width = _width + 'px';
_workingEl.style.height = _height + 'px';
}
_workingEl.style.left = Math.min(_curX, evt.clientX) + _docEl.scrollLeft + 'px';
_workingEl.style.top = Math.min(_curY, evt.clientY) + _docEl.scrollTop + 'px';
},
draw: function(e) {
var evt = e ? e : window.event;
if (evt.which === 1) {
_curX = evt.clientX;
_curY = evt.clientY;
_workingEl = document.createElement('div');
_workingEl.className = 'drawing';
document.body.appendChild(_workingEl);
window.onmousemove = dragBox.drag;
window.onmouseup = function() {
window.onmousemove = null;
_workingEl.className = 'done';
_workingEl = false;
}
}
}
};
})();
window.onmousedown = dragBox.draw;
Edit
Here is how you would create a box with a set a data. You just set height and width styles, then give it a left position equal to your x coordinate and a top position of your y coordinate.
https://jsfiddle.net/RDay/47nmp90w/4/
var createButton = document.getElementById('create');
var xPosInput = document.getElementById('x-pos');
var yPosInput = document.getElementById('y-pos');
var widthInput = document.getElementById('width');
var heightInput = document.getElementById('height');
var target = document.getElementById('target');
createButton.onclick = function() {
var xPos = xPosInput.value;
var yPos = yPosInput.value;
var width = widthInput.value;
var height = heightInput.value;
var box = document.createElement('div');
box.className = 'box';
box.style.left = xPos + 'px';
box.style.top = yPos + 'px';
box.style.width = width + 'px';
box.style.height = height + 'px';
box.style.left = xPos + 'px';
target.appendChild(box);
};
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
How to set on click event in moving object in canvas? Also how to move the object bottom to top in canvas.I am newly in javascript i am going to develop the sample like when the page open, objects like square and circle randomly come from bottom of the page and move to top automatically.
You need to establish an array that will have your moving objects in it. When the onclick handler fires, check to see if the coordinates of the click are inside any of the objects in the array.
On each animation frame, move your objects up by subtracting some of the y coordinate from each object.
//width and height of canvas...
var rW = 400;
var rH = 500;
var coinImage = getCoinImage();
var coinsOnScreen = [];
var risingSpeed = 100; //pixels per second...
var coinSize = 75;
var lastAnimationTime = 0;
var howLongUntilNextCoin = 1000;
var nextCoinOnScreen = 0;
function doDraw() {
var can = document.getElementById("myCanvas");
can.width = rW;
can.height = rH;
var context = can.getContext("2d");
//Erase the canvas
context.fillStyle = "#FFFFFF";
context.fillRect(0, 0, rW, rH);
if (new Date().getTime() - nextCoinOnScreen > 0) {
var newX = Math.floor(Math.random() * rW) + 1;
var newY = rH + 50;
var newCoin = {
x: newX,
y: newY
};
coinsOnScreen.push(newCoin);
nextCoinOnScreen = new Date().getTime() + howLongUntilNextCoin;
}
//Now draw the coins
if (lastAnimationTime != 0) {
var deltaTime = new Date().getTime() - lastAnimationTime;
var coinRisePixels = Math.floor((deltaTime * risingSpeed) / 1000);
var survivingCoins = [];
for (var i = 0; i < coinsOnScreen.length; i++) {
var coin = coinsOnScreen[i];
coin.y = coin.y - coinRisePixels;
//the stl variable controlls the alpha of the image
if (coin.y + 50 > 0) {
context.drawImage(coinImage, coin.x, coin.y);
//this coin is still on the screen, so promote it to the new array...
survivingCoins.push(coin);
}
}
coinsOnScreen = survivingCoins;
}
lastAnimationTime = new Date().getTime();
//Wait, and then call this function again to animate:
setTimeout(function() {
doDraw();
}, 30);
}
function setupClickHandler() {
var can = document.getElementById("myCanvas");
//Here is the onclick handler
can.onclick = function(e) {
var x = e.clientX;
var y = e.clientY;
var survivingCoins = [];
for (var i = 0; i < coinsOnScreen.length; i++) {
var coin = coinsOnScreen[i];
//check to see if this coin has been clicked...
if (x > coin.x && x < coin.x + coinSize && y > coin.y && y < coin.y + coinSize) {
//ths coin will disappear because it is not inserted into the new array...
console.log("Coin was clicked!! " + x + " " + y);
} else {
survivingCoins.push(coin);
}
}
coinsOnScreen = survivingCoins;
};
}
doDraw();
setupClickHandler();
function getCoinImage() {
var image = new Image(50, 50);
image.src = "data:image/png;base64,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";
return image;
}
<canvas id="myCanvas"></canvas>