canvas closePath on finger release on iPad - html

I'm trying to use canvas object on iPad; the user need to draw a free curve with the finger and when he releases the finger the system must close the curve and fill it.
Actually I wrote down the following code but the problem is that it draws but it does not close the path on finger release.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=768px, maximum-scale=1.0" />
<title>sketchpad</title>
<script type="text/javascript" charset="utf-8">
window.addEventListener('load',function(){
// get the canvas element and its context
var canvas = document.getElementById('sketchpad');
var context = canvas.getContext('2d');
var img = new Image();
img.src = 'imp_02.jpg';
context.drawImage(img,0,0,600,600);
var colorPurple = "#cb3594";
context.strokeStyle=colorPurple;
context.lineWidth = 5;
context.fillStyle = "red";
// create a drawer which tracks touch movements
var drawer = {
isDrawing: false,
touchstart: function(coors){
context.beginPath();
context.moveTo(coors.x, coors.y);
this.isDrawing = true;
},
touchmove: function(coors){
if (this.isDrawing) {
context.lineTo(coors.x, coors.y);
context.stroke();
}
},
touchend: function(coors){
if (this.isDrawing) {
context.touchmove(coors);
context.closePath();
this.isDrawing = false;
}
}
};
// create a function to pass touch events and coordinates to drawer
function draw(event){
// get the touch coordinates
var coors = {
x: event.targetTouches[0].pageX,
y: event.targetTouches[0].pageY
};
// pass the coordinates to the appropriate handler
drawer[event.type](coors);
}
// attach the touchstart, touchmove, touchend event listeners.
canvas.addEventListener('touchstart',draw, false);
canvas.addEventListener('touchmove',draw, false);
canvas.addEventListener('touchend',draw, false);
// prevent elastic scrolling
document.body.addEventListener('touchmove',function(event){
event.preventDefault();
},false); // end body.onTouchMove
},false); // end window.onLoad
</script>
<style type="text/css"><!--
body{margin:0;padding:0; font-family:Arial;}
#container{position:relative;}
#sketchpad{ border: 1px solid #000;}
--></style>
</head>
<body>
<div id="container">
<canvas id="sketchpad" width="766" height="944">
Sorry, your browser is not supported.
</canvas>
</div>
</body>
</html>
I don't understand what I missed.
Is there anyone who can help me..... I would appreciate a lot!!

You are fetching the touch end co-ordinates from a wrong array.
event object has one more array called changedTouches where you can find the co-ordinates of the point where the touch ended. These end co-ordinates are not in targetTouches array.
So you need
endCoordX = event.changedTouches[0].pageX;
endCoordY = event.changedTouches[0].pageY;
[modify the above code to fit into your scenario. hope you got the concept.... And seriuosly i too got stuck on the same point in the past and wasted more than an hour to know this fact....]

Related

Clear canvas drawpad jquery

