How we can utilize resize method in javascript - javascript

I am a noob in javascript so anyone please help me, When I zoomed in on the image and if the mouse out from that image it will return its original size how we did that through resize method that given in "imageviewer2.js".
The image is zoomed in million times but when the mouse cursor is out from the image div it will not return its original size how we can do it by resize method.
I did that mouseout method but that is a patchwork so I want with the resize method but I can't understand how I can do that from resize method.
/*
* imgViewer2
*
*
* Copyright (c) 2013 Wayne Mogg
* Licensed under the MIT license.
*/
var waitForFinalEvent = (function () {
var timers = {};
return function (callback, ms, uniqueId) {
if (!uniqueId) {
uniqueId = "Don't call this twice without a uniqueId";
}
if (timers[uniqueId]) {
clearTimeout (timers[uniqueId]);
}
timers[uniqueId] = setTimeout(callback, ms);
};
})();
/*
* imgViewer2 plugin starts here
*/
;(function($) {
$.widget("wgm.imgViewer2", {
options: {
zoomStep: 0.5,
zoomMax: undefined,
zoomable: true,
dragable: true,
onClick: $.noop,
onReady: $.noop
},
_create: function() {
var self = this;
if (!$(this.element).is("img")) {
var elem = this.element.children()[0];
if (!$(elem).is("img")) {
$.error('imgviewer plugin can only be applied to img elements');
} else {
self.img = self.element.children()[0];
}
} else {
self.img = self.element[0];
}
// the original img element
var $img = $(self.img);
/*
* a copy of the original image to be positioned over it and manipulated to
* provide zoom and pan
*/
self.view = $("<div class='viewport' />").uniqueId().appendTo($img.parent());
var $view = $(self.view);
self.map = {};
self.bounds = {};
// a flag used to check the target image has loaded
self.ready = false;
self.resize = false;
$img.one("load",function() {
// get and some geometry information about the image
self.ready = true;
var width = $img.width(),
height = $img.height(),
offset = $img.position();
// cache the image padding information
self.offsetPadding = {
top: parseInt($img.css('padding-top'),10),
left: parseInt($img.css('padding-left'),10),
right: parseInt($img.css('padding-right'),10),
bottom: parseInt($img.css('padding-bottom'),10)
};
/*
* cache the image margin/border size information
* because of IE8 limitations left and right borders are assumed to be the same width
* and likewise top and bottom borders
*/
self.offsetBorder = {
x: Math.round(($img.outerWidth()-$img.innerWidth())/2),
y: Math.round(($img.outerHeight()-$img.innerHeight())/2)
};
/*
* define the css style for the view container using absolute positioning to
* put it directly over the original image
*/
var vTop = offset.top + self.offsetBorder.y + self.offsetPadding.top,
vLeft = offset.left + self.offsetBorder.x + self.offsetPadding.left;
$view.css({
position: "absolute",
overflow: "hidden",
top: vTop+"px",
left: vLeft+"px",
width: width+"px",
height: height+"px"
});
// add the leaflet map
self.bounds = L.latLngBounds(L.latLng(0,0), L.latLng(self.img.naturalHeight,self.img.naturalWidth));
self.map = L.map($view.attr('id'), {crs:L.CRS.Simple,
minZoom: -10,
trackresize: false,
maxBoundsViscosity: 1.0,
attributionControl: false,
inertia: false,
zoomSnap: 0,
wheelPxPerZoomLevel: Math.round(36/self.options.zoomStep),
zoomDelta: self.options.zoomStep
});
self.zimg = L.imageOverlay(self.img.src, self.bounds).addTo(self.map);
self.map.options.minZoom = self.map.getBoundsZoom(self.bounds,false);
self.map.fitBounds(self.bounds);
self.bounds = self.map.getBounds();
self.map.setMaxBounds(self.bounds);
if (self.options.zoomMax !== null) {
var lzoom = self.leafletZoom(self.options.zoomMax);
if (lzoom < self.map.getZoom()) {
self.map.setZoom(lzoom);
}
self.map.options.maxZoom = lzoom;
}
if (!self.options.dragable) {
self.map.dragging.disable();
}
if (!self.options.zoomable) {
self.map.zoomControl.disable();
self.map.boxZoom.disable();
self.map.touchZoom.disable();
self.map.doubleClickZoom.disable();
self.map.scrollWheelZoom.disable();
}
self.map.on('click', function(ev) {
if (self.options.onClick !== null) {
self.options.onClick.call(self, ev.originalEvent, self.eventToImg(ev));
}
});
self.map.on('zoomend', function() {
if (self.options.zoomMax >= 1 && this.getZoom() > this.options.zoomMax) {
this.setZoom(this.options.zoomMax);
}
if (!self.resize) {
self.bounds = self.map.getBounds();
}
});
self.map.on('moveend', function() {
if (!self.resize) {
self.bounds = self.map.getBounds();
}
});
self.map.on('resize', function() {
self.map.options.minZoom = -10;
self.map.fitBounds(self.bounds,{animate:false});
self.map.options.minZoom = self.map.getBoundsZoom(L.latLngBounds(L.latLng(0,0), L.latLng(self.img.naturalHeight,self.img.naturalWidth)),true);
self.map.options.maxZoom = self.leafletZoom(self.options.zoomMax);
waitForFinalEvent(function(){
self.resize = false;
self._view_resize();
self.map.options.minZoom = -10;
self.map.fitBounds(self.bounds,{animate:false});
self.map.options.minZoom = self.map.getBoundsZoom(L.latLngBounds(L.latLng(0,0), L.latLng(self.img.naturalHeight,self.img.naturalWidth)),true);
self.map.options.maxZoom = self.leafletZoom(self.options.zoomMax);
}, 300, $img[0].id);
});
self.options.onReady.call(self);
}).each(function() {
if (this.complete) { $(this).trigger("load"); }
});
/*
/*
* Window resize handler
*/
$(window).resize(function() {
if (self.ready) {
self.resize = true;
self._view_resize();
self.map.invalidateSize({animate: false});
}
});
},
/*
* View resize - the aim is to keep the view centered on the same location in the original image
*/
_view_resize: function() {
if (this.ready) {
var $view = $(this.view),
$img = $(this.img),
width = $img.width(),
height = $img.height(),
offset = $img.position(),
vTop = Math.round(offset.top + this.offsetBorder.y + this.offsetPadding.top),
vLeft = Math.round(offset.left + this.offsetBorder.x + this.offsetPadding.left);
$view.css({
top: vTop+"px",
left: vLeft+"px",
width: width+"px",
height: height+"px"
});
}
},
/*
* Remove the plugin
*/
destroy: function() {
$(window).unbind("resize");
this.map.remove();
$(this.view).remove();
$.Widget.prototype.destroy.call(this);
},
_setOption: function(key, value) {
switch(key) {
case 'zoomStep':
if (parseFloat(value) <= 0 || isNaN(parseFloat(value))) {
return;
}
break;
case 'zoomMax':
if (parseFloat(value) < 1 || isNaN(parseFloat(value))) {
return;
}
break;
}
var version = $.ui.version.split('.');
if (version[0] > 1 || version[1] > 8) {
this._super(key, value);
} else {
$.Widget.prototype._setOption.apply(this, arguments);
}
switch(key) {
case 'zoomStep':
if (this.ready) {
this.map.options.zoomDelta = this.options.zoomStep;
this.map.options.wheelPxPerZoomLevel = Math.round(60/this.options.zoomStep);
}
break;
case 'zoomMax':
if (this.ready) {
lzoom = this.leafletZoom(this.options.zoomMax);
if (lzoom < this.map.getZoom()) {
this.map.setZoom(lzoom);
}
this.map.options.maxZoom = lzoom;
this.map.fire('zoomend');
}
break;
case 'zoomable':
if (this.options.zoomable) {
this.map.zoomControl.enable();
this.map.boxZoom.enable();
this.map.touchZoom.enable();
this.map.doubleClickZoom.enable();
this.map.scrollWheelZoom.enable();
} else {
this.map.zoomControl.disable();
this.map.boxZoom.disable();
this.map.touchZoom.disable();
this.map.doubleClickZoom.disable();
this.map.scrollWheelZoom.disable();
}
break;
case 'dragable':
if (this.options.dragable) {
this.map.dragging.enable();
} else {
this.map.dragging.disable();
}
break;
}
},
/*
* Test if a relative image coordinate is visible in the current view
*/
isVisible: function(relx, rely) {
var view = this.getView();
if (view) {
return (relx >= view.left && relx <= view.right && rely >= view.top && rely <= view.bottom);
} else {
return false;
}
},
/*
* Convert a user supplied zoom to a Leaflet zoom
*/
leafletZoom: function(zoom) {
if (this.ready && zoom !== undefined) {
var img = this.img,
map = this.map,
lzoom = map.getZoom() || 0,
size = map.getSize(),
width = img.naturalWidth,
height = img.naturalHeight,
nw = L.latLng(height/zoom,width/zoom),
se = L.latLng(0,0),
boundsSize = map.project(nw, lzoom).subtract(map.project(se, lzoom));
var scale = Math.min(size.x / boundsSize.x, -size.y / boundsSize.y);
return map.getScaleZoom(scale, lzoom);
} else {
return undefined;
}
},
/*
* Get the Leaflet map object
*/
getMap: function() {
if (this.ready) {
return this.map;
}
else {
return null;
}
},
/*
* Get current zoom level
* Returned zoom will always be >=1
* a zoom of 1 means the entire image is just visible within the viewport
* a zoom of 2 means half the image is visible in the viewport etc
*/
getZoom: function() {
if (this.ready) {
var img = this.img,
map = this.map,
width = img.naturalWidth,
height = img.naturalHeight,
constraint = this.options.constraint,
bounds = map.getBounds();
if (constraint == 'width' ) {
return Math.max(1, width/(bounds.getEast()-bounds.getWest()));
} else if (constraint == 'height') {
return Math.max(1,height/(bounds.getNorth()-bounds.getSouth()));
} else {
return Math.max(1, (width/(bounds.getEast()-bounds.getWest()) + height/(bounds.getNorth()-bounds.getSouth()))/2);
}
} else {
return null;
}
},
/*
* Set the zoom level
* Zoom must be >=1
* a zoom of 1 means the entire image is just visible within the viewport
* a zoom of 2 means half the image is visible in the viewport etc
*/
setZoom: function( zoom ) {
if (this.ready) {
zoom = Math.max(1, zoom);
if (this.options.zoomMax === undefined) {
} else {
zoom = Math.min(zoom, this.options.zoomMax);
}
var img = this.img,
map = this.map,
width = img.naturalWidth,
height = img.naturalHeight,
constraint = this.options.constraint,
center = map.getCenter(),
bounds = map.getBounds();
var hvw, hvh;
if (constraint == 'width') {
hvw = width/zoom/2;
hvh = hvw * (bounds.getNorth()-bounds.getSouth())/(bounds.getEast()-bounds.getWest());
} else if (constraint == 'height') {
hvh = height/zoom/2;
hvw = hvh * (bounds.getEast()-bounds.getWest())/(bounds.getNorth()-bounds.getSouth());
} else {
hvw = width/zoom/2;
hvh = height/zoom/2;
}
var east = center.lng + hvw,
west = center.lng - hvw,
north = center.lat + hvh,
south = center.lat - hvh;
if (west<0) {
east += west;
west = 0;
} else if (east > width) {
west -= east-width;
east = width;
}
if (south<0) {
north += south;
south = 0;
} else if (north > height) {
south -= north-height;
north = height;
}
map.fitBounds(L.latLngBounds(L.latLng(south,west), L.latLng(north,east)),{animate:false});
}
return this;
},
/*
* Get relative image coordinates of current view
*/
getView: function() {
if (this.ready) {
var img = this.img,
width = img.naturalWidth,
height = img.naturalHeight,
bnds = this.map.getBounds();
return {
top: 1 - bnds.getNorth()/height,
left: bnds.getWest()/width,
bottom: 1 - bnds.getSouth()/height,
right: bnds.getEast()/width
};
} else {
return null;
}
},
/*
* Pan the view to be centred at the given relative image location
*/
panTo: function(relx, rely) {
if ( this.ready && relx >= 0 && relx <= 1 && rely >= 0 && rely <=1 ) {
var img = this.img,
map = this.map,
bounds = this.bounds,
// bounds = map.getBounds(),
east = bounds.getEast(),
west = bounds.getWest(),
north = bounds.getNorth(),
south = bounds.getSouth(),
centerX = (east+west)/2,
centerY = (north+south)/2,
width = img.naturalWidth,
height = img.naturalHeight,
newY = (1-rely)*height,
newX = relx*width;
east += newX - centerX;
west += newX - centerX;
north += newY - centerY;
south += newY - centerY;
if (west<0) {
east -= west;
west = 0;
}
if (east > width) {
west -= east-width;
east = width;
}
if (south<0) {
north -= south;
south = 0;
}
if (north > height) {
south -= north-height;
north = height;
}
map.fitBounds(L.latLngBounds(L.latLng(south,west), L.latLng(north,east)),{animate:false});
}
return this;
},
/*
* Return the relative image coordinate for a Leaflet event
*/
eventToImg: function(ev) {
if (this.ready) {
var img = this.img,
width = img.naturalWidth,
height = img.naturalHeight;
relx = ev.latlng.lng/width;
rely = 1 - ev.latlng.lat/height;
if (relx>=0 && relx<=1 && rely>=0 && rely<=1) {
return {x: relx, y: rely};
} else {
return null;
}
} else {
return null;
}
},
/*
* Convert relative image coordinate to Leaflet LatLng point
*/
relposToLatLng: function(x,y) {
if (this.ready) {
var img = this.img,
width = img.naturalWidth,
height = img.naturalHeight;
return L.latLng((1-y)*height, x*width);
} else {
return null;
}
},
/*
* Convert relative image coordinate to Image pixel
*/
relposToImage: function(pos) {
if (this.ready) {
var img = this.img,
width = img.naturalWidth,
height = img.naturalHeight;
return {x: Math.round(pos.x*width), y: Math.round(pos.y*height)};
} else {
return null;
}
}
});
})(jQuery);
<!DOCTYPE html>
<html>
<head>
<title>imgViewer2 Plugin - custom onClick callback example</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" media="screen">
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.3/dist/leaflet.css" />
<script type="text/javascript" src="https://unpkg.com/leaflet#1.0.3/dist/leaflet.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="lib/imgViewer2.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes" />
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" style="width: 100%; min-width: 320px;">
<tr>
<td style="padding: 10px">
<h1 align="center">imgViewer2 Plugin - custom onClick callback example</h1>
<div align="center">
<img id="image1" src="https://media.gettyimages.com/photos/laughing-black-man-wearing-backpack-near-purple-door-picture-id573064079" style="border: 30px solid #555; padding:20px;" width="80%" />
</div>
<p style="margin:10px 5% 10px 5%;text-align: justify;">
This example demonstrates the widget with a custom "onClick" callback. In this case clicking on the image will show the page pixel coordinates, image pixel coordinates and relative image coordinates (relative image coordinates range from 0,0 to 1,1 where 0,0 is the top-left corner and 1,1 is the bottom-right corner of the image) in a modal dialog.
</p>
<p style="margin:10px 5% 10px 5%;text-align: justify;">
Zoom in and out using the mousewheel, +/- controls, double click/tap or hold the shift key and drag out a rectangle. Left mouseclick and drag to pan. On touch enable devices pinch gestures can be used to zoom in and out and tap and drag to pan around.
</p>
<p style="margin:10px 5% 10px 5%;">Resize the window and try again</p>
</td>
</tr>
</table>
<script type="text/javascript">
;(function($) {
$(document).ready(function(){
var $img = $("#image1").imgViewer2({
onReady: function() {
$('.leaflet-grab').css('cursor','crosshair');
},
onClick: function( e, pos ) {
var $message = $("<div id='dialog-modal'></div>").dialog({
modal: true,
title: "You clicked at:",
open: function(ev, ui) {
$('.ui-dialog').css('z-index',2001);
$('.ui-widget-overlay').css('z-index',2000);
}
});
var imgpos = this.relposToImage(pos);
$message.html("Page X: " + e.pageX + "<br/>Page Y: " + e.pageY + "<br/>Image Pixel X: " + imgpos.x + "<br/>Image Pixel Y: " + imgpos.y + "<br/>Image Rel X: " + pos.x.toFixed(3) + "<br/>Image Rel Y: " + pos.y.toFixed(3));
}
});
});
})(jQuery);
</script>
</body>
</html>

