danielthall / ember-cropperjs Goto Github PK
View Code? Open in Web Editor NEWEmber wrapper around CropperJS
License: MIT License
Ember wrapper around CropperJS
License: MIT License
Hi,
I have a use case where I need to toggle "zoomable" from a checkbox control. The problem I'm seeing is that this change doesn't take effect. The default value of that option takes effect, whether I make it true
or `false, but it can't change that value after the fact.
I noticed in the code there is a short list of options that require complete re-instantiation of the cropper. Is this one of those options, and if so, would adding zoomable
to that list fix this?
https://github.com/danielthall/ember-cropperjs/blob/master/addon/components/image-cropper.js#L15
Thanks!
We have a consuming application that cannot build when this addon is installed. The consuming app uses postCSS. This seems to be related to jeffjewiss/ember-cli-postcss#143.
Since there's no real use of sass in this addon, and since removing sass dependencies and converting the scss files to CSS is trivial (there's only two very short files), we might want to remove the deps and convert the files. Doing this fixed our builds.
Here's a PR that addresses this issue: #74
Hi,
first of all, thank you for providing this wrapper! It saves us all a lot of time.
It would be even more useful if you could provide just a little bit more documentation. Maybe it is just me being an ember beginner (and all the confusion mixed in that stems from all this octane vs pre-octane code), but I can not figure out how you are supposed to use your components. While I think I understand what
{{cropper.on 'crop' action=(action 'crop')}}
actually does (when "crop" is called on cropper, the passed action will be executed), I can not figure out how to utilize the "call" component to actually call "crop" when I want to (vs e.g. autocrop).
What I want is to simply add a toolbar where e.g. one clicks on the "fliip X" button and the image is flipped, clicking on "crop" crops the image etc..
Now I did get it to work like this:
{{! -- in *.hbs --}}
{{#image-cropper
source=this.preview_image
options=(hash
aspectRatio=1
viewMode=2
responsive=true
) as |cropper|}}
<a class="button" {{on 'click'(fn this.flip_x cropper.cropper)}}>Flip</a>
{{/image-cropper}}
//in *.js
(...)
@action
flip_x(cropper)
{
var oldScale = cropper.imageData.scaleX ? cropper.imageData.scaleX : 1;
cropper.scaleX( oldScale * -1);
}
(...)
Please especially notice the "cropper.cropper" part. It does work but I am absolutely not sure if this is what I am supposed to do. It sounds like I shall use "cropper.call", but no matter how I do it, I always end up getting
Assertion Failed: image-cropper-call crop() must be a function on [object Object]
Furthermore I have no Idea how to call it using the on-modifier (or any way besides pasting in in the template directly).
If the above is a sane way to do it, please add it to the documentation. Otherwise any example of how to actually do this would be appreciated.
Hi, I realize this isn't something to do with this addon specifically, but I'm curious if you've had any issues with images being of low quality after crop? I've seen a number of threads on this on the cropper.js repo, but oddly enough, the repo owner closes them without addressing the issue.
My code is fairly simple:
ember-file-upload
to upload the file as base 64.
Note: the image uploaded in this screenshot was 2000x2000, so it's not an issue with the image being scaled up and losing quality.*
Here's my code:
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { debounce } from '@ember/runloop';
import { task } from 'ember-concurrency';
import File from 'ember-file-upload/file';
import config from 'scout-app/config/environment';
const FILE_UPLOAD_URL = `${config.APP.API_GATEWAY}/uploadFile`;
export default Component.extend({
store: service(),
editMode: false,
sourceImg: null,
croppedImg: null,
mimeType: null,
init() {
this._super(...arguments);
this.set('cropperOptions', {
autoCropArea: 1,
minCropBoxHeight: 125,
minContainerHeight: 250,
viewMode: 2,
zoomable: false
})
},
/**
* Handles the actual cropping of the image.
* @param {*} cropper
*/
cropImage(cropper) {
const croppedImg = cropper.getCroppedCanvas({
imageSmoothingQuality: 'high',
maxHeight: 300,
fillColor: '#fff'
}).toDataURL(this.get('mimeType'), 1);
if (croppedImg) {
this.set('croppedImg', croppedImg);
}
},
/**
* Uploads an image locally as base64 for preview.
*/
uploadForPreview: task(function * (file) {
try {
file.readAsDataURL().then((url) => {
if (url) {
this.set('sourceImg', url)
this.set('mimeType', file.get('type'))
}
});
} catch (e) {
}
}).maxConcurrency(3).enqueue(),
/**
* Uploads an image to the server after it's been cropped (optional).
*/
uploadToServer: task(function * () {
// convert data to url to file
const file = File.fromDataURL(this.get('croppedImg'));
// set name of file since this is being read from a data url
const fileName = `logo.${file.get('extension')}`;
file.set('name', fileName);
const options = {
headers: {
'Authorization': this.get('session.data.authenticated.token')
},
fileKey: 'fileData',
data: {
tags: JSON.stringify([{ name: 'scout:logo' }]),
isAdmin: true
}
};
try {
// upload the file
const response = yield file.upload(FILE_UPLOAD_URL, options);
// push into local store
const { body } = response;
this.get('store').pushPayload(body);
// retrieve an Ember data object of what we just got back from the server
const { data } = body
const logo = this.get('store').peekRecord('document', data[0].id);
// get a reference to the current business
const business = this.get('session.currentBusiness');
// update the logo url
business.set('preferences.brand.logoUrl', logo.get('url'));
yield business.save();
// if edit mode was on, set it to off
this.set('editMode', false);
} catch (err) {
console.log(err)
}
}).maxConcurrency(3).enqueue(),
actions: {
crop(cropper) {
debounce(this, this.cropImage, cropper, 100);
},
uploadForPreview(file) {
this.get('uploadForPreview').perform(file);
},
uploadToServer() {
this.get('uploadToServer').perform();
}
}
});
Thanks in advance for any input!
when i upload a different image and update the {{#cropper-image source=*thelatestuploadedimageurl*
... }}. the source changes but the previous options are not getting set to the new image.
On running this app on a fastboot application, it throws the error to the effect document is not defined
.
Instead of using a release candidate version, we should use one of the latest releases
After testing #1 in a real app scenario, it's not quite working right for me. A couple issues:
Now it will re-initialize the cropper instance on any attribute change, so even if I just change the aspect ratio for instance, it will re-initialize the entire cropper.
It shouldn't have to re-initialize the entire cropper anyway. When the source attribute changes, there is a cropper.replace()
function that can be called.
I am working around these issues in my app by reverting to 0.1.0 and using something like this in my parent component:
updateSource: observer("cropper", "source", function() {
const cropper = this.get("cropper");
if (cropper) {
cropper.replace(this.get("source"));
}
}),
updateAspectRatio: observer("aspectRatio", "cropper", function() {
const aspectRatioValue = this.get("aspectRatioValue");
const cropper = this.get("cropper");
if (aspectRatioValue && cropper) {
cropper.setAspectRatio(aspectRatioValue);
}
}),
I'd love to do a PR to help fix this. But are observers the recommended way to do this, or is there a better way? If I remember correctly, didReceiveAttrs doesn't actually tell you which attribute has changed, does it?
I think that lorempixel.com must be removed from the CSP.
or only added on the development environment or on an environement different from production
It'd be nice to move this to the latest version of Ember.
This addon should be updated to a v2 addon! https://github.com/embroider-build/embroider/blob/main/PORTING-ADDONS-TO-V2.md
As I understand Cropper.js from the box loading like a chunk by path /assets/chunk.js and it's works fine.
But when I changed vendor.js script to async like
the path chaged to chunk.js without assets.
This is not a critical problem, but not obvious.
Grateful for any ideas
{{cropper.call 'crop()'}}
throws error Assertion Failed: image-cropper-call crop() must be a function on [object Object]
The following should be added to the readme:
readAsDataURL()
)A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.