I'm using the drawing pad (pen tool) plugin of Jquery to draw with different colors and having an image in the canvas as background. My purpose is to have a button to clear the drawing over the canvas. The way I try to do it remove the background image along with the drawing. How can I keep the background and remove the drawing on clicking the clear button ?
My fiddle : https://jsfiddle.net/ub3s9go7/
<script>
$(document).ready(function() {
// set background
var urlBackground = 'https://picsum.photos/id/100/500/400';
var imageBackground = new Image();
imageBackground.src = urlBackground;
imageBackground.setAttribute('crossorigin', 'anonymous');
$("#target").drawpad();
var contextCanvas = $("#target canvas").get(0).getContext('2d');
imageBackground.onload = function(){
contextCanvas.drawImage(imageBackground, 0, 0);
}
// Need to clear only the drawing not the background image
$("#clearDrawing").click(function() {
contextCanvas.clearRect(0, 0, 750, 423);
});
});
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cnbilgin.github.io/jquery-drawpad/jquery-drawpad.css" />
<style>
body {background-color:rgb(248, 255, 227)}
#target {
width:500px;
height:400px;
}
</style>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cnbilgin.github.io/jquery-drawpad/jquery-drawpad.js"></script>
</head>
<body>
<button id="clearDrawing">Clear Drawing</button>
<div id="target" class="drawpad-dashed"></div>
</body>
</html>
This answer is an improvisation on my previous answer at https://stackoverflow.com/a/67155647/3706717
So we have new requirement: delete/clear previous drawings
There are some possible approach here:
#sinisake in comment suggested to reload the background so that we have fresh canvas with only the background intact (but for some reason, white doodle make the background gone)
the library must have "delete" or "erase" doodle feature (which it didn't have)
save each changes of the drawing when user click "save", so that user can "undo" to previous version of the drawing (like git's git commit and git reset command), I'll be using this approach in my answer
Ideally, you should use server-side language and persistent storage (e.g.: database) to store user's doodling history. But in this case, to simulate such thing I'll be using javascript's localStorage API https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
So every time I'm calling localStorage API, just assume that I'm calling some ajax to some endpoint.
Fiddle: https://jsfiddle.net/0da572jy/3/
Here is stack fiddle (modified because browser didn't allow stack fiddle to use localStorage)
// polyfill for localStorage API
var localStorage1 = {
items: {},
removeItem: function(key) {
window.localStorage1.items[key] = null;
},
getItem: function(key) {
return window.localStorage1.items[key];
},
setItem: function(key, val) {
return window.localStorage1.items[key] = val;
},
}
//window.localStorage = localStorage1;
window.localStorage1 = localStorage1;
$(document).ready(function() {
$("#save").click(function() {
// I already explained the #save logic in https://stackoverflow.com/a/67155647/3706717
//console.log("save");
var base64Image = $("#target canvas").get(0).toDataURL();
//console.log(base64Image);
$("#outputBase64FormInput").val(base64Image);
$("#outputBase64").html(base64Image);
// load/read saved states/histories
var savedImageJson = window.localStorage1.getItem("savedImage");
//console.log(savedImageJson);
// if the history is undefined, create empty array
if(savedImageJson == null || typeof savedImageJson == "undefined") savedImageJson = "[]";
// parse the history
var savedImageArr = JSON.parse(savedImageJson);
// add current state as a new item to history
savedImageArr.push(base64Image);
// save the modified (added history)
window.localStorage1.setItem("savedImage", JSON.stringify(savedImageArr));
$("#numOfSavedHistory").html( savedImageArr.length );
});
// clear button just clears the localStorage (or any kind of API you use for persistent storage
$("#clear").click(function() {
//console.log("save");
window.localStorage1.removeItem("savedImage");
$("#numOfSavedHistory").html( 0 );
});
// undo last change (rollback to last state when you clicked save)
$("#undo").click(function() {
// clear canvas (to prevent white ink bug that also clears the background)
canvas.width = canvas.width;
//console.log("undo");
// load/read saved states/histories
var savedImageJson = window.localStorage1.getItem("savedImage");
//console.log(savedImageJson);
// if the history is undefined, create empty array
if(savedImageJson == null || typeof savedImageJson == "undefined") savedImageJson = "[]";
// parse the history
var savedImageArr = JSON.parse(savedImageJson);
// delete last item in history
savedImageArr.pop();
// save the modified (pop'ed history)
window.localStorage1.setItem("savedImage", JSON.stringify(savedImageArr));
// draw old picture on canvas
var imageOld = new Image();
imageOld.src = savedImageArr[savedImageArr.length-1];
imageOld.onload = function() {
contextCanvas.drawImage(imageOld, 0, 0);
};
$("#numOfSavedHistory").html( savedImageArr.length );
});
// set background
var urlBackground = 'https://picsum.photos/id/100/500/400';
var imageBackground = new Image();
imageBackground.src = urlBackground;
//imageBackground.crossorigin = "anonymous";
imageBackground.setAttribute('crossorigin', 'anonymous');
$("#target").drawpad();
var canvas = $("#target canvas").get(0);
var contextCanvas = canvas.getContext('2d');
imageBackground.onload = function(){
contextCanvas.drawImage(imageBackground, 0, 0);
$("#clear").trigger("click"); // clear previous drawings when page refreshed
$("#save").trigger("click"); // save the first image (background only)
}
});
body {background-color:rgb(248, 255, 227)}
#target {
width:500px;
height:400px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cnbilgin.github.io/jquery-drawpad/jquery-drawpad.css" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cnbilgin.github.io/jquery-drawpad/jquery-drawpad.js"></script>
</head>
<body>
<button id="undo">Undo</button>
<button id="save">Save</button>
<button id="clear">Clear Saved Picture</button>
<span id="numOfSavedHistory">0</span>
<div id="target" class="drawpad-dashed"></div>
<div id="outputBase64"></div>
</body>
</html>

Here maps not draggable in ms access webbrowser

I have created a simple html using the draggable marker example from here maps. I have adapted it to support IE 11 by adding reference to legacy js, meta tag and using P2D engine in map options. Also added two url parameters for coordinates. It works perfectly in IE11 and it loads and shows pan and zoom buttons in ms-access webbrowser but it keeps static, it's not draggable, but pan and zoom works.
The curious thing is that if I navigate to wego.here.com in the same webbrowser control then the map is draggable. So they're doing something else in the here maps main page that I'm not doing in my script.
I have also tried using Microsoft Web Browser from the activex controls list in access.
I need it to be draggable so I can pick the coordinates after the user changes the marker position.
This is my script:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Draggable Marker</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-core.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-core-legacy.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-service.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-service-legacy.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-ui.js" type="text/javascript" charset="utf-8"></script>
<script src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js" type="text/javascript" charset="utf-8"></script>
<style>
html, body { margin:0px; padding:0px; width: 100%; height: 100%; }
.main { height: 100%; }
</style>
</head>
<body id="markers-on-the-map">
<div class="main" style="width:100%" id="map"></div>
<input type="hidden" id="long" name="long">
<input type="hidden" id="lat" name="lat">
<script>
function addDraggableMarker(map, behavior){
var marker = new H.map.Marker({lat:latitud, lng:longitud}, {volatility: true});
// Ensure that the marker can receive drag events
marker.draggable = true;
map.addObject(marker);
// disable the default draggability of the underlying map
// and calculate the offset between mouse and target's position
// when starting to drag a marker object:
map.addEventListener('dragstart', function(ev) {
var target = ev.target,
pointer = ev.currentPointer;
if (target instanceof H.map.Marker) {
var targetPosition = map.geoToScreen(target.getGeometry());
target['offset'] = new H.math.Point(pointer.viewportX - targetPosition.x, pointer.viewportY - targetPosition.y);
behavior.disable();
}
}, false);
// re-enable the default draggability of the underlying map
// when dragging has completed
map.addEventListener('dragend', function(ev) {
var target = ev.target;
if (target instanceof H.map.Marker) {
$('#long').val(ev.target.b.lng);
$('#lat').val(ev.target.b.lat);
behavior.enable();
}
}, false);
// Listen to the drag event and move the position of the marker
// as necessary
map.addEventListener('drag', function(ev) {
var target = ev.target,
pointer = ev.currentPointer;
if (target instanceof H.map.Marker) {
target.setGeometry(map.screenToGeo(pointer.viewportX - target['offset'].x, pointer.viewportY - target['offset'].y));
}
}, false);
}
/**
* Boilerplate map initialization code starts below:
*/
//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: '?????????????????????????????????'
});
var defaultLayers = platform.createDefaultLayers();
//url parameters
var query_string = {};
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (typeof query_string[pair[0]] === "undefined") {
query_string[pair[0]] = decodeURIComponent(pair[1]);
} else if (typeof query_string[pair[0]] === "string") {
var arr = [ query_string[pair[0]],decodeURIComponent(pair[1]) ];
query_string[pair[0]] = arr;
} else {
query_string[pair[0]].push(decodeURIComponent(pair[1]));
}
}
var latitud=query_string.lat;
var longitud=query_string.long;
//Step 2: initialize a map - this map is centered over Boston
var map = new H.Map(document.getElementById('map'),
defaultLayers.raster.normal.map, {
center: {lat:latitud, lng:longitud},
engineType: H.map.render.RenderEngine.EngineType.P2D,
zoom: 12,
pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
//window.addEventListener('resize', () => map.getViewPort().resize());
window.addEventListener('resize', function () {map.getViewPort().resize(); });
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
//var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Step 4: Create the default UI:
var ui = H.ui.UI.createDefault(map, defaultLayers, 'en-US');
// Add the click event listener.
addDraggableMarker(map, behavior);
</script>
</body>
</html>```
Check please on this static page
: your code works for my IE11

how to render offscreen canvas properly

I'm trying to create a basic example of offscreen rendering canvas but I'm error in js "cannot read property of context". actually my idea is to create a demo like I saw in https://yalantis.com/ I want to create my name initial. If there is any better idea to achieve this then please enlighten me.
Thanks here is my basic attempt before the actual implementation :)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Off Screen Canvas</title>
<script>
function createOffscreenCanvas() {
var offScreenCanvas= document.createElement('canvas');
offScreenCanvas.width= '1360px';
offScreenCanvas.height= '400px';
var context= offScreenCanvas.getContext("2d");
context.fillRect(10,10,200,200);
}
function copyToOnScreen(offScreenCanvas) {
var onScreenContext=document.getElementById('onScreen').getContext('2d');
var offScreenContext=offScreenCanvas.getContext('2d');
var image=offScreenCanvas.getImageData(10,10,200,200);
onScreenContext.putImageData(image,0,0);
}
function main() {
copyToOnScreen(createOffscreenCanvas());
}
</script>
<style>
#onScreen {
width:1360px;
height: 400px;
}
</style>
</head>
<body onload="main()">
<canvas id="onScreen"></canvas>
</body>
</html>
You could achieve this in the following way ...
function createOffscreenCanvas() {
var offScreenCanvas = document.createElement('canvas');
offScreenCanvas.width = '1360';
offScreenCanvas.height = '400';
var context = offScreenCanvas.getContext("2d");
context.fillStyle = 'orange'; //set fill color
context.fillRect(10, 10, 200, 200);
return offScreenCanvas; //return canvas element
}
function copyToOnScreen(offScreenCanvas) {
var onScreenContext = document.getElementById('onScreen').getContext('2d');
onScreenContext.drawImage(offScreenCanvas, 0, 0);
}
function main() {
copyToOnScreen(createOffscreenCanvas());
}
canvas {
border: 1px solid black;
}
<body onload="main()">
<canvas id="onScreen" width="1360" height="400"></canvas>
note : never set canvas's width and height using css. instead use the native width and height property of the canvas.
You can try to do that with experimental OffScreenCanvas API. I'm leaving the link here.
So you don't actually need a canvas element attached to DOM with this experimental API, furthermore you can perform your drawing in webworkers, so it will not block the browser's main thread if you're drawing thousands of objects.
const offscreen = new OffscreenCanvas(256, 256);
offscreen.getContext("2d") // or webgl, etc.
Please beware that it's experimental. You can try to check like "OffscreenCanvas" in window and use that, if it's not available, you can fallback to document.createElement("canvas").
Return offScreenCanvas in your function createOffscreenCanvas
function createOffscreenCanvas() {
var offScreenCanvas= document.createElement('canvas');
offScreenCanvas.width= '1360px';
offScreenCanvas.height= '400px';
var context= offScreenCanvas.getContext("2d");
context.fillRect(10,10,200,200);
return offScreenCanvas;
}
Edit
You were getting image date from canvas not context.
function copyToOnScreen(offScreenCanvas) {
var onScreenContext=document.getElementById('onScreen').getContext('2d');
var offScreenContext = offScreenCanvas.getContext('2d');
var image=offScreenContext.getImageData(10,10,200,200);
onScreenContext.putImageData(image,0,0);
}

CreateJS - Targeting aspecific key frame

I have an html5 basic presentation that was generated using Flash 6 and CreateJS.
The presentation is basically a bunch of flash keyframes with stop(); commands.
Now, here come my questions:
1. How do I target a specific frame on this presentation, using a link, located on a different page (something like the html anchor) ?
2. is there an easy way to add some cool frames transitions between those frames, using some kind of an open source library?
I'm a designer, not a programmer, so I have only little knowledge in coding.
Any help will be appreciate.
Thanks
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CreateJS export from main</title>
<script src="easeljs-0.6.0.min.js"></script>
<script src="tweenjs-0.4.0.min.js"></script>
<script src="movieclip-0.6.0.min.js"></script>
<script src="preloadjs-0.3.0.min.js"></script>
<script src="main.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
images = images||{};
var manifest = [
{src:"images/bg_b.jpg", id:"bg_b"},
];
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", handleFileLoad);
loader.addEventListener("complete", handleComplete);
loader.loadManifest(manifest);
}
function handleFileLoad(evt) {
if (evt.item.type == "image") { images[evt.item.id] = evt.result; }
}
function handleComplete() {
exportRoot = new lib.main();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener("tick", stage);
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4">
<canvas id="canvas" width="1024" height="768" style="background-color:#FFFFFF"></canvas>
</body>
</html>
CreateJS supports the use of basic actionscript by way of providing direct translations in javascript. For example, if you add the following bit of code to your timeline, the CreateJS publisher is smart enough to add a javascript call to stop the timeline at that position.
/* js
this.stop();
*/
To have a link skip to a location in the main timeline, you would need to use gotoAndPlay, or gotoAndStop depending on whether you want playback to continue. When CreateJS publishes your .fla, it creates a javascript instance of the main timeline movieclip called exportRoot. You can use this instance to manipulate the timeline via javascript.
Question 1: Changing location from another page
Using your code as an example now, notice the index.html page links to your Flash exported page (which I am calling target.html) with different hash tag locations for the frames. Also notice I have added the jquery library to your exported page, and a couple lines after the createjs.Ticker.addEventListener("tick", stage); to gotoAndStop based on the current hash, and to listen to future hash changes to gotoAndStop.
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
Goto frame 5
Goto frame 10
Goto frame 15
Goto frame 20
</body>
</html>
target.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CreateJS export from main</title>
<script src="//code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="easeljs-0.6.0.min.js"></script>
<script src="tweenjs-0.4.0.min.js"></script>
<script src="movieclip-0.6.0.min.js"></script>
<script src="preloadjs-0.3.0.min.js"></script>
<script src="main.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
images = images||{};
var manifest = [
{src:"images/bg_b.jpg", id:"bg_b"},
];
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", handleFileLoad);
loader.addEventListener("complete", handleComplete);
loader.loadManifest(manifest);
}
function handleFileLoad(evt) {
if (evt.item.type == "image") { images[evt.item.id] = evt.result; }
}
function handleComplete() {
exportRoot = new lib.main();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener("tick", stage);
//When doc loads, check if there is a hash and gotoAndStop if there is
if(document.location.hash)
exportRoot.gotoAndStop(document.location.hash.replace('#', ''));
//Use jQUery to listen to the hash change event and gotoAndStop to new location when event fires
$(window).on('hashchange', function() {
exportRoot.gotoAndStop(document.location.hash.replace('#', ''));
});
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4">
<canvas id="canvas" width="1024" height="768" style="background-color:#FFFFFF"></canvas>
</body>
</html>
Question 2: Transitions
As far as page transitions go, I would suggest either creating them in the timeline, and calling gotoAndPlay(FRAME_OF_THE_TRANSITION) until you start to get more comfortable with the CreateJS library to take a more object oriented approach.

Get Image back to its original location

I have the following HTML and JS. When i click on the image the images zooms. This is working. But then I zoom out I want to retract the image to the original location when It was loaded.
Consider image being dragged to right a little and then zoomed.
What I want is when its zoomed out its relocated to the original location when it was loaded.
What am I doing wrong? I need the effect this page has here. When you drag the image and release it, it will go to its original position.
JS
var isZoom=1;
var stage=new Kinetic.Stage({
container:'container',
width:700,
height:700,
id:'kineticstage',
name:'kineticstage'
});
var layer=new Kinetic.Layer({});
var group = new Kinetic.Group({
width:700,
height:700,
draggable: true
});
layer.add(group);
// set the images
var pages = ["http://197.242.159.63/reader/demo/img/face.jpg"];
var loadedPage = 0;
function loadPage(pageno){
var imageObj = new Image();
imageObj.onload = function() {
var kimage = new Kinetic.Image({
x: 0,
y: 0,
image: imageObj,
width:700,
height:700
});
// add to layer
group.add(kimage);
stage.add(layer);
};
// load the page image
imageObj.src = pages[pageno - 1];
}
// page 1
loadPage(1);
var tween = new Kinetic.Tween({
node: group,
duration: 1.0,
rotation:0,
scaleX: 1.5,
scaleY: 1.5,
easing:Kinetic.Easings.EaseInOut
});
group.on('dblclick dbltap',function(e){
if(isZoom == 1){
tween.play();
}
else{
tween.reverse();
}
layer.batchDraw();
isZoom = (isZoom>0) ? -1 : 1;
});
HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" >
<meta name="apple-mobile-web-app-capable" content="yes" >
</head>
<body>
<div id="container"><!-- --></div>
</body>
<script type="text/javascript" language="javascript" src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.0.min.js"></script>
</html>
Fiddle
Dragging your kinetic group will cause its x,y to change.
To "undo" the drag, just reset the group back to its original x,y position:
In your case, you created the group at its default position of 0,0 so reset like this:
group.setX(0);
group.setY(0);