If I have an image that I apply a filter to, e.g. Lomo filter, is there way to make that the current Caman instance?
Meaning, if I then want to then play about with the brightness on the image that I applied the filter to, and use this.revert(); to reset the brightness, I want it to revert to the canvas with the filter on it that I just applied.
Is this possible?
I'm having a nightmare with trying to apply many effects, only one at once (except for preset filters), and carry the state through...
If i understand, you want to apply filter ("Lomo") as shown on their example page and then fiddle with some properties (like brightness) and then revert changes back to "Lomo" filter?
Why not just click on filter ("Lomo") again?
EDIT:
You should probably take a look at guide and implement your own method with default values like in filters.
u.Filter.register("lomo", function (D) {
if (D == null) {
D = true
}
this.brightness(15);
this.exposure(15);
this.curves("rgb", [0, 0], [200, 0], [155, 255], [255, 255]);
this.saturation(-20);
this.gamma(1.8);
if (D) {
this.vignette("50%", 60)
}
return this.brightness(5)
});
I dont think your requirement comes "out of the box".
If i understand you correctly , You want to apply a filter and play with other effects like brightness and contrast etc.,
I made some code which will work according to your need
Caman('#canvas-camanImage',"./../media/caman.png", function () {
this.revert(false);
for(var i = 0 ;i<selectedPresets.length;i++){
this[selectedPresets[i]]();
}
for(var key in effect){
this[key](effect[key].value);
}
this.render(function () {
});
in the above code i am storing all effects like brightness contrast in effect variable like effect = {
brightness : {
min : -100,
max: 100,
value : 0
},
contrast : {
min : -100,
max: 100,
value : 0
},
saturation : {
min : -100,
max: 100,
value : 0
}
};
and presets in an array
presets = [
{filter:'vintage',name : 'Vintage'},
{filter:'lomo',name:'Lomo'},
{filter: 'clarity', name:'Clarity'},
{filter:'sinCity', name:'Sin City'}
];
So every time you add any preset or change any effect value i am changing the values in variable and rendering canvas again
It is working very fine for me Let me know if your concern is something else
Related
Consider the following code:
<div class="red-square"
*ngIf="someCondition"
[#showHideAnimation]
></div>
Is there a way to cause aforementioned div to disappear with random animation?
Random animation being, for example, rotation of the object by any number of degrees between, say, 30 and 150.
I have an idea, but it's not randomized per se.
given your animation
animations: [
trigger('animationName', [
state('void', style({
// hidden case
})),
state('*', style({
// visible case
})),
transition(':enter', animate('TIME [DELAY] EASING')),
transition(':leave', animate('TIME [DELAY] EASING'))
])
]
What you could do is make a global function like so
function randomizeAnimation(propertiesNumber: number, state: number) {
let properties = ['borderBottom', 'opacity', 'All of the properties you want to animate here'];
let randomIndex = () => Math.random() * properties.length;
let style = {};
for (let i = 0; i < propertiesNumber; i++) {
let index = randomIndex();
let voidValue = '0';
let showValue = '*';
// Why it's not "randomized" : you need to make custom rules here. Example : colors
if (properties[index].toLowerCase().includes('color')) {
let RdmOct = () => Math.random() * 256;
let generateRandomColor = () => `rgb(${RdmOct()}, ${RdmOct()}, ${RdmOct()})`;
voidValue = generateRandomColor();
showValue = generateRandomColor();
}
style[properties[index]] = state ? voidValue : showValue;
}
return style;
}
What this function does is that it takes a number of properties to animate, and an animation state (boolean, or 0/1). It then choses random properties in its array, making it "random". If the properties have a special use case, such as colors (the wildcard '*' won't work), then you have to handle it. Once it has created the random style, it returns it to be used in the animate function. It's not "randomized" like a Math.random(), but it could do the trick !
In your component, you can now call this function in your animate :
animations: [
trigger('animationName', [
state('void', style(randomizeAnimation(1, 0))),
state('void', style(randomizeAnimation(1, 1))),
transition(':enter', animate('275ms ease-out')),
transition(':leave', animate('275ms ease-in'))
])
]
I'm not sure it would work, but that's close enought for your need I guess !
EDIT you could even go further by setting an Interval in your animate, changing the animation every minute or so. But if this method doesn't even work ... I won't lose more time to write this one ahah
For animations with random values you will need to create animations that accept parameters. This will allow you to provide different values in the animation so that you can get random behavior. You will need to setup one or more animations depending on what you want to animate and set parameters on the values like so:
animations: [
trigger('randomAnimation', [
transition('* => colorFade', [
animate("500ms ease-in", keyframes([
style({'background-color': "{{color}}"}),
style({'opacity': "{{opacity}}"}),
]))
], {params : { color: "yellow", opacity: "0" }}),
transition('rotateFade', [
animate("{{time}}ms ease-in", keyframes([
style({'transform': 'rotate({{rotate}}deg);'}),
style({'opacity': "{{opacity}}"}),
]))
], {params : { time: "500", rotate: "45", opacity: "0.6 }})
])
]
And then in the view you can bind the animation to an animation object that has the random values in it.
<div class="red-square" [#randomAnimation]="animationConfig"></div>
And in your component you can create the object that will make the animation random.
public setRandomAnimation() {
this.animationConfig = {
value: Math.random() > 0.5 ? 'colorFade' : 'rotateFade',
params: {
time: Math.floor(Math.random() * 5000) + 200,
color: `#${(Math.floor(Math.random() * 255)).toString(16)}${(Math.floor(Math.random() * 255)).toString(16)}${(Math.floor(Math.random() * 255)).toString(16)}`,
opacity: Math.random(),
rotate: Math.floor(Math.random() * 360),
};
}
The above method is just an example you could expand this much further and not cram it all into one method. The parameters that are not used by the animation will be ignored so it is okay to specify rotate even though it is not used in colorFade for example.
PREVIOUS ANSWER
You can define any number of animation states and then set up transitions so that when they go from any state to a specific state a certain animation will occur. Here is an example of what the animation states might look like:
animations: [
trigger('randomAnimation', [
transition('* => yellowDisappear', [
animate(300, keyframes([
style({'background-color': 'yellow'}),
style({opacity: 0})
])),
transition('* => rotateFade', [
animate(300, keyframes([
style({'transform': 'rotate(45deg);'}),
style({opacity: 0.6})
]))
])
]
You can then specify the animation that you want to apply in the template.
<div class="red-square" [#randomAnimation]="'yellowDisappear'"></div>
<div class="red-square" [#randomAnimation]="'rotateFade'"></div>
If you want to have it occur randomly I would set up some kind of Observable that would change the animation randomly and if you want it to occur on certain conditions then I would make a method in the component to set the current state of the animation based on certain conditions.
Animations in Angular are a little tricky but there is good information in the tutorial and Matias Niemelä (one of the lead developers of the Angular animation module) wrote a good article on it as well. I would recommend checking these out if your project is going to make use of animations
I'm not sure if this will work, but you can add a state to the animated div like so:
<div class="red-square"
*ngIf="someCondition"
[#showHideAnimation]="getRandomState()"
></div>
The getRandomState method can return a couple of predefined strings randomly.
Next you only need to create transitions for each of these strings to void, for example:
transition('yellowFirstState => void',[
style({'background-color':'yellow'}),
animate(100)
])
I'm using a line chart (I think) for my data, and I'm trying to have red, yellow or green dots based upon the value of the data. The problem is, I can't even change the symbols used on the graph!
I'm using data pulled from a database, so I can't simply define the data within a series[] and then define the symbol from there, it's added using the chart.addSeries() function.
I'm sorry if this is a total noob question, I'm a total noob when it comes to JavaScript and Highcharts.
EDIT: For security reasons, I can't post the code.
Answer may not be 100% accurate, but I would do something like this:
// Loop over series and populate chart data
$.each(results.series, function (i, result) {
var series = chart.get(result.id);
//I think I have to do some sort of marker: set here
$.each(result.data, function (i, point) {
var x = point.x, // OR point[0]
y = point.y; // OR point[1]
result.data[i] = {
color: y > 100 ? 'red' : 'blue',
x: x,
y: y
}
});
if (series) {
series.update(result, false);
} else {
chart.addSeries(result, false);
}
});
chart.redraw();
As you can see, here I am adding color property to the point. Right now there is simple logic (value < 100), but you can apply there anything you want to, for example function which will return correct color etc.
Note that I am extracting x and y values. How to get them depends on how your data is formatted. It can be {x: some_valueX, y: some_valueY} or [some_valueX, some_valueY] or even some_valueY only.
Important: if you have a lot of points (1000+), don't forget to increase turboThreshold or disable it.
Using Highstock to chart a sorted time serie: [[timestamp, value], ...]
The datasource is sampled at irregular intervals. As result the distances between two points (in the time axis) varies.
If two adjacent points are separated for more than 5 minutes I want to show a gap in the chart.
Using the gapSize option doesn't work, because it doesn't allows to specify the 'size' of the gap as a function of time.
Showing gaps is already a part of Highstock, I just need a way to specify it as a fixed amount of time (5 minutes). Ideas?
Btw, beside that the plot works great.
Here's a slightly unclean way to "manipulate" gapSize to work so that it's value is the amount of milliseconds required to create a gap.
(function (H) {
// Wrap getSegments to change gapSize functionality to work based on time (milliseconds)
H.wrap(H.Series.prototype, 'getSegments', function (proceed) {
var cPR = this.xAxis.closestPointRange;
this.xAxis.closestPointRange = 1;
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
this.xAxis.closestPointRange = cPR;
});
}(Highcharts));
This utilizes that gapSize is only used within the getSegments function (see source), and it works based on the closestPointRange of the axis. It wraps the getSegments, sets closestPointRange to 1, calls the original method and then resets closestPointRange to its original value.
With the code above you could do gaps for 5 minutes like this:
plotOptions: {
line: {
gapSize: 300000 // 5 minutes in milliseconds
}
}
See this JSFiddle demonstration of how it may work.
Halvor Strand function wrapper did not work for me as long as getSegments is not part of highstock source code anymore to calculate that gap. Anyway, you can find an approximation to solve the problem combining this other topic and the previows answer like this:
(function(H) {
H.wrap(H.Series.prototype, 'gappedPath', function(proceed) {
var gapSize = this.options.gapSize,
xAxis = this.xAxis,
points = this.points.slice(),
i = points.length - 1;
if (gapSize && i > 0) { // #5008
while (i--) {
if (points[i + 1].x - points[i].x > gapSize) { // gapSize redefinition to be the real threshold instead of using this.closestPointRange * gapSize
points.splice( // insert after this one
i + 1,
0, {
isNull: true
}
);
}
}
}
return this.getGraphPath(points);
});
}(Highcharts))
setting gapSize in plotOptions to the desired size (in ms) like Halvor said:
plotOptions: {
line: {
gapSize: 300000 // 5 minutes in milliseconds
}
}
In case anyone comes across this and is spending hours trying to figure out why gapSize is not working like me. Make sure your time series data is sorted, only then will the gaps appear in the graph.
Another issue I ran into was my data series was in this format
[
{x: 1643967900000, y: 72},
{x: 1643967600000, y: 72},
{x: 1643967300000, y: 72}
]
However this does not seem to work with gapSize and needs to be in the format below
[
[1643967900000, 72],
[1643967600000, 91],
[1643967300000, 241]
]
Im trying to pass a variable('maxValue') into my Highcharts guage . I cant get the variable to pass in successfully, the graph renders but without the value.
Ive tried Number and parseInt Functions but neither make a difference.
I setup a JS fiddle here: http://jsfiddle.net/d5d4cgbe/16/
The code section in question:
var maxValue = 120; //set the maxValue var
$('#visitPerformanceWeek').highcharts(Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: maxValue,
title: {
text: 'Hours Worked'
}
},
I will eventually be passing a value collected from an AJAX request, this part I have working but have excluded from the fiddle to keep it simple. Help appreciated
For setting the maxValue dynamically, something like setExtremes should do it. Try
chart.yAxis[0].setExtremes(0,maxValue);
Another alternative is the update method:
chart.yAxis[0].update({ max: maxValue });
For the maxValue to be displayed by the solidgauge, you need to specify a tickerInterval which divides into the maxValue. Presently, the chart is generating a default tick interval e.g. 10, which adds up to 100. For example, a maxValue of 120, you may set the tickInterval to 12
yAxis: {
min: 0,
max: 120,
tickInterval: 12,
...
}
JSFiddle
Check here : http://jsfiddle.net/d5d4cgbe/23/
you can set value using following command :
chart.yAxis.max = maxValue;
check browser console for yAxis value.
I want to make a graph with Highcharts/Highstock which looks like this (sorry for the bad graphic ;)):
I already found out how to do the columns and the line. What I could not find out (or what might not be possible) is:
how to have columns and lines on both sides of the x-axis?
edit: I want to set the distance between the tick points manually and statically!
how to have a x-axis which is not only irrgular, but also only shows some points with a description?
EDIT: Here is what I came up with by now: http://jsfiddle.net/pJEER/ The only thing missing is to give the columns an individual width (isn't their anything like x: 2-4), and to color them dynamically based on their value!
Thank you very much in advance!
You can use tickPositioner
http://api.highcharts.com/highcharts#xAxis.tickPositioner and ordinal as false: http://api.highcharts.com/highstock
No a straight answer but some advices:
to make column with specific width you need to have each column in a different series
for each column you can set specific color using data: [{ x: X, y:Y, color: specific_color}]. So to set specific color based on value, preprocess your data with adding property color.
To format a column based on their value you can use a little helper function where you return the point object with a certain color based on the input value.
function scatterDot(x, y, color){
return {
"x": x
, "y": y
, "color": color
, "marker": { "fillColor": color, "states": { "hover": { "fillColor": color } } }
};
}
For the dynamic plotbands you could also use a formatter function to show it depending on if it's in a specific range, making the tickpositions flexible instead of preset. I did similar for setting the datalabels.
dataLabels: {
enabled: true,
formatter: function() {
if (this.percentage >= 0) {
return this.key +"<br />"+ this.y+" ("+Math.round(this.percentage)+"%)";
} else {
return '';
}
}
}