Hello every one i am currently working with html5 and easelJS.I have a canvas and an images on it.What I want is that when I click on the image its copy is created and and when I click on some other place at canvas my images is copied there so leaving two images on my canvas.
I want to ask is there a way by which I can know that whether I am clicking on the image or or on the canvas.and How to make a copy of my image as I have wrote some code but it removes my orignal image and place it to ther place leaving only one image on the canvas
thanks
You can solve this by storing the image that your bitmaps are built from, then re-adding them when you need to paste. Also you'll need to override Stage.prototype._handleMouseDown like this:
window.Stage.prototype._handleMouseDown = function(e){
if (this.onMouseDown) {
this.onMouseDown(new MouseEvent("onMouseDown", this.mouseX, this.mouseY, this, e));
}
var target = this._getObjectsUnderPoint(this.mouseX, this.mouseY, null, (this._mouseOverIntervalID ? 3 : 1));
if (target) {
if (target.onPress instanceof Function) {
var evt = new MouseEvent("onPress", this.mouseX, this.mouseY, target, e);
target.onPress(evt);
if (evt.onMouseMove || evt.onMouseUp) { this._activeMouseEvent = evt; }
}
this._activeMouseTarget = target;
} else {
this.onPressThrough && this.onPressThrough(e);
}
}
Then in your implementation define onPressThrough like this.
stage.onPressThrough = function(event){
console.log("paste");
paste(event.x, event.y);
}
Here is a complete working example:
$(document).ready(
function(){
var canvas = document.createElement('canvas');
$(canvas).attr('width', '1000');
$(canvas).attr('height', '1000');
$('body').append(canvas);
var stage = window.stage = new Stage(canvas);
canvas.stage = stage;
function copy(target){
window.clipboard = target;
}
function addImage(image, x, y){
var bitmap = new Bitmap(image);
bitmap.image = image;
bitmap.onPress = function(event){
console.log("copy")
copy(this.image);
}
stage.addChild(bitmap);
bitmap.x = x || 0;
bitmap.y = y || 0;
}
function paste(x, y){
window.clipboard && addImage(clipboard, x, y);
}
window.Stage.prototype._handleMouseDown = function(e){
if (this.onMouseDown) {
this.onMouseDown(new MouseEvent("onMouseDown", this.mouseX, this.mouseY, this, e));
}
var target = this._getObjectsUnderPoint(this.mouseX, this.mouseY, null, (this._mouseOverIntervalID ? 3 : 1));
if (target) {
if (target.onPress instanceof Function) {
var evt = new MouseEvent("onPress", this.mouseX, this.mouseY, target, e);
target.onPress(evt);
if (evt.onMouseMove || evt.onMouseUp) { this._activeMouseEvent = evt; }
}
this._activeMouseTarget = target;
} else {
this.onPressThrough && this.onPressThrough(e);
}
}
stage.onPressThrough = function(event){
console.log("paste");
paste(event.x, event.y);
}
var image = new Image();
image.src = "assets/images/tempimage.png";
addImage(image);
window.tick = function(){
stage.update();
}
Ticker.addListener(window);
}
)
Related
I have some code that I've used to create controls for a long time, and it works well, in that it properly captures and releases the mouse (at least in chrome).
function createSlider(slider, width, height)
{
slider.width = width;
slider.height = height;
slider.style.display = 'inline';
//
slider.onchange = new Event('onchange');
//
slider.addEventListener('mousedown', function(e)
{
var e = window.event || e;
if (e.button == 0)
{
e.preventDefault();
if (slider.setCapture)
slider.setCapture();
slider.mouseDown0 = true;
slider.sx = e.clientX;
slider.sv = slider.value;
}
});
slider.addEventListener('losecapture', function()
{
slider.mouseDown0 = false;
});
document.addEventListener('mouseup', function(e)
{
var e = window.event || e;
if (e.button == 0 && slider.mouseDown0)
slider.mouseDown0 = false;
}, true);
(slider.setCapture ? slider : document).addEventListener('mousemove', function(e)
{
if (slider.mouseDown0)
{
var dx = slider.sx - e.clientX;
var adaptive = 10 * Math.pow(Math.abs(dx), slider.acc);
slider.value = Math.min(Math.max(slider.min, slider.sv - dx*slider.scale*adaptive), slider.max);
//TODO: if (log) do log scaling
slider.paint();
slider.dispatchEvent(slider.onchange);
}
}, true);
slider.onmousewheel = function(e)
{
e.preventDefault();
var s = e.target;
s.value = Math.min(Math.max(s.min, s.value + (e.wheelDeltaY > 0 ? 1 : -1) * s.scale), s.max);
s.dispatchEvent(s.onchange);
s.paint();
};
slider.paint = function()
{
//...
};
//
slider.paint();
}
But when I tried using this code inside of a Figma plugin window, it loses mouse capture as soon as the mouse leaves the window. Is there something that I need to adjust for this to work?
Apparently you cannot, but you can use pointer lock to solve the issue for some situations.
I can't reset the image on javascript, codepen say imagem in not defined.
Codepen link: https://codepen.io/AlissonTelez/pen/ExPJBvv
Thats variables:
var originalImage;
var grayImage = null;
var redImage = null;
var rainbowImage = null;
var windowImage = null;
var canvas = document.getElementById("can1");
thats function to make filter red:
function makeRedy() {
if (imgCarregada(imagemRedy)) {
filtroVermelho();
var canNovo = document.getElementById("can");
imagemRedy.drawTo(canvas);
}
}
function filtroVermelho() {
for (var pixel2 of imagemRedy.values()) {
avg2 = (pixel2.getRed()+pixel2.getGreen()+pixel2.getBlue()/3);
if (avg2 < 128) {
pixel2.setRed(2*avg2);
pixel2.setGreen(0);
pixel2.setBlue(0);
}
else {
pixel2.setRed(255);
pixel2.setGreen((2*avg2)-255);
pixel2.setBlue((2*avg2)-255);
}
}
}
that's reset function:
function resete() {
if (imgCarregada(imagem)) {
imagem.drawTo(canvas);
}
}
function imgCarregada(x) {
if (x === null) {
return false;
}
else if (x !== null) {
return true;
}
}
You have not defined imagem. But it appears your original image is being stored as imagemOriginal.
Change your resete() function to this;
function resete() {
if (imgCarregada(imagemOriginal)) {
imagemOriginal.drawTo(canvas);
}
}
Based on your CodePen. Which appears to hold different values to what you pasted in your question.
read my comments in code and try understand what's new
// for checking later if null or not
var imagemOriginal = null;
var imagemRedy = null;
var imagemGray = null;
var avg;
var avg2;
// ctx for canvas api 2d
var canvas , ctx;
function upload() {
var img = document.getElementById("Finput");
canvas = document.getElementById("can");
// defined canvas context 2d for drawing and accessing all canvas api
ctx = canvas.getContext("2d");
imagemOriginal = new SimpleImage(img);
imagemGray = new SimpleImage(img);
imagemRedy = new SimpleImage(img);
imagemOriginal.drawTo(canvas);
}
// calling upload as first step for making canvas ready
upload();
function makeGray() {
if (imgCarregada(imagemGray)) {
filtroCinza();
var canNovo = document.getElementById("can");
imagemGray.drawTo(canvas);
}
}
function filtroCinza() {
for (var pixel of imagemGray.values()) {
avg = (pixel.getRed()+pixel.getGreen()+pixel.getBlue())/3;
pixel.setRed(avg);
pixel.setGreen(avg);
pixel.setBlue(avg);
}
}
function makeRedy() {
if (imgCarregada(imagemRedy)) {
filtroVermelho();
var canNovo = document.getElementById("can");
imagemRedy.drawTo(canvas);
}
}
function filtroVermelho() {
for (var pixel2 of imagemRedy.values()) {
avg2 = (pixel2.getRed()+pixel2.getGreen()+pixel2.getBlue()/3);
if (avg2 < 128) {
pixel2.setRed(2*avg2);
pixel2.setGreen(0);
pixel2.setBlue(0);
}
else {
pixel2.setRed(255);
pixel2.setGreen((2*avg2)-255);
pixel2.setBlue((2*avg2)-255);
}
}
}
// in resete function you put arguments not exist 'imagem' ! and that give you error
// soo sloution is checking 'imagemOriginal'
function resete() {
// soo here do your check // if true call restCanvas for make canvas clear :)
if (imgCarregada(imagemOriginal)) resetCanvas();
}
// this function using 'ctx' or canvas context for make canvas clean
function resetCanvas(){
// fillstyle for select your draw color
ctx.fillStyle = "white";
// fillrect for draw with resloution :)
ctx.fillRect(0,0,canvas.width,canvas.height);
}
// here just syntax better :)
function imgCarregada(x) {
if (x === null) return false;
else if (x !== null) return true;
}
My Code works for 1 canvas. But I need this implementation to work for 2 of canvas.
So I tried
var SIGNATURE_2 = new CLIPBOARD_CLASS("signatureCanvas2", true);
The problem is that this always pastes the image in the first canvas, I just need to press Ctrl+V.
How do I paste ONLY when the canvas is focused or hovered?
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copy paste Image to Canvas
////////////////////////////////////////////////////////////////////////////////////////////////////////////
var SIGNATURE = new CLIPBOARD_CLASS("signatureCanvas", true);
var SIGNATURE_2 = new CLIPBOARD_CLASS("signatureCanvas2", true);
/**
* image pasting into canvas
*
* #param {string} canvas_id - canvas id
* #param {boolean} autoresize - if canvas will be resized
*/
function CLIPBOARD_CLASS(canvas_id, autoresize) {
var _self = this;
var canvas = document.getElementById(canvas_id);
var ctx = document.getElementById(canvas_id).getContext("2d");
var ctrl_pressed = false;
var command_pressed = false;
var paste_event_support;
var pasteCatcher;
//handlers
document.addEventListener('keydown', function (e) {
_self.on_keyboard_action(e);
}, false); //firefox fix
document.addEventListener('keyup', function (e) {
_self.on_keyboardup_action(e);
}, false); //firefox fix
document.addEventListener('paste', function (e) {
_self.paste_auto(e);
}, false); //official paste handler
//constructor - we ignore security checks here
this.init = function () {
pasteCatcher = document.createElement("div");
pasteCatcher.setAttribute("id", "paste_ff");
pasteCatcher.setAttribute("contenteditable", "");
pasteCatcher.style.cssText = 'opacity:0;position:fixed;top:0px;left:0px;width:10px;margin-left:-20px;';
document.body.appendChild(pasteCatcher);
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (paste_event_support === true || ctrl_pressed == false || mutation.type != 'childList'){
//we already got data in paste_auto()
return true;
}
//if paste handle failed - capture pasted object manually
if(mutation.addedNodes.length == 1) {
if (mutation.addedNodes[0].src != undefined) {
//image
_self.paste_createImage(mutation.addedNodes[0].src);
}
//register cleanup after some time.
setTimeout(function () {
pasteCatcher.innerHTML = '';
}, 20);
}
});
});
var target = document.getElementById('paste_ff');
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
}();
//default paste action
this.paste_auto = function (e) {
paste_event_support = false;
if(pasteCatcher != undefined){
pasteCatcher.innerHTML = '';
}
if (e.clipboardData) {
var items = e.clipboardData.items;
if (items) {
paste_event_support = true;
//access data directly
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
//image
var blob = items[i].getAsFile();
var URLObj = window.URL || window.webkitURL;
var source = URLObj.createObjectURL(blob);
this.paste_createImage(source);
}
}
e.preventDefault();
}
else {
//wait for DOMSubtreeModified event
}
}
};
//on keyboard press
this.on_keyboard_action = function (event) {
var k = event.keyCode;
//ctrl
if (k == 17 || event.metaKey || event.ctrlKey) {
if (ctrl_pressed == false)
ctrl_pressed = true;
}
//v
if (k == 86) {
if (document.activeElement != undefined && document.activeElement.type == 'text') {
//let user paste into some input
return false;
}
if (ctrl_pressed == true && pasteCatcher != undefined){
pasteCatcher.focus();
}
}
};
//on kaybord release
this.on_keyboardup_action = function (event) {
//ctrl
if (event.ctrlKey == false && ctrl_pressed == true) {
ctrl_pressed = false;
}
//command
else if(event.metaKey == false && command_pressed == true){
command_pressed = false;
ctrl_pressed = false;
}
};
//draw pasted image to canvas
this.paste_createImage = function (source) {
var pastedImage = new Image();
pastedImage.onload = function () {
if(autoresize == true){
//resize
canvas.width = pastedImage.width;
canvas.height = pastedImage.height;
}
else{
//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(pastedImage, 0, 0);
};
pastedImage.src = source;
};
}
.signatureCanvas {
border:1px solid #027C8C;
width: 100%;
max-height:200px;
}
<canvas id="signatureCanvas" class="signatureCanvas"></canvas>
<canvas id="signatureCanvas2" class="signatureCanvas"></canvas>
PS: Please just open snipping tool on windows and copy paste an image to test
Detect if mouse is over canvas, and store it in a variable.
var over_canvas=false;
document.getElementById("signatureCanvas").addEventListener("mouseover", function (i) {
over_canvas=true;
});
document.getElementById("signatureCanvas").addEventListener("mouseout", function (i) {
over_canvas=false;
});
When pasting, check if mouse is over canvas by changing your paste function to:
document.addEventListener('paste', function (e) {
if (over_canvas){
_self.paste_auto(e);
}
}, false);
I have original script: http://pastebin.com/ERWdaQym
I need to appear in the image, the image is displayed. Script worked when he was with html. But there was another problem, put this script in a separate file. But I did not get, get it to work so it worked.
I have an library.js, this file is automatically included in every page.:
var LIBRARY = {
init: function() {
$('image[itemprop = image]').each(LIBRARY.lazyLoad());
},
/**
* LazyLoad images
*/
lazyLoad: function(event) {
$(function() {
var $window = $(window),
images = [],
imagesToBeLoaded = 0,
i,
src;
function throttle(func, wait) {
var timeout;
return function() {
var context = this, args = arguments;
if(!timeout) {
timeout = setTimeout(function() {
timeout = null;
}, wait);
func.apply(context, args);
}
};
}
function inViewport($el) {
var top = $window.scrollTop(),
left = $window.scrollLeft(),
bottom = top + $window.height(),
right = left + $window.width(),
offset = $el.offset(),
thisTop = offset.top,
thisLeft = offset.left,
thisBottom = thisTop + $el.outerHeight(),
thisRight = thisLeft + $el.outerWidth();
return !(
bottom < thisTop ||
top > thisBottom ||
right < thisLeft ||
left > thisRight
);
}
// throttle so we don't do too many calls
var lazyScroll = throttle(function() {
// have all images been loaded?
if(imagesToBeLoaded > 0) {
for(i = 0; i < images.length; i++) {
// data is there if nothing has been done to it
src = images[i].data('src');
// see if the image is in the view
if(src && inViewport(images[i])) {
// create a nice closure here
(function(img, src, i, $img) {
img.onload = function() {
console.log('Loaded ' + i + ' ' + img.src);
$img.attr('src', img.src);
imagesToBeLoaded--;
};
img.onerror = function() {
console.log('Could not load ' + i + ' ' + img.src);
imagesToBeLoaded--;
};
// important to remove this to avoid duplicate calls
$img.removeData('src');
// start loading the image
img.src = src;
})(new Image(), src, i, images[i]);
}
}
} else {
// cleanup
images = void 0;
// why keep listening if there is nothing to listen
$window.off('resize scroll touchmove', lazyScroll);
// all images are loaded
console.log('Unloaded event listener');
}
}, 50);
$('image[itemprop = image]').each(function() {
var $this = $(this),
$img = $(this.innerText || $this.text()).filter('img');
// make sure we got something
if($img.length === 1) {
// remember the real image
$img.data('src', $img.attr('src'));
// use a blank image
$img.attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
// cache a reference
images.push($img);
// replace noscript element with the image
$this.replaceWith($img);
imagesToBeLoaded++;
}
});
// only add if we need it
if(imagesToBeLoaded) {
lazyScroll();
$window.on('resize scroll touchmove', lazyScroll);
}
});
}
};
I need to connect the init: event that would run the script and images appear correctly, in other words, if a user comes to the image, then it is loaded. Tell me how to do it and what I need to fix?
You can use document ready: http://learn.jquery.com/using-jquery-core/document-ready/
something like:
$(document).ready(LIBRARY.init);
Ok! I'm working on a wordpress site, and everything this javascript add on is supposed to do, it does...But, when I inspect element via safari develop, I notice that it's loading all of my headers scripts,meta,styles etc. into the body as well as the head. I can't figure out why. Here's what the script looks like:
function ft(params) {
var ol= document.addEventListener?"DOMContentLoaded":"load"; //on load event
var navB = params.navB || "reverse slide"; //backbrowser button effect, default empty
var but = params.but || false; //Allow transitions on input type button
var cBa = params.cBa || function() {};
function aDL(url, t, o) { //Ajax Div Load
if (window.XMLHttpRequest) {
r = new XMLHttpRequest();
} else if (window.ActiveXObject) {
r = new ActiveXObject("Microsoft.XMLHTTP");
}
if (r != undefined) {
r.onreadystatechange = function() {Ol(r, t, o);};
r.open("GET", url, true);
r.send("");
}
}
function Ol(r, t, o) { //On load div
if (r.readyState == 4) {
if (r.status == 200 || r.status == 0) {
t.innerHTML = r.responseText;
o();
} else {
t.innerHTML="Error:\n"+ r.status + "\n" +r.statusText;
}
}
}
function DE() //Div Effect
{
var dochtml = document.body.innerHTML;
document.body.innerHTML = "";
var d1 = document.createElement("div");
d1.id = "d1";
d1.style.zIndex = 2;
d1.style.position = "absolute";
d1.style.width = "100%";
d1.style.height = "100%";
d1.style.left = "0px";
d1.style.top = "0px";
document.body.appendChild(d1);
d1.innerHTML = dochtml;
var d2 = document.createElement("div");
d2.id = "d2";
d2.style.zIndex = 1;
d2.style.position = "absolute";
d2.style.width = "100%";
d2.style.height = "100%";
d2.style.left = "0px";
d2.style.top = "0px";
document.body.appendChild(d2);
return {d1: d1, d2: d2 };
}
function timeOuts(e, d1,d2)
{
setTimeout(function() { d1.className = e + " out"; }, 1);
setTimeout(function() { d2.className = e + " in"; }, 1);
setTimeout(function() {
document.body.innerHTML = d2.innerHTML;
cBa();
}, 706);
}
function slideTo(href, effect, pushstate)
{
var d = DE();
var d1 = d.d1;
var d2 = d.d2;
aDL(href, d2,
function() {
if (pushstate && window.history.pushState) window.history.pushState("", "", href);
timeOuts(effect,d1,d2);
}
);
}
function dC(e){ //Detect click event
var o;
var o=e.srcElement || e.target;
var tn = o.tagName.toLowerCase();
if (!but || tn!="input" || o.getAttribute("type")!="button") //if it is not a button
{
//try to find an anchor parent
while (tn!=="a" && tn!=="body")
{
o = o.parentNode;
tn = o.tagName.toLowerCase();
}
if (tn==="body") return;
}
var t = o.getAttribute("data-ftrans");
if (t)
{
e.preventDefault();
var hr = o.getAttribute("href") || o.getAttribute("data-href");
if (hr) slideTo(hr, t, true);
}
}
function aE(ev, el, f) { //Add event
if (el.addEventListener) // W3C DOM
el.addEventListener(ev,f,false);
else if (el.attachEvent) { // IE DOM
var r = el.attachEvent("on"+ev, f);
return r;
}
}
aE("click", window, dC);
aE(ol, document, //On load
function(ev)
{
aE("popstate", window, function(e) { //function to reload when back button is clicked
slideTo(location.pathname, navB, false);
});
}
);
}
here is the link to the site: http://www.fasw.ws/faswwp/non-jquery-page-transitions-lightweight/
I assume that thats not supposed to happen. So im trying to figure out how to keep it clean, and keep the head files loaded in the head, and only load the page content. I cannot figure this one out, some help from the pros is needed :)
FASW comes with two functions that serves as "hooks" both before and after initializing the component. you can do it like this:
(function inittrans()
{
initComponents();
var params = { /*put your options here*/ };
new ft(params);
})();
function onTransitionFinished()
{
initComponents();
}
function initComponents() {
// here is where you put your "other" javascript codes
}
Notice how your javascript codes are executed after loading your initial page and once again after the transition happened. Anyway, this is how I got the work around on it 'coz javascript codes just won't work as they are loaded by FASW via Ajax on-the-fly.