Related

How can I make images going down the screen randomly and at a certain speed (video game js)?

I am building a game where a spaceship moves into the screen with PC controllers. Now, my remaining part is to make a fireball images drop of the screen randomly with a precise speed and quantity (because the image is only one, we have to multiplicate it). Can someone achieve this?
Here is the code:
Fireball image:
<img src="Photo/fireball.png" id="fireball">
Spaceship image:
<img src="Photo/Spaceship1.png" id="icon-p">
Spaceship moving with controllers + prevent it from going out of screen:
let display = document.getElementById("body");
let rect = icon;
let pos = { top: 1000, left: 570 };
const keys = {};
window.addEventListener("keydown", function(e) {
keys[e.keyCode] = true
});
window.addEventListener("keyup", function(e) {
keys[e.keyCode] = false
});
const loop = function() {
if (keys[37] || keys[81]) { pos.left -= 10; }
if (keys[39] || keys[68]) { pos.left += 10; }
if (keys[38] || keys[90]) { pos.top -= 10; }
if (keys[40] || keys[83]) { pos.top += 10; }
var owidth = display.offsetWidth;
var oheight = display.offsetHeight;
var iwidth = rect.offsetWidth;
var iheight = rect.offsetHeight;
if (pos.left < 0) { pos.left = -10; }
if (pos.top < 0) { pos.top = -10; }
if (pos.left + iwidth >= owidth) { pos.left = owidth - iwidth; }
if (pos.top + iheight >= oheight) { pos.top = oheight - iheight; }
rect.setAttribute("data", owidth + ":" + oheight);
rect.style.left = pos.left + "px";
rect.style.top = pos.top + "px";
};
let sens = setInterval(loop, 1000 / 60);
// Random X coordiante
function rndScreenX(offset) {
return Math.floor(Math.random() * (window.innerWidth - offset));
}
// Set fireball coordinates (X is random)
let fireballElement = document.querySelector('#fireball');
let fireball = {
x: rndScreenX(fireballElement.offsetWidth),
y: 0
}
const loop = function() {
// Change fireball Y
fireball.y += 10;
fireballElement.style.top = fireball.y + 'px';
if (fireball.y > window.innerHeight) {
// Fireball is out of window
// Reset Y and get new random X
fireball.x = rndScreenX(fireballElement.offsetWidth);
fireballElement.style.left = fireball.x + 'px';
fireball.y = 0;
}
};
fireballElement.style.left = fireball.x + 'px';
let sens = setInterval(loop, 1000 / 60);
#fireball {
position: absolute;
/* Ignore this rule if you're using an image */
width: 50px;
height: 50px;
background: red;
border-radius: 40% 40% 50% 50%;
}
<img src="Photo/fireball.png" id="fireball">
This solution includes three configurable variables: spawnRate, advanceRate, and fallDistance. It uses them to determine how often new fireballs spawn, how often they move down the screen, and how far they move on each 'tick'.
The "main" part of the script consists of two setInterval calls, one to handle spawning new fireballs, and the other to handle advancing them down the screen.
(See the in-code comments for further explanation.)
const
display = document.getElementById("display"), // Container element
fireballs = [], // Array to hold all fireball objects
fallDistance = 6; // Measured in `vh` units (but could be whatever)
spawnRate = 2000,
advanceRate = 500;
// Adds the first fireball immediately
spawnFireball(fireballs);
// Moves all fireballs down every 500 milliseconds
const advancerTimer = setInterval(
function(){ advanceAll(fireballs, fallDistance, display); },
advanceRate
);
// Spawns a new fireball every 2000 milliseconds
const spawnerTimer = setInterval(
function(){ spawnFireball(fireballs); },
spawnRate
);
// Defines a function to add a fireball to the array
function spawnFireball(fireballs){
const
img = document.createElement("img"), // Element to add to screen
x = Math.floor(Math.random() * 96) + 2, // Random `x` position
y = 3; // `y` position starts near top of screen
img.src = "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.UyMqod0eO6Qcmco1Zrmj0QAAAA%26pid%3DApi&f=1",
img.classList.add("fireball"); // To style fireballs
img.style.left = x + "vw"; // `x` position will never change
newFb = { x, y, img }; // `fb` object includes coords + img element
fireballs.push(newFb); // Adds the new fireball to the array
}
// Defines a function to advance a fireball's position
function advance(fb, distance){
fb.y += distance;
}
// Defines a function to draw a fireball in the container
function draw(fb, container){
if(fb.y > 100){ return; } // Ignores below-screen fireballs
fb.img.style.top = fb.y + "vh"; // Updates the location on screen
container.appendChild(fb.img); // The `img` property holds our DOM element
}
// Defines a function to advance and draw all fireballs
function advanceAll(fireballs, distance, container){
for(let fb of fireballs){
advance(fb, distance);
draw(fb, container)
}
}
#display{ height: 99vh; width: 99vw; position: relative; }
.fireball{ height: 2em; width: 2em; position: absolute; }
<div id="display"></div>

