Javascript - Motion Blur Image/Canvas - javascript

is there a way to do image processing with javascript on an image or a canvas?
I need to apply a motion blur with length/strength and an angle.
I also need to export the image then. Should also work on mobile devices.
Can I do that in real-time with javascript?

You could use an SVG filter. Within an <svg> it looks like this:
svg{
overflow: visible;
}
<svg>
<filter id="verticalMotionBlur">
<feGaussianBlur in="SourceGraphic" stdDeviation="0 5" />
</filter>
<circle cx="60" cy="60" r="50" fill="green" filter="url(#verticalMotionBlur)" />
</svg>
but you can also apply it to any other DOM element on your page, including an image:
img {
filter: url(#verticalMotionBlur)
}
<svg>
<filter id="verticalMotionBlur">
<feGaussianBlur in="SourceGraphic" stdDeviation="0 5" />
</filter>
</svg>
<img src="https://picsum.photos/200"/>

Related

How can I apply a pattern to an SVG element that ignores the element's transform values?

I have a JavaScript application that modifies an inline SVG. I have multiple elements within the SVG that all need to have the same background image applied to them. Elements (paths) are positioned in the SVG via transform attributes. Presently I am using a pattern fill on the elements. Is there any way to achieve the effect of the pattern staying stationary irrespective to element transforms?
Currently I have this:
I want this:
(note: I hard-baked the path in the second photo, which can't be used in the application)
Edit:
The patterns are currently applied like so:
<defs>
<pattern id="metallicgold" x="0" y="0" width="1240" height="775" patternUnits="userSpaceOnUse">
<image xlink:href="img/gold-texture.png" />
</pattern>
</defs>
The transforms on elements look like this:
<path transform="translate(-445.0000396775016 -1950.3326958481455) rotate(317.2309439443859 2926.326416015625 2926.32666015625) scale(1 1)" style="fill: url('#metallicgold'); stroke: none;" d="M1951.326416015625,1951.32666015625L3901.326416015625,1951.32666015625L3901.326416015625,3901.32666015625L1951.326416015625,3901.32666015625L1951.326416015625,1951.32666015625Z" x="0" y="0"></path>
If you want a constant background as you transform shapes, you should consider using a filter with userSpaceOnUse filterUnits, unless the transforms are easy and apply to all elements filled, in which case, you can use patternTransform on the pattern to reverse the transform on the elements.
<svg width="800px" height="600px" viewBox="0 0 4000 4000">
<defs>
<filter id="brick" x="0" y="0" width="4000" height="4000" filterUnits="userSpaceOnUse">
<feImage xlink:href="https://s-media-cache-ak0.pinimg.com/originals/c9/97/81/c99781a0ab356681cb038f70b1df68f1.jpg" x="0" y="0" width="4000" height="4000" preserveAspectRatio="xMinYMin meet"/>
<feComposite operator="in" in2="SourceGraphic"/>
</filter>
</defs>
<g filter="url(#brick)">
<path transform="translate(-445.00 -1950.33) rotate(317.23 2926.32 2926.32) scale(1 1)" stroke="none" fill="red" d="M1951.326416015625,1951.32666015625L3901.326416015625,1951.32666015625L3901.326416015625,3901.32666015625L1951.326416015625,3901.32666015625L1951.326416015625,1951.32666015625Z" x="0" y="0"></path>
</g>
<rect x="1250" y="500" width="300" height="300" fill="blue"/>
<g filter="url(#brick)">
<circle cx="1000" cy="1000" r="500"/>
</g>
</svg>

How to set static SVG size for `<g id="child">` element under `<svg id="parent">` element that gets transform attr

Main Question:
Is there a way to set a static width and height on <g> elements so that they don't get effected by transform attribute done on its parent view-box <svg> element?
i.e.
<svg id="viewbox" transform="translate(1,5)scale(2)">
// continuously gets the transform attr via js upon zoom event
<g>
<path "the shape of a triangle"/>
<path same/>
<path same/>
<path same/>
<path same/>
</g>
</svg>
I want everything under the <g> element to translate according to the zoom event transform values that the <svg> view-box receives, but not scale the dimensions of the <g> element. So that it looks like the screen is zooming into one section of the view-box, but without the <g> elements changing dimensions.
Instead of applying transformations to the svg element tag (svg) directly, you can use a group tag (g) to translate everything and a rectangle tag (rect) to scale only your 'viewbox'.
<svg width="1000" height="1000" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(1, 5)">
<rect
id="viewbox"
fill="black"
width="100"
height="100"
transform="scale(2)" />
<!-- your elements down here -->
<rect
fill="grey"
width="20"
height="20"
x="10"
y="10" />
</g>
</svg>
Hope this help :)

How to animate an referential SVG background

Does exists some way to animate referential background svg with vivus.js? I'm trying to use it. I found this code in the oficial documentation but I don't know if this is possible. Look at the code below:
HTML
<section id="svg-bg" class="materiais-topo">
<!-- some elements here -->
</section>
CSS (SASS)
.materiais-topo {
background-color: $green-fluo;
background-image: url('../images/line-fluo.svg');
background-position: center center;
background-repeat: no-repeat;
}
JS
new Vivus-bg('svg-bg', {
file: MAIN_URL+'dist/images/line-fluo.svg'
});
Someone has any solution? If you know to animate referential background svg without vivus.js let me know.
EDIT: This method only inject SVG file in my div element.
So, as far as I know, it's impossible to manipulate a Background SVG with Javascript.
But, you can:
Use SMIL animations in your SVG (It’s will not work with MSIE/Edge), example here.
Generate a data:uri for every frame with Javascript, and use them as a background-image.
Here an example of SVG SMIL animation:
<svg xmlns="http://www.w3.org/2000/svg" width="300px" height="100px">
<rect x="0" y="0" width="300" height="100" stroke="black" stroke-width="1" />
<circle cx="0" cy="50" r="15" fill="blue" stroke="black" stroke-width="1">
<animateMotion path="M 0 0 H 300 Z" dur="3s" repeatCount="indefinite" />
</circle>
</svg>

Is it possible to extend the height and width of a child element beyond its container?

I have a zoomable svg that's provided by 3rd a party API. It's basically a drawing that's mapped to a grid. The problem is the API doesn't include the grid in the provided svg file so I have to hack it to include one. Basically, the markup is like this:
<svg>
<g>
<line>....
<rect>....
etc...
</g>
</svg>
The zoom functionality is done and now I'd like to add the grid. I'm thinking I should add it like so:
<svg>
<g>
<rect x="0" y="0" width="100%" height="100%" fill="black" />
<defs>
<pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M 1 1 L 0 0 0 0" fill="none" stroke="green" stroke-width="1" />
</pattern>
</defs>
<rect x="-100%" y="-100%" width="200%" height="200%" fill="url(#grid)" />
<line>....
<rect>....
etc...
</g>
</svg>
The grid is drawn but it's bound within the <g> tag. Is it possible to extend the grid beyond it but still zoomable? Or are there other better ways to achieve this?

How to adjust contrast, darken/lighten vector graphics using dojox.gfx

I am using dojox.gfx to create and manipulate vector graphics. I need to adjust contrast and apply blur, darken/lighten effect on them?
And the browser I need to support are IE 8+. So, I have to achieve these things on SVG(IE 9) and VML(IE 8)
Is there a way to achieve this? Through dojo or any other library.
This is for svg:
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<filter id="brightness">
<feComponentTransfer>
<feFuncR type="linear" slope="4"/>
<feFuncG type="linear" slope="4"/>
<feFuncB type="linear" slope="4"/>
</feComponentTransfer>
</filter>
<image filter="url(#brightness)" x="0" y="0" width="200" height="100" xlink:href="pic.png" />
</svg>
For VML I'm not sure.
It might be the blacklevel attribute,values are between -0.5(pure black) and 0.5(pure white)
<v:image style='width:200px;height:100px' src="images/temporary/pic2.png" blacklevel="-0.2"/>
This is the link for the vml blacklevel attribute
http://msdn.microsoft.com/en-us/library/bb229563%28v=vs.85%29.aspx

Categories