I'm trying to add Caman.js filter functionality to a paper.js Raster. And in order not to loose image information I want to reset the image data to the original data (_camanImageData) every time before I call Caman by copying it from a cloned raster. The code is like this:
with(paper) {
Raster.prototype._camanImageData = null;
Raster.prototype.filter = function(options) {
var self = this,
ctx = this.getContext(), // caution! This also inits this._canvas (should).
size = this._size;
if( !this._camanOrgImage ) {
this._camanOrgImage = this.clone(false);
} else {
var dst = ctx.createImageData(size.width, size.height);
dst.data.set(this._camanOrgImage.getImageData(new Rectangle(0, 0, size.width, size.height)).data);
this.setImageData(dst);
}
Caman(this._canvas, function () {
for( option in options ) {
var value = options[option];
this[option](value);
}
this.render(function () {
self._changed(129);
});
});
};
}
The first call works fine. The second works apparently on the already modified data.
I call the filter function like this:
raster.filter({
brightness: 50,
saturation: 10,
hue: 20,
});
What do I do wrong?
The problem was with Caman. Caman doesn't reload the changed canvas, if a "data-caman-id" attribute is set in the canvas element. Just delete this before the call to Caman and it works fine:
this._canvas.removeAttribute("data-caman-id");
Caman(this._canvas, function () {
...
The solution came from: How can I change out an image using CamanJS?
Related
I'm trying a basic display of a preloaded image with p5.js library (instantiation mode):
var sketch = function(p) {
var fondo;
p.preload = function() {
fondo = p.loadImage('app/themes/mrg/dist/images/tramas/example.jpg');
};
var viewportWidth = $(window).width();
p.setup = function(){
canvas = p.createCanvas(viewportWidth, 200);
canvas.background(255);
canvas.image(fondo, 0, 0);
};
};
new p5(sketch);
The canvas was created but no image is there.
Here is a working example:
https://stage.margenesdelarte.org/
The canvas is at the end of the page (with white background) but no image is rendered inside.
Image path is right, since there is no error in the console and it can be reached in its place:
https://stage.margenesdelarte.org/app/themes/mrg/dist/images/tramas/example.jpg
What is wrong, and how can I display this image? Thanks!
That's correct version? (I used BASE64 because I didn't want to run a local server)
var sketch = function(p) {
var fondo;
p.preload = function() {
fondo = p.loadImage("data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7");
};
var viewportWidth = 500;
p.setup = function(){
var canvas = p.createCanvas(viewportWidth, 200);
canvas.image(fondo, 0, 0); // doesn't work
p.image(fondo, 0, 0); // works fine
console.log(p.image, canvas.image); //there are different functions
};
};
new p5(sketch);
https://codepen.io/anon/pen/yPENXx?editors=1111
Explanation:
Both p and canvas has a image function but there are different image functions. You have to use p.image(). I think canvas.image() is has some relations with https://p5js.org/reference/#/p5.Image, but that's only my assumptions.
Is your file being localhosted? For p5 to access local files such as images, it needs to be localhosted... I recommend apache
i'm working on this graphic visualizer. following is a example code of what i'm doing.
first i create new canvas and there is a simple jQuery click event to add image objects to canvas.and after working on this canvas i need to load data from database, I've managed to save data on database by "Serialization" which default support by fabric-js. and retrieve data as a json object to load in to canvas. what i want is to completely remove current working canvas and load a new with database retrieved data. so here what i've done so far...
(function() {
var canvasOffsetHeight = '400';
var canvasOffsetWidth = '600';
var canvas = new fabric.Canvas('canvas');
window.addEventListener('resize', resizeCanvas, false);
function resizeCanvas() {
canvas.setHeight(canvasOffsetHeight);
canvas.setWidth(canvasOffsetWidth);
canvas.renderAll();
}
// resize on init
resizeCanvas();
jQuery('.category ul').on('click', 'li', function (e) {
var imgElement = jQuery(this).children("img")[0];
var imgInstance = new fabric.Image(imgElement, {
left: 100,
top: 100,
angle: 0,
opacity: 1
});
canvas.add(imgInstance);
canvas.renderAll();
return false;
});
jQuery('#obj').click(function(){
canvas_data = '{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0}],"background":"rgba(0, 0, 0, 0)"}';
var canvas = new fabric.Canvas('canvas');
canvas.loadFromJSON(canvas_data,canvas.renderAll.bind(canvas));
});
})();
here lets assume "canvas_data" is the data from database.
the problem is when i load data from an object it appears on canvas correctly but soon as i click on them they just vanishing.
i think because main function run onLoad so when i click it triggers the main function and load the previous canvas. what i want is to wipe out old canvas and load new one with database data. please help.
they say "loadFromJSON" automatically does this for us but it seems not working for me.
No need to create another canvas object. So your code in the #obj.click becomes:
jQuery('#obj').click(function(){
canvas_data = '{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0}],"background":"rgba(0, 0, 0, 0)"}';
canvas.loadFromJSON(canvas_data,canvas.renderAll.bind(canvas));
});
I am building a web application and for this I am building a basic Image Editor using HTML5 and Raphael js. I have implemented some features like:
Resize Flip horizontal and/or vertical Drag
Some more features I need to implement are :
Crop Undo/Redo Changing background colour and opacity.
I am mainly looking for crop and undo functionality. Can anyone help me to achieve this using RaphaelJs and HTML5?
My Code:
var r, c, d;
var paper = Raphael("editor", 600,450);
var canvas = document.getElementById('editor');
canvas.style.backgroundColor='gray';
$scope.current;
var someFunction = function(e) {
e.data('dragged', false);
e.drag(dragmove, dragstart, dragend);
for(var i in elements) {
var thisShape = elements[i];
var ft = paper.freeTransform(thisShape,{draw:['bbox']});
ft.hideHandles();
thisShape.click(function(){
paper.forEach(function(el) {
if(el.freeTransform.handles.bbox != null)
el.freeTransform.hideHandles();
});
this.freeTransform.showHandles();
});
}
};
function dragmove(dx, dy, x, y, e) {
this.transform(this.current_transform+'T'+dx+','+dy);
}
function dragstart(x, y, e) {
this.current_transform = this.transform();
}
function dragend(e) {
this.current_transform = this.transform();
};
var elements = [];
$scope.raph = function () {
c= paper.circle(40,40,40).click(function() {
someFunction(this);
$scope.current= this;
});
r = paper.rect(50, 60, 100,100,25).click(function() {
someFunction(this);
$scope.current= this;
});
d = paper.rect(70, 60, 100,100,25).click(function() {
someFunction(this);
$scope.current= this;
});
elements.push(c,r,d);
c.attr({
fill:'red',
cursor:'pointer'
});
r.attr({
fill:'green',
cursor:'pointer'
});
d.attr({
fill:'blue',
cursor:'pointer'
});
};
$scope.back = function () {
$scope.current.toBack();
}
$scope.front = function () {
$scope.current.toFront();
}
$scope.clear = function () {
paper.clear();
};
$scope.flips = function () {
$scope.current.rotate(180);
};
//function for cloning element
$scope.clones = function () {
var n = $scope.current.clone();
n.attr("x",$scope.current.attr("x")+100);
$scope.current = n;
elements.push(n);
n.click(function() {
someFunction(this);
});
};
$scope.changing= function (e) {
$scope.opacity=event.target.value;
if($scope.current != null){
$scope.current.attr({
opacity:$scope.opacity
})
}
}
UPDATE: just use Fabric.js http://fabricjs.com/kitchensink/, although you'll probably need to add Darkroom http://mattketmo.github.io/darkroomjs/ for cropping.
Some suggestions for RaphaelJS:
resize: http://raphaeljs.com/reference.html#Element.transform c.transform('S1.5,1.5')
flip: resize with a negative scale in either direction (S-1,1)
drag: http://raphaeljs.com/reference.html#Element.drag, also consider set overloads like http://wesleytodd.com/2013/4/drag-n-drop-in-raphael-js.html
changing colors and stuff: http://raphaeljs.com/reference.html#Element.attr
undo -- you'll have to save a list of operations/previous states to reverse?
crop -- most likely you'd create the UI in raphael using a mask/overlay (layers: http://raphaeljs.com/reference.html#Element.toBack) to send instructions to a server-side API to handle the heavy work. You can manipulate raster images in the browser, but if people are uploading photos it could quickly overload the memory limitations (think: unedited 12MP photo)
Check out stuff like Sketchpad http://ianli.com/sketchpad/ or the commented Darkroom http://mattketmo.github.io/darkroomjs/ for ideas.
You can always try exploring the sourcecode for existing web editors, like Google+... (that was mostly a joke).
I am new to Cocos2d-html5 v2.2.1 and I am trying to add a sprite (simple image) to the canvas. The code does add an image with the correct width and height but it is just black.
I cant seem to find any errors so I am kinda stuck.
Any help would be great. My code is below:
In main.js i load the resources:
applicationDidFinishLaunching:function () {
if(cc.RenderDoesnotSupport()){
//show Information to user
alert("Browser doesn't support WebGL");
return false;
}
// initialize director
var director = cc.Director.getInstance();
//cc.EGLView.getInstance()._adjustSizeToBrowser();
//cc.EGLView.getInstance()._resizeWithBrowserSize(true);
//cc.EGLView.getInstance().setDesignResolutionSize(600, 400, cc.RESOLUTION_POLICY.SHOW_ALL);
// set FPS. the default value is 1.0/60 if you don't call this
director.setAnimationInterval(1.0 / this.config['frameRate']);
//load resources
cc.LoaderScene.preload(g_resources, function () {
director.replaceScene(new this.startScene());
}, this);
return true;
}
g_resources is defined in resource.js:
var s_jet = "images/jet.png";
var s_character = "images/p1_front.png";
var g_resources = [
//image
{src:s_jet},
{src:s_character}];
spriteScene.js:
init:function () {
var selfPointer = this;
this._super();
var size = cc.Director.getInstance().getWinSize();
var lazyLayer = cc.LayerColor.create(new cc.Color4B(45, 50, 128, 255), 600, 600);
//var lazyLayer = cc.Layer.create();
lazyLayer.setAnchorPoint(new cc.Point(0.5,0.5));
var characterSprite = cc.Sprite.create("./images/p1_front.png");
lazyLayer.addChild(characterSprite, 0);
this.addChild(lazyLayer);
var rotateToA = cc.RotateTo.create(2, 0);
var scaleToA = cc.ScaleTo.create(2, 1, 1);
characterSprite.setPosition(new cc.Point(size.width/2,size.height/2));
I just dont understand why the sprite is just being drawn as a black box.
Edit: When I uncomment the line below from main.js; at first the image is still black but when I resize the browser, the image appears:-
cc.EGLView.getInstance().setDesignResolutionSize(600, 400, cc.RESOLUTION_POLICY.SHOW_ALL);
I dont know what this is implying.
Ok guys! I figured it out and I am pissed. Changed this line:
this.characterSprite.setPosition(new cc.Point(size.width/2,size.height/2));
to:
this.characterSprite.setPosition(cc.p(size.width/2, size.height/2));
Documentation/tutorials for cocos2d-html5 are outdated and this is getting frustrating.
I want to save part of a KineticJS stage. This code is working perfect:
stage.toDataURL({
width: 350,
height: 350,
mimeType: "image/jpeg",
callback: function(dataUrl) {
/*
* here you can do anything you like with the data url.
* In this tutorial we'll just open the url with the browser
* so that you can see the result as an image
*/
window.open(dataUrl);
}
});
}, false);
But what i want is to add an offset to that, so image would start and coordinates (75,75) of the stage area. Any idea?
Well, since there is no crop() method you would have to revert to moving all the objects on your stage 75 in both directions, luckily, this is not very difficult.
Something like:
var layersList = stage.getChildren();
for (var layerNum in layersList){ //loop through all layers
var childList = layerList.getChildren(); //get all children of the layer
for(var childNum in childList){
childList[childNum].move(-75,-75);
}
}
stage.draw();
stage.toDataURL({.....});
You can undo this by using the same code and doing .move(75,75); to place each item back in their original position
or if you want an offset defined through a function just do this:
function moveStage(offsetX, offsetY){
var layersList = stage.getChildren();
for (var layerNum in layersList){ //loop through all layers
var childList = layerList.getChildren(); //get all children of the layer
for(var childNum in childList){
childList[childNum].move(-offsetX,-offsetY);
}
}
stage.draw();
stage.toDataURL({.....});
}