Select marker located below a rectangle selection drawn by user over google maps

code below includes appropriate comments for proper understanding. Please let me know if the question is not clear
My requirement is to get the information of all markers under a rectangle selection made by user over the map. (using control key + mouse down + mouse move event)
I have a list of markers to be plotted in the google map. In order to manipulate it later I have used Custom Overlays provided by the API. it works fine.
Now I need to allow user to draw a rectangle selection by pressing Control key + mouse down. When the mouse moves, a rectangle is drawn over the map and a check is done whether any marker lies below the rectangle drawn. This also works fine.
However If I scroll the map using mouse the values are wrongly calculated and not getting result. i.e the rectangle is not drawn properly.
My analysis is something wrong with the usage of PageX and PageY of mouse move event. Initially I used clientX and clientY, but to account scroll I used PageX and PageY.
What could be wrong here ? Kindly let me know.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Proto 1 displaying a list of cameras with custom markers.</title>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
#rectangle {
position: absolute;
border: 1px solid #c1e0ff;
z-index: 100000;
visibility: hidden;
background-color: #c1e0ff;
opacity: 0.5
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBY_Jb6UGbhR1g9cM3uPGStdevUputZh5s"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
var map;
/* Need to listen for control key + mouse down + mouse move to draw a rectangle over google map and check for markers below the selection*/
document.addEventListener('keydown', multipleCameraSelection);
function multipleCameraSelection(e) {
if (e.ctrlKey) {
map.setOptions({
draggable: false
});
document.onmousedown = function(event) {
/*get div having ID of rectangle.This is created and added to the overlay image pane of map in the draw() function*/
var rectangleDiv = document.getElementById('rectangle');
/*get the co ordinates where mouse is clicked*/
var initialX = event.pageX;
var initialY = event.pageY;
rectangleDiv.style.left = initialX + 'px';
rectangleDiv.style.top = initialY + 'px';
document.onmousemove = function(event) {
/*on mouse move width and height of rectangle is calculated and set*/
var wid = Math.abs(event.pageX - initialX);
var hei = Math.abs(event.pageY - initialY);
rectangleDiv.style.width = wid + 'px';
rectangleDiv.style.height = hei + 'px';
rectangleDiv.style.visibility = 'visible';
if (event.pageX < initialX && event.pageY >= initialY) {
rectangleDiv.style.left = event.pageX + 'px';
} else if (event.pageY <= initialY && event.pageX >= initialX) {
rectangleDiv.style.top = event.pageY + 'px';
} else if (event.pageY < initialY && event.pageX < initialX) {
rectangleDiv.style.left = event.pageX + 'px';
rectangleDiv.style.top = event.pageY + 'px';
}
}
document.onmouseup = function(event) {
document.onmousedown = null;
document.onmousemove = null;
document.onmouseup = null;
rectangleDiv.style.visibility = 'hidden';
/*get the current left , top value of element*/
var rectPos = getOffsetValues(rectangleDiv);
/*all markers have a name starting with cameraDiv. checking whether they lies between the rectangle drawn*/
$("div[id^='cameraDiv']").each(function(index, value) {
var elemToFind = value;
var elemToFindpos = getOffsetValues(elemToFind);
if ((((rectPos.topValue + rectangleDiv.offsetHeight) > elemToFindpos.topValue) && (rectPos.topValue < elemToFindpos.topValue || rectPos.topValue <= (elemToFindpos.topValue + elemToFind.offsetHeight))) &&
(((rectPos.leftValue + rectangleDiv.offsetWidth) > elemToFindpos.leftValue) && (rectPos.leftValue < elemToFindpos.leftValue || rectPos.leftValue <= (elemToFindpos.leftValue + elemToFind.offsetWidth)))) {
console.log(value);
}
})
map.setOptions({
draggable: true
});
}
}
}
}
function getOffsetValues(elem) {
var left = 0,
top = 0;
while (elem) {
left += elem.offsetLeft;
top += elem.offsetTop;
elem = elem.offsetParent;
}
return {
leftValue: left,
topValue: top
};
}
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {
lat: 8.5241,
lng: 76.9366
}
});
overlay = new CameraLayer(map);
//setMarkers(map);
}
var overlay;
CameraLayer.prototype = new google.maps.OverlayView();
function CameraLayer(map) {
this.map_ = map;
this.div_ = null;
this.setMap(map);
//window.alert('constructor called');
}
CameraLayer.prototype.onAdd = function() {
var panes = this.getPanes();
var div = document.createElement('div');
div.style.position = 'absolute';
div.id = 'myCustomdiv';
this.div_ = div;
panes.overlayImage.appendChild(this.div_);
}
CameraLayer.prototype.draw = function() {
/*when a scroll happens replot the markers in correct pixel coordinates using methods exposed by map api*/
while (this.div_.firstChild)
this.div_.removeChild(this.div_.firstChild);
var msgContainer = document.createDocumentFragment();
for (i = 0; i < camerasToPlace.length; i++) {
var lat = camerasToPlace[i];
var lat1 = lat[1];
var lng1 = lat[2];
var latLng = new google.maps.LatLng({
lat: lat1,
lng: lng1
});
var pixelPosition = this.getProjection().fromLatLngToDivPixel(latLng);
//msgContainer.appendChild()
var div1 = document.createElement('div');
div1.id = 'cameraDiv' + i;
div1.style.position = 'absolute';
var img = document.createElement('img');
img.src = 'camera.png';
img.style.position = 'absolute';
//img.style.width = '100%';
//img.style.height = '100%';
div1.style.left = pixelPosition.x + 'px';
div1.style.top = pixelPosition.y + 'px';
//
div1.style.width = '32px';
div1.style.height = '32px';
div1.appendChild(img);
msgContainer.appendChild(div1)
}
/*creating and appending a div to the overlay image , width and height calculated when the mouse move event happens , style applied above*/
var rectDiv = document.createElement('div');
rectDiv.id = 'rectangle';
rectDiv.style.position = 'absolute';
this.div_.appendChild(rectDiv);
/*container holding marker data to plot in map with left and top values*/
this.div_.appendChild(msgContainer);
}
/* a list holding the latitude and longitude values to be used in draw function to plot in map*/
var camerasToPlace = [
['Camera1 located at TVM', 8.545394, 76.883503],
['Camera2 located at TVM', 8.7379, 76.7163],
['Camera3 located at TVM', 8.8932, 76.6141],
['Camera4 located at TVM', 8.7707, 76.8836],
['Camera5 located at TVM', 8.936906, 76.871831],
['Camera6 located at TVM', 8.485295, 76.916806]
];
google.maps.event.addDomListener(window, 'load', initMap);
</script>
</body>
</html>
As suggested by Emmanuel Delay, reworked on this using map events and its working
Here is the code for that, if it helps anyone. Please note we have to do control + mouse down + mouse move to draw a selection. Also the div element holding marker have a predefined name appended to identify it later
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Proto 1 displaying a list of cameras with custom markers.</title>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
#rectangle {
position: absolute;
border: 1px solid #c1e0ff;
z-index: 100000;
visibility: hidden;
background-color: #c1e0ff;
opacity: 0.5
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBY_Jb6UGbhR1g9cM3uPGStdevUputZh5s"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
var map;
var mapMouseMoveHandler;
var mapMouseDownHandler;
var mapMouseUpHandler;
document.addEventListener('keydown', controlKeyDown);
document.addEventListener('keyup', controlKeyUp);
function controlKeyDown(e) {
if (e.ctrlKey) {
mapMouseDownHandler = google.maps.event.addListener(map, 'mousedown', cameraSelectionOnMouseDown);
}
}
function controlKeyUp(e) {
if (e.key == 'Control') {
google.maps.event.removeListener(mapMouseDownHandler);
}
}
function getElementOffsetValues(elem) {
var left = 0,
top = 0;
while (elem) {
left += elem.offsetLeft;
top += elem.offsetTop;
elem = elem.offsetParent;
}
return {
leftValue: left,
topValue: top
};
}
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {
lat: 8.5241,
lng: 76.9366
}
});
overlay = new CameraLayer(map);
//setMarkers(map);
}
function cameraSelectionOnMouseDown(e) {
map.setOptions({
draggable: false
});
var rectangleDiv = document.getElementById('rectangle');
var pixelPosition = overlay.getProjection().fromLatLngToDivPixel(e.latLng);
var initialX = pixelPosition.x;
var initialY = pixelPosition.y;
rectangleDiv.style.left = initialX + 'px';
rectangleDiv.style.top = initialY + 'px';
mapMouseMoveHandler = google.maps.event.addListener(map, 'mousemove', function(e) {
var newXY = overlay.getProjection().fromLatLngToDivPixel(e.latLng);
var wid = Math.abs(newXY.x - initialX);
var hei = Math.abs(newXY.y - initialY);
rectangleDiv.style.width = wid + 'px';
rectangleDiv.style.height = hei + 'px';
rectangleDiv.style.visibility = 'visible';
if (newXY.x < initialX && newXY.y >= initialY) {
rectangleDiv.style.left = newXY.x + 'px';
} else if (newXY.y <= initialY && newXY.x >= initialX) {
rectangleDiv.style.top = newXY.y + 'px';
} else if (newXY.y < initialY && newXY.x < initialX) {
rectangleDiv.style.left = newXY.x + 'px';
rectangleDiv.style.top = newXY.y + 'px';
}
})
mapMouseUpHandler = google.maps.event.addListener(map, 'mouseup', function(e) {
google.maps.event.removeListener(mapMouseMoveHandler);
google.maps.event.removeListener(mapMouseUpHandler);
var rectPosition = getElementOffsetValues(rectangleDiv);
$("div[id^='cameraDiv']").each(function(index, value) {
var elemToFind = value;
var elemToFindposition = getElementOffsetValues(elemToFind);
if ((((rectPosition.topValue + rectangleDiv.offsetHeight) > elemToFindposition.topValue) && (rectPosition.topValue < elemToFindposition.topValue || rectPosition.topValue <= (elemToFindposition.topValue + elemToFind.offsetHeight))) &&
(((rectPosition.leftValue + rectangleDiv.offsetWidth) > elemToFindposition.leftValue) && (rectPosition.leftValue < elemToFindposition.leftValue || rectPosition.leftValue <= (elemToFindposition.leftValue + elemToFind.offsetWidth)))) {
console.log(value);
}
})
rectangleDiv.style.visibility = 'hidden';
map.setOptions({
draggable: true
});
});
}
var overlay;
CameraLayer.prototype = new google.maps.OverlayView();
function CameraLayer(map) {
this.map_ = map;
this.div_ = null;
this.setMap(map);
}
CameraLayer.prototype.onAdd = function() {
var panes = this.getPanes();
var div = document.createElement('div');
div.style.position = 'absolute';
div.id = 'myCustomdiv';
this.div_ = div;
panes.overlayImage.appendChild(this.div_);
}
CameraLayer.prototype.draw = function() {
while (this.div_.firstChild)
this.div_.removeChild(this.div_.firstChild);
var msgContainer = document.createDocumentFragment();
for (i = 0; i < camerasToPlace.length; i++) {
var lat = camerasToPlace[i];
var lat1 = lat[1];
var lng1 = lat[2];
var latLng = new google.maps.LatLng({
lat: lat1,
lng: lng1
});
var pixelPosition = this.getProjection().fromLatLngToDivPixel(latLng);
var div1 = document.createElement('div');
div1.id = 'cameraDiv' + i;
div1.style.position = 'absolute';
var img = document.createElement('img');
img.src = 'camera.png';
img.style.position = 'absolute';
//img.style.width = '100%';
//img.style.height = '100%';
div1.style.left = pixelPosition.x + 'px';
div1.style.top = pixelPosition.y + 'px';
//
div1.style.width = '32px';
div1.style.height = '32px';
div1.appendChild(img);
msgContainer.appendChild(div1)
}
var rectDiv = document.createElement('div');
rectDiv.id = 'rectangle';
rectDiv.style.position = 'absolute';
this.div_.appendChild(rectDiv);
this.div_.appendChild(msgContainer);
}
var camerasToPlace = [
['Camera1 located at TVM', 8.545394, 76.883503],
['Camera2 located at TVM', 8.7379, 76.7163],
['Camera3 located at TVM', 8.8932, 76.6141],
['Camera4 located at TVM', 8.7707, 76.8836],
['Camera5 located at TVM', 8.936906, 76.871831],
['Camera6 located at TVM', 8.485295, 76.916806]
];
google.maps.event.addDomListener(window, 'load', initMap);
</script>
</body>
</html>

Fabric.js - Dynamic Crop Area with a rectangle

I want to make and dynamic crop area and found this snippet. It works perfect in normal usage, but when you scaled the original object before making the crop area, the crop zone seems not in the right position. Can you look into this pen for some help ?
var canvas = new fabric.CanvasEx('canvas');
var el;
var object, lastActive, object1, object2;
var cntObj = 0;
var selection_object_left = 0;
var selection_object_top = 0;
var src = "http://fabricjs.com/lib/pug.jpg";
fabric.Image.fromURL('https://omicron.aeon.co/images/08e7f2bb-f2ce-4058-a955-1c8d594468a2/card_SIZED-Aleksandr-Zykov-4975950437_b84f9f9ef8_o.jpg', function (oImg) {
oImg.top = canvas.getHeight()/2 - oImg.getHeight()/2;
oImg.left = canvas.getWidth()/2 - oImg.getWidth()/2;
canvas.add(oImg);
bindCropEvent(oImg);
});
canvas.renderAll();
function bindCropEvent(obj){
obj.on('object:dblclick', function(){
CropMode();
});
};
function CropMode() {
canvas.remove(el);
if (canvas.getActiveObject()) {
object = canvas.getActiveObject();
if (lastActive !== object) {
console.log('different object');
} else {
console.log('same object');
}
if (lastActive && lastActive !== object) {
//lastActive.clipTo = null; results in clip loss
}
el = new fabric.Rect({
fill: 'rgba(0,0,0,0.6)',
originX: 'left',
originY: 'top',
stroke: '#ccc',
strokeDashArray: [2, 2],
opacity: 1,
width: 1,
height: 1,
borderColor: 'red',
cornerColor: 'red',
hasRotatingPoint: false
});
el.left = canvas.getActiveObject().left;
selection_object_left = canvas.getActiveObject().left;
selection_object_top = canvas.getActiveObject().top;
el.top = canvas.getActiveObject().top;
el.width = canvas.getActiveObject().width * canvas.getActiveObject().scaleX;
el.height = canvas.getActiveObject().height * canvas.getActiveObject().scaleY;
//插入
canvas.add(el);
canvas.setActiveObject(el);
el.on('deselected', function(){
console.log('des');
doCrop();
});
} else {
alert("Please select an object or layer");
}
}
function doCrop() {
var eLeft = el.get('left');
var eTop = el.get('top');
var left = eLeft - object.left;
var top = eTop - object.top;
console.log(left, top);
left *= 1;
top *= 1;
console.log(left, top);
var eWidth = el.get('width');
var eHeight = el.get('height');
var eScaleX = el.get('scaleX');
var eScaleY = el.get('scaleY');
var width = eWidth * 1;
var height = eHeight * 1;
object.clipTo = function (ctx) {
ctx.rect(-(eWidth / 2) + left, -(eHeight / 2) + top, parseInt(width * eScaleX), parseInt( height * eScaleY));
}
canvas.remove(el);
lastActive = object;
canvas.renderAll();
}
Thanks !
when you create a rect, you can create new image with toDataURL(). What will be cropped image.
cropOptions = {
left: Math.floor(rect.left),
top: Math.floor(rect.top),
width: Math.floor(rect.width),
height: Math.floor(rect.height)
},
cropDataUrl ;
cropDataUrl = image.toDataURL(cropOptions);
new fabric.Image.fromURL(cropDataUrl, function(img) {
canvas.remove(image,rect).add(img); //this is your cropped image
})

fengyuanchen Cropper - How to Fit Image into Canvas If Rotated?

I gone through documentation of cropper by fengyuanchen. I want the image to be fit by default into canvas if rotated. But I couldnt find a way to achieve this. Any idea how to achieve this functionality?
I want it to be like this to be default: link
Check issue demo here: link
I fixed this behavior but for my special needs. I just needed one rotate button which rotates an image in 90° steps. For other purposes you might extend/change my fix.
It works in "strict" mode by dynamically change the cropbox dimensions.
Here my function which is called, when I want to rotate an image. Ah and additionally the misplacement bug has also been fixed.
var $image;
function initCropper() {
$image = $('.imageUploadPreviewWrap > img').cropper({
autoCrop : true,
strict: true,
background: true,
autoCropArea: 1,
crop: function(e) {
}
});
}
function rotateImage() {
//get data
var data = $image.cropper('getCropBoxData');
var contData = $image.cropper('getContainerData');
var imageData = $image.cropper('getImageData');
//set data of cropbox to avoid unwanted behavior due to strict mode
data.width = 2;
data.height = 2;
data.top = 0;
var leftNew = (contData.width / 2) - 1;
data.left = leftNew;
$image.cropper('setCropBoxData',data);
//rotate
$image.cropper('rotate', 90);
//get canvas data
var canvData = $image.cropper('getCanvasData');
//calculate new height and width based on the container dimensions
var heightOld = canvData.height;
var heightNew = contData.height;
var koef = heightNew / heightOld;
var widthNew = canvData.width * koef;
canvData.height = heightNew;
canvData.width = widthNew;
canvData.top = 0;
if (canvData.width >= contData.width) {
canvData.left = 0;
}
else {
canvData.left = (contData.width - canvData.width) / 2;
}
$image.cropper('setCanvasData', canvData);
//and now set cropper "back" to full crop
data.left = 0;
data.top = 0;
data.width = canvData.width;
data.height = canvData.height;
$image.cropper('setCropBoxData',data);
}
This is my extended code provided by AlexanderZ to avoid cuttong wider images than container :)
var contData = $image.cropper('getContainerData');
$image.cropper('setCropBoxData',{
width: 2, height: 2, top: (contData.height/ 2) - 1, left: (contData.width / 2) - 1
});
$image.cropper('rotate', 90);
var canvData = $image.cropper('getCanvasData');
var newWidth = canvData.width * (contData.height / canvData.height);
if (newWidth >= contData.width) {
var newHeight = canvData.height * (contData.width / canvData.width);
var newCanvData = {
height: newHeight,
width: contData.width,
top: (contData.height - newHeight) / 2,
left: 0
};
} else {
var newCanvData = {
height: contData.height,
width: newWidth,
top: 0,
left: (contData.width - newWidth) / 2
};
}
$image.cropper('setCanvasData', newCanvData);
$image.cropper('setCropBoxData', newCanvData);
Not a direct answer to the question ... but i'm betting many people that use this plugin will find this helpfull..
Made this after picking up #AlexanderZ code to rotate the image.
So ... If you guys want to ROTATE or FLIP a image that has already a crop box defined and if you want that cropbox to rotate or flip with the image ... use these functions:
function flipImage(r, data) {
var old_cbox = $image.cropper('getCropBoxData');
var new_cbox = $image.cropper('getCropBoxData');
var canv = $image.cropper('getCanvasData');
if (data.method == "scaleX") {
if (old_cbox.left == canv.left) {
new_cbox.left = canv.left + canv.width - old_cbox.width;
} else {
new_cbox.left = 2 * canv.left + canv.width - old_cbox.left - old_cbox.width;
}
} else {
new_cbox.top = canv.height - old_cbox.top - old_cbox.height;
}
$image.cropper('setCropBoxData', new_cbox);
/* BUG: When rotated to a perpendicular position of the original position , the user perceived axis are now inverted.
Try it yourself: GO to the demo page, rotate 90 degrees then try to flip X axis, you'll notice the image flippped vertically ... but still ... it fliped in relation to its original axis*/
if ( r == 90 || r == 270 || r == -90 || r == -270 ) {
if ( data.method == "scaleX") {
$image.cropper("scaleY", data.option);
} else {
$image.cropper("scaleX", data.option);
}
} else {
$image.cropper(data.method, data.option);
}
$image.cropper(data.method, data.option);
}
function rotateImage(rotate) {
/* var img = $image.cropper('getImageData'); */
var old_cbox = $image.cropper('getCropBoxData');
var new_cbox = $image.cropper('getCropBoxData');
var old_canv = $image.cropper('getCanvasData');
var old_cont = $image.cropper('getContainerData');
$image.cropper('rotate', rotate);
var new_canv = $image.cropper('getCanvasData');
//calculate new height and width based on the container dimensions
var heightOld = new_canv.height;
var widthOld = new_canv.width;
var heightNew = old_cont.height;
var racio = heightNew / heightOld;
var widthNew = new_canv.width * racio;
new_canv.height = Math.round(heightNew);
new_canv.width = Math.round(widthNew);
new_canv.top = 0;
if (new_canv.width >= old_cont.width) {
new_canv.left = 0;
} else {
new_canv.left = Math.round((old_cont.width - new_canv.width) / 2);
}
$image.cropper('setCanvasData', new_canv);
if (rotate == 90) {
new_cbox.height = racio * old_cbox.width;
new_cbox.width = racio * old_cbox.height;
new_cbox.top = new_canv.top + racio * (old_cbox.left - old_canv.left);
new_cbox.left = new_canv.left + racio * (old_canv.height - old_cbox.height - old_cbox.top);
}
new_cbox.width = Math.round(new_cbox.width);
new_cbox.height = Math.round(new_cbox.height);
new_cbox.top = Math.round(new_cbox.top);
new_cbox.left = Math.round(new_cbox.left);
$image.cropper('setCropBoxData', new_cbox);
}
var photoToEdit = $('.photo_container img');
$( photoToEdit ).cropper({
autoCrop : true,
crop: function(e) {}
});
$("#rotate_left_btn").click( function () {
$( photoToEdit ).cropper('rotate', -90);
var containerHeightFactor = $(".photo_container").height() / $( photoToEdit).cropper('getCanvasData').height;
if ( containerHeightFactor < 1 ) { // if canvas height is greater than the photo container height, then scale (on both x and y
// axes to maintain aspect ratio) to make canvas height fit container height
$( photoToEdit).cropper('scale', containerHeightFactor, containerHeightFactor);
} else if ( $( photoToEdit).cropper('getData').scaleX != 1 || $( photoToEdit).cropper('getData').scaleY != 1 ) { // if canvas height
// is NOT greater than container height but image is already scaled, then revert the scaling cuz the current rotation will bring
// the image back to its original orientation (landscape/portrait)
$( photoToEdit).cropper('scale', 1, 1);
}
}
I Fixed this issue hope fully. i have added or changed the option to 0 (viewMode: 0,). Now its working well.
cropper = new Cropper(image, {
dragMode: 'none',
viewMode: 0,
width: 400,
height: 500,
zoomable: true,
rotatable: true,
crop: function(e) {
}
});
document.getElementById('rotateImg').addEventListener('click', function () {
cropper.rotate(90);
});

Proportion scaling AND stretching of image using anchor points

i have an image with 8 anchor points. Thanks to an example, i've managed to get those on the 4 corners to only scale the picture. But i am having difficulty in making the other 4 to stretch the image ONLY.
The midTop & midBottom anchors shall stretch vertically; the midLeft and midRight anchors shall stretch horizontally. I think it might concern the bounds those anchors can move but i don't know how to proceed.
http://jsfiddle.net/Dppm7/3/ (sorry can't get this to work in jsFiddle)..
The output looks like this.
Please if anyone can help. :)
Some code for the anchors (not all codes for the middle anchors have been implemented):
// Update the positions of handles during drag.
// This needs to happen so the dimension calculation can use the
// handle positions to determine the new width/height.
switch (activeHandleName) {
case "topLeft":
topRight.setY(activeHandle.getY());
midRight.setY(activeHandle.getY());
midTop.setY(activeHandle.getY());
bottomLeft.setX(activeHandle.getX());
midLeft.setX(activeHandle.getX());
midBottom.setX(activeHandle.getX());
break;
case "topRight":
topLeft.setY(activeHandle.getY());
midLeft.setY(activeHandle.getY());
midTop.setY(activeHandle.getY());
bottomRight.setX(activeHandle.getX());
midBottom.setX(activeHandle.getX());
midRight.setX(activeHandle.getX());
break;
case "bottomRight":
bottomLeft.setY(activeHandle.getY());
midBottom.setY(activeHandle.getY());
midLeft.setY(activeHandle.getY());
topRight.setX(activeHandle.getX());
midTop.setX(activeHandle.getX());
midRight.setX(activeHandle.getX());
break;
case "bottomLeft":
bottomRight.setY(activeHandle.getY());
midBottom.setY(activeHandle.getY());
midRight.setY(activeHandle.getY());
topLeft.setX(activeHandle.getX());
midTop.setX(activeHandle.getX());
midLeft.setX(activeHandle.getX());
break;
case "midTop":
topRight.setY(activeHandle.getY());
topLeft.setY(activeHandle.getY());
midRight.setY(activeHandle.getY());
midLeft.setY(activeHandle.getY());
break;
case "midBottom":
bottomRight.setY(activeHandle.getY());
bottomLeft.setY(activeHandle.getY());
midRight.setY(activeHandle.getY());
midLeft.setY(activeHandle.getY());
break;
case "midRight":
topRight.setX(activeHandle.getX());
bottomRight.setX(activeHandle.getX());
midTop.setX(activeHandle.getX());
midBottom.setX(activeHandle.getX());
break;
case "midLeft":
topLeft.setX(activeHandle.getX());
bottomLeft.setX(activeHandle.getX());
midTop.setX(activeHandle.getX());
midBottom.setX(activeHandle.getX());
break;
}
// Calculate new dimensions. Height is simply the dy of the handles.
// Width is increased/decreased by a factor of how much the height changed.
newHeight = bottomLeft.getY() - topLeft.getY();
newWidth = image.getWidth() * newHeight / image.getHeight();
// Move the image to adjust for the new dimensions.
// The position calculation changes depending on where it is anchored.
// ie. When dragging on the right, it is anchored to the top left,
// when dragging on the left, it is anchored to the top right.
if (activeHandleName === "topRight" || activeHandleName === "bottomRight") {
image.setPosition(topLeft.getX(), topLeft.getY());
} else if (activeHandleName === "topLeft" || activeHandleName === "bottomLeft") {
image.setPosition(topRight.getX() - newWidth, topRight.getY());
}
imageX = image.getX();
imageY = image.getY();
// Update handle positions to reflect new image dimensions
topLeft.setPosition(imageX, imageY);
topRight.setPosition(imageX + newWidth, imageY);
bottomRight.setPosition(imageX + newWidth, imageY + newHeight);
bottomLeft.setPosition(imageX, imageY + newHeight);
midTop.setPosition(imageX + image.getWidth() / 2, imageY);
midBottom.setPosition(imageX + image.getWidth() / 2, imageY + newHeight);
midRight.setPosition(imageX + image.getWidth(), imageY + image.getHeight() / 2);
midLeft.setPosition(imageX, imageY + image.getHeight() / 2);
// Set the image's size to the newly calculated dimensions
if (newWidth && newHeight) {
image.setSize(newWidth, newHeight);
}
}
<script>
var imWidth;
var imHeight;
var topRight;
var topLeft;
var bottomLeft;
var width;
var height;
var group;
var bottomRight;
var image;
var aspectRatio;
var oldwidth;
var oldheight;
var oldtopleftX;
var oldtopleftY;
var shrinkLimitBound;
function update(activeAnchor) {
group = activeAnchor.getParent();
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
actRatio=imWidth/imHeight;
shrinkLimitBound=100;
height=bottomLeft.getY() - topLeft.getY();
width=topRight.getX() - topLeft.getX();
newRatio=(width)/(height);
width=actRatio*height;
switch (activeAnchor.getName()) {
case 'topLeft':
if(height<shrinkLimitBound)
{
height=shrinkLimitBound;
width=actRatio*height;;
topRight.setY(bottomRight.getY()-height);
}
else
{
if(anchorY < bottomRight.getY())
topRight.setY(anchorY);
else
topRight.setY(bottomRight.getY()-height);
}
topRight.setX(bottomRight.getX());
bottomLeft.setX(bottomRight.getX()-width);
bottomLeft.setY(bottomRight.getY());
topLeft.setX(bottomRight.getX()-width);
topLeft.setY(bottomRight.getY()-height);
break;
case 'topRight':
if(height<shrinkLimitBound)
{
height=shrinkLimitBound;
width=actRatio*height;;
topLeft.setY(bottomLeft.getY()-height);
}
else
{
if(anchorY < bottomLeft.getY()-shrinkLimitBound)
{
topLeft.setY(anchorY)
}
else
{
topLeft.setY(bottomLeft.getY()-height);
}
}
topLeft.setX(bottomLeft.getX());
bottomRight.setX(bottomLeft.getX()+width);
bottomRight.setY(bottomLeft.getY());
topRight.setX(bottomLeft.getX()+width);
topRight.setY(bottomLeft.getY()-height);
break;
case 'bottomRight':
if(height<shrinkLimitBound)
{
height=shrinkLimitBound;
width=actRatio*height;;
bottomLeft.setY(topLeft.getY()+height);
}
else
{
if(anchorY > topLeft.getY()+shrinkLimitBound)
{
bottomLeft.setY(anchorY);
}
else
bottomLeft.setY(topLeft.getY()+height);
}
bottomLeft.setX(topLeft.getX());
topRight.setX(topLeft.getX()+width);
topRight.setY(topLeft.getY());
bottomRight.setX(topLeft.getX()+width);
bottomRight.setY(topLeft.getY()+height);
break;
case 'bottomLeft':
if(height<shrinkLimitBound)
{
height=shrinkLimitBound;
width=actRatio*height;;
bottomRight.setY(topRight.getY()+height);
}
else
{
if(anchorY > topRight.getY())
bottomRight.setY(anchorY);
else
bottomRight.setY(topRight.getY()+height);
}
bottomRight.setX(topRight.getX());
topLeft.setX(topRight.getX()-width);
topLeft.setY(topRight.getY());
bottomLeft.setX(topRight.getX()-width);
bottomLeft.setY(topLeft.getY()+height);
break;
}
image.setPosition(topLeft.getPosition());
if(width>0 && height>0)
{
image.setSize(width,height);
}
oldwidth=width;
oldheight=height;
oldtopleftX=topLeft.getX();
oldtopleftY=topLeft.getY();
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 0,
radius: 4,
name: name,
draggable: true,
dragOnTop: false
});
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
function initStage(images) {
var conWidth = 578; //container Width.
var conHeight = 400; //container Heitgh.
imWidth = images.dressTrailImage.width;
imHeight = images.dressTrailImage.height;
if (imWidth > conWidth)
{
imHeight = (imHeight/imWidth)*conWidth;
imWidth = conWidth;
}
if (imHeight > conHeight)
{
imWidth = (imWidth/imHeight)*conHeight;
imHeight = conHeight;
}
if ((imHeight < conHeight) && (imWidth < conWidth))
{
var diffX = conWidth - imWidth;
var diffY = conHeight - imHeight;
var diffY2 = (imHeight/imWidth)*diffX;
if (diffY2 > diffY)
{
imWidth = (imWidth/imHeight)*conHeight;
imHeight = conHeight;
}
else
{
imHeight = (imHeight/imWidth)*conWidth;
imWidth = conWidth;
}
}
images.UsrTrail.width = imWidth;
images.UsrTrail.height = imHeight;
var stage = new Kinetic.Stage({
container: 'container',
width: imWidth,
height: imHeight
});
var dressTrailImageGroup = new Kinetic.Group({
x: 0,
y: 0,
draggable: true,
//dragBoundFunc: function(pos) {
// console.log(pos);
// // var newX;
// // var newY;
// console.log(topLeft.x+","+bottomRight.y);
// x1=topLeft.x;
// x2=bottomRight.x;
// y1=topLeft.y;
// y2=bottomRight.y;
// x=pos.x;
// y=pos.y;
// var calsign = ((x-x1)*(y-y2))-((y-y1)*(x-x2))
// if (calsign < 0){
// return {
// x : pos.x,
// y : pos.y
// }
// }else {
// return {
// x : 50,
// y : 50
// }
// }
//}
// if (pos.x < ){
// newX=10;
// }
// else if ((pos.x+dressTrailImage.getWidth()) > stage.getWidth()-50){
// newX = stage.getWidth()-dressTrailImage.getWidth()-50;
// }
// else{
// newX = pos.x;
// };
// if(pos.y < 10){
// newY = 10;
// }
// else if((pos.y + dressTrailImage.getHeight()) > stage.getHeight()-50){
// newY = stage.getHeight()-dressTrailImage.getHeight()-50;
// }
// else {
// newY = pos.y;
// }
//console.log("newX:"+newX+", newY:"+newY);
// return {
// x : newX,
// y : newY,
// };
//}
});
// UsrTrail
var UsrTrailImg = new Kinetic.Image({
x: 0,
y: 0,
image: images.UsrTrail,
width: images.UsrTrail.width,
height: images.UsrTrail.height,
name: 'image'
});
var layer = new Kinetic.Layer();
/*
* go ahead and add the groups
* to the layer and the layer to the
* stage so that the groups have knowledge
* of its layer and stage
*/
layer.add(dressTrailImageGroup);
layer.add(UsrTrailImg);
stage.add(layer);
UsrTrailImg.moveToBottom();
intialAspRatio = images.dressTrailImage.width/images.dressTrailImage.height;
console.log("aspectRatio is :"+intialAspRatio);
// dress Trail Image
var inith=200; //set this to the desired height of the dress that shows up initially
var initw=intialAspRatio*inith;
var neck_user_x=50;//from backend
var neck_user_y=20;//from backend
var neck_dress_x=50;//from backend
var neck_dress_y=5;//from backend
//for getting the actual width and height of the User's Image
var UsrImgObjActual= new Image();
UsrImgObjActual.src=sources.UsrTrail;
UsrimgWidth=UsrImgObjActual.width;
UsrimgHeight=UsrImgObjActual.height;
//////////////////////////////////////////
// var UsrimgWidth= 180;
// var UsrimgHeight=270;
console.log("height Should Be 270 and is:"+UsrimgHeight);
console.log("Width Should Be 180 and is:"+UsrimgWidth);
var dressimgWidth=initw;
var dressimgHeight=inith;
console.log("usertrail image width adn height"+images.UsrTrail.width+"::"+images.UsrTrail.height);
console.log("neck user and dress resp"+neck_user_x+","+neck_user_y+','+neck_dress_x+','+neck_dress_y);
var x_draw=((neck_user_x*UsrimgWidth)-(neck_dress_x*dressimgWidth));
var y_draw=((neck_user_y*UsrimgHeight)-(neck_dress_y*dressimgHeight));
x_draw=x_draw/100;
y_draw=y_draw/100;
console.log("xdraw and ydraw:"+x_draw+','+y_draw);
//top left corner coordinates of the dress image.
var initx=x_draw;
var inity=y_draw;
var dressTrailImage = new Kinetic.Image({
x: initx,
y: inity,
image: images.dressTrailImage,
name: 'image',
width: initw,// images.dressTrailImage.width,
height: inith //images.dressTrailImage.height
});
// dressTrailImage.width = 50;
// dressTrailImage.height = dressTrailImage.width / intialAspRatio;
// console.log(dressTrailImage.height);
dressTrailImageGroup.add(dressTrailImage);
addAnchor(dressTrailImageGroup, initx , inity, 'topLeft');
addAnchor(dressTrailImageGroup, initx + initw , inity , 'topRight');
addAnchor(dressTrailImageGroup, initx + initw , inity + inith, 'bottomRight');
addAnchor(dressTrailImageGroup, initx , inity + inith, 'bottomLeft');
topLeft = dressTrailImageGroup.get('.topLeft')[0];
topRight = dressTrailImageGroup.get('.topRight')[0];
bottomRight = dressTrailImageGroup.get('.bottomRight')[0];
bottomLeft = dressTrailImageGroup.get('.bottomLeft')[0];
image = dressTrailImageGroup.get('.image')[0];
dressTrailImageGroup.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
}
var sources = {
dressTrailImage: "http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg",
UsrTrail: "http://www.html5canvastutorials.com/demos/assets/yoda.jpg"
};
loadImages(sources, initStage);
//function called on clicking the submit button.
function Sunmit_fn(){
//neck positions of the trail dress in percentages (assumed for now!).
neckDressX=50;//in percentage.
neckDressY=5;//in percentage.
//height and width of the user image used in the canvas.
//original here here is refered to the height and width used in the canavs
var originalUserImgWidth = imWidth;
var originalUserImgHeight = imHeight;
var trailDressWidth = image.getWidth();//Final Image Width
var trailDressHeight = image.getHeight();//Final Image Height
imageX=topLeft.getParent().getX()+topLeft.getX()+1;//upper right anchor X Position
imageY=topLeft.getParent().getY()+topLeft.getY()+1;//upper right anchor Y Position
//formula for calculating the final neck positions of the resized and dragged dress
//with respect to the user image in percentages
neckFinalX=(imageX+(trailDressWidth*(neckDressX/100)))/originalUserImgWidth;
neckFinalY=(imageY+(trailDressHeight*(neckDressY/100)))/originalUserImgHeight;
//neck in percentages trail pic neck x,y.
neckFinalX=neckFinalX*100;
neckFinalY=neckFinalY*100;
//Just for testing.
console.log("neck position updated by User:");
console.log("X:"+neckFinalX+", Y:"+neckFinalY+")");
console.log("Resized Size of the dress is:");
console.log("Width:"+trailDressWidth+", Height:"+trailDressHeight);
}
</script>
This Script resizes only along one axis for four points.You can figure out the same for all the points

Categories

Resources