What I'm trying to accomplish is when the window is resized, the blurred image is resized as well. For some reason the code is not working. Can someone spot what is wrong and what I need to do to correct the code. Thanks.
CSS -
/* ------- BLUR BEHIND MESSAGE HOLDER CONTAINER SETTINGS ------- */
img.clipphoto {
/*--- CLIP SETTINGS: top, right, bottom, left ---*/
clip: rect(18px,770px,600px,240px);
position: absolute;
-webkit-filter: blur(10px);
-moz-filter: blur(10px);
-o-filter: blur(10px);
-ms-filter: blur(10px);
filter: blur(10px);
}
JS -
window.addEventListener('resize', function(event){
var vInnerHeight= window.innerHeight;
var t = "18";
var r = "770";
var b = vInnerHeight-140;
var l = "240";
var clipString = "rect(" + t + "px " + r + "px " + b + "px " + l + "px)";
document.getElementByClassName(clipphoto).style.clip = clipString;
HTML -
<!-- blurred photo of pix -->
<img src="images/image1.png" width="1200" height="620" alt="" class="clipphoto">
There is no getElementByClassName() function. It's getElementsByClassName() (plural).
And you want the string "clipphoto", not the (non-existant) variable named clipphoto:
var clipString = "rect(" + t + "px, " + r + "px, " + b + "px, " + l + "px)";
document.getElementsByClassName('clipphoto')[0].style.clip = clipString;
Believe the values should be comma separated, not space separated
var clipString = "rect(" + t + "px," + r + "px," + b + "px," + l + "px)";
document.getElementsByClassName('clipphoto')[0].style.clip = clipString;
Edit: incorporated class accessor errror by Paul Roub too
Related
I have this, it worked before if I set the background and put the linear gradient inside the data-src, but when I changed it to this so that it would support more browsers, it isn't working anymore. The background gets set to an image but the gradient isn't showing up. The message that gets sent to the console is
linear-gradient(to top, rgba(2, 0, 36, .8) 0%, rgba(0, 0, 0, 0) 100%), url( '/static/images/mountain.jpg');
var url = "url( '" + slide.dataset.src + "')";
slide.style.backgroundImage = url;
if (slide.dataset.type == 'linear') {
var direction = slide.dataset.lindir;
var linstart = slide.dataset.linstart;
var linend = slide.dataset.linend;
var gradient = "linear-gradient(" + direction + ", " + linstart + ", " + linend + ")";
if (!(url == null)) {
gradient += (", " + url);
}
gradient += (";");
console.log(gradient);
slide.style.background = "-moz-" + gradient;
slide.style.background = "-webkit-" + gradient;
slide.style.background = gradient;
}
<div class="content category cursor-hand has-text-centered load" data-type="linear" data-lindir="to top" data-linstart="rgba(2, 0, 36, .8) 0%" data-linend="rgba(0, 0, 0, 0) 100%" data-src="{{ category.url }}">
The root problem is that you don't need the semicolon you are adding because you are setting the style in JavaScript, not adding a style to a stylesheet. I've commented that out below, and you can see that it works.
As others have pointed out, you are also doing your vendor prefixes incorrectly. See Setting vendor-prefixed CSS using javascript for more info on that topic.
Note, though, that support for multiple CSS backgrounds goes back to IE 9, so you probably don't need prefixes at all.
One thing to note is that since you are not setting any other background properties in your JS besides the background-image it would probably be best to use style.backgroundImage throughout instead of switching to style.background. This will let you control the other properties included in the background shorthand in your stylesheet.
var slide = document.querySelector('.slide');
var url = "url( '" + slide.dataset.src + "')";
slide.style.backgroundImage = url;
if (slide.dataset.type == 'linear') {
var direction = slide.dataset.lindir;
var linstart = slide.dataset.linstart;
var linend = slide.dataset.linend;
var gradient = "linear-gradient(" + direction + ", " + linstart + ", " + linend + ")";
if (!(url == null)) {
gradient += (", " + url);
}
//gradient += (";");
console.log(gradient);
slide.style.MozBackground = gradient;
slide.style.WebkitBackground = gradient;
slide.style.background = gradient;
}
.slide {
width: 300px;
height: 300px;
}
<div class="slide content category cursor-hand has-text-centered load" data-type="linear" data-lindir="to top" data-linstart="rgba(2, 0, 36, .8) 0%" data-linend="rgba(0, 0, 0, 0) 100%" data-src="{{ category.url }}"></div>
I'm trying to scale my SVG with g.animate({ transform: "s2.5,2.5," + bbox.cx + "," + bbox.cy }, 0); and then animate wheelAnimation(bbox.cx, bbox.cy, 1500);
var i = 0;
function wheelAnimation(cx, cy, speed){
i++;
g.animate(
{ transform: "r360," + cx + ',' + cy}, // Basic rotation around a point. No frills.
speed, // Nice slow turning rays
function(){
if(i == 5)
speed = 5000;
g.attr({ transform: 'rotate(0 ' + cx + ' ' + cy}); // Reset the position of the rays.
wheelAnimation(cx,cy, speed); // Repeat this animation so it appears infinite.
}
);
}
But my SVG didn't scaling. It's only rotates. If I remove rotation - SVG scaling. How to combine it to immediately scale and then animate rotation?
Plunker example
I've never used Snap.svg but you might try this:
var i = 0;
function wheelAnimation(cx, cy, speed, scale){
i++;
g.attr({ transform: "r0 " + cx + " " + cy + " s" + scale + "," + scale + "," + cx + "," + cy }); //Reset + Scale setup
g.animate({
transform: "r360," + cx + "," + cy + " s" + scale + "," + scale + "," + cx + "," + cy }, // Basic rotation around a point. No frills.
speed, // Nice slow turning rays
function(){
if(i == 5)
speed = 5000;
wheelAnimation(cx, cy, speed, scale); // Repeat this animation so it appears infinite.
}
);
}
Hope this helps you :)
See Plunkr
What I'm trying to do is simple: scale some SVG dots from scale(0) to scale(1) when a sibling element is hovered using vanilla js. They are the red ones in the demo
Here's the basic SVG setup
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px" viewBox="0 0 720 576" style="enable-background:new 0 0 720 576;" xml:space="preserve">
<style type="text/css">
.st3 {
fill:red;
}
* {
-webkit-transition:.3s;
transition:.3s;
}
</style>
<g id="Layer_4">
<!-- Shield -->
<path class="st8" d="M601,304.7c-32.4-15.4-68.6-24-106.8-24c-40.4,0-78.5,9.6-112.3,26.6c4.9,79.7,41.9,146.7,109.5,187.6
C559.8,454.1,597,385.6,601,304.7z" />
<path class="st9" d="M420.1,328.7c2.1-4.7,32.5-23.9,72.5-23.9c39.9,0,73.1,20,75.5,24.3c2.4,4.3,5.7,40-12.7,74.6
c-19.7,36.9-53.5,50.1-61.8,50.4c-6.4,0.2-41.8-14.3-62.5-51.6C411.5,367.4,418,333.4,420.1,328.7z" />
<circle class="st10" cx="494.9" cy="373.3" r="35.5" />
</g>
<g id="Layer_8">
<!-- Dots on shield -->
<circle class="st3" cx="578.8" cy="316.2" r="4.6" />
<circle class="st3" cx="543.4" cy="346.2" r="4.6" />
<circle class="st3" cx="505" cy="375.5" r="4.6" />
</g>
</svg>
The issue is that SVG scales based on the origin location, not the current location, thus when a transform is applied it moves the element in addition to scaling it. I am attempting to fix this situation by translating by the BBox() offset, scaling, then translating back but that only seemed to help and not entirely fix the issue.
var shield = document.getElementById("Layer_4"),
dots = document.querySelectorAll("#Layer_8 .st3");
toggleTransform(false);
shield.onmouseover = function () { toggleTransform(true); }
shield.onmouseout = function () { toggleTransform(false); }
function toggleTransform(bool) {
if (!bool) {
for (var i = 0; i < dots.length; i++) {
var box = dots[i].getBBox(),
cx = box.x + box.width / 10,
cy = box.y + box.height / 10;
//dots[i].setAttribute("transform", "translate(" + cx + " " + cy + ") scale(0) translate(" + cx + " " + cy + ")");
dots[i].style.WebkitTransform = "translate(" + cx + "px, " + cy + "px) scale(0) translate(" + -cx + "px, " + -cy + "px)";
}
} else {
for (var i = 0; i < dots.length; i++) {
var box = dots[i].getBBox(),
cx = box.x + box.width / 2,
cy = box.y + box.height / 2;
//dots[i].setAttribute("transform", "translate(0 0) scale(1) translate(0 0)");
dots[i].style.WebkitTransform = "translate(0, 0) scale(1) translate(0, 0)";
}
}
}
I tried using both setAttribute and CSS's transform (I couldn't get setAttribute to transition, presumably because it's not animatable by CSS) but couldn't get it with either. I've only been testing in Chrome
Anyone have an idea how I can scale, while not moving, red dots?
Here's the demo again if you missed it
Edit
I made a function based on RashFlash's answer to make it quite simple to use and also takes into account offsets and different transform origins
function scaleMe(elem, scaleX, scaleY, newOffsetX, newOffsetY, originX, originY) {
newOffsetX = null ? 0 : newOffsetX;
newOffsetY = null ? 0 : newOffsetY;
originX = null ? "center" : originX;
originY = null ? "center" : originY;
var bbox = elem.getBBox(),
cx = bbox.x + (bbox.width / 2),
cy = bbox.y + (bbox.height / 2),
tx = -cx * (scaleX - 1) + newOffsetX,
ty = -cy * (scaleY - 1) + newOffsetY;
if(originX === "left" || originX === "right") {
tx = newOffsetX;
}
if(originY === "top" || originY === "bottom") {
ty = newOffsetY;
}
var scalestr = scaleX + ',' + scaleY,
translatestr = tx + 'px,' + ty + 'px';
elem.style.WebkitTransformOrigin = originX + " " + originY;
elem.style.MozTransformOrigin = originX + " " + originY;
elem.style.msTransformOrigin = originX + " " + originY;
elem.style.transformOrigin = originX + " " + originY;
elem.style.WebkitTransform = "translate(" + translatestr + ") scale(" + scalestr + ")";
elem.style.MozTransform = "translate(" + translatestr + ") scale(" + scalestr + ")";
elem.style.msTransform = "translate(" + translatestr + ") scale(" + scalestr + ")";
elem.style.transform = "translate(" + translatestr + ") scale(" + scalestr + ")";
}
Updated to work with modern browsers that support transform-box
Previously, this approach worked only in Chrome. But spec changes to how transform-origin works, and the addition of transform-box now means that this works in more browsers (currently Chrome, FF, and Opera).
You can actually achieve this effect without JS.
.st3 {
fill: red;
-webkit-transform: scale(1);
-webkit-transform-origin: 50% 50%;
-webkit-transition:.3s;
transform: scale(1);
transform-origin: 50% 50%;
transition:.3s;
transform-box: fill-box;
}
#Layer_4:hover + g .st3 {
-webkit-transform: scale(2);
-webkit-transform-origin: 50% 50%;
-webkit-transition:.3s;
transform: scale(2);
transform-origin: 50% 50%;
transition:.3s;
}
Demo here
if i am not wrong, you want to scale the dots along their center, dots remain their current position and just gets bigger.
if this you want, then following code will help you
var bbox=elementNode.getBBox();
var cx=bbox.x+(bbox.width/2),
cy=bbox.y+(bbox.height/2); // finding center of element
var scalex=1.5, scaley=1.5; // your desired scale
var saclestr=scalex+','+scaley;
var tx=-cx*(scalex-1);
var ty=-cy*(scaley-1);
var translatestr=tx+','+ty;
elementNode.setAttribute('transform','translate('+translatestr+') scale('+saclestr+')');
So what i did, i first translate the dot and than scale it. i use following formula as described in
Transforming Coordinate system
translate(-centerX*(factor-1), -centerY*(factor-1))
scale(factor)
An easier way to do this that does not involve a bunch of geometry is to put the item to be scaled and translated into a parent group ('g').
Then, you apply the translation to the parent group and the scale to the element itself.
var trasnstr = x + ',' + y;
var scalestr = scaleX + ',' + scaleY;
parentElement.setAttribute('transform', 'translate(' + trasnstr + ')');
element.setAttribute('transform', 'scale(' + scalestr + ')');
This will automatically calculate and set transform-origin for any SVG element.
// mainSvgElement is SVG element itself
// svgChildElement is any path, rect, circle etc. inside SVG element
var setTransformOrigin = function(mainSvgElement, svgChildElement) {
var mainRect = mainSvgElement.getBoundingClientRect();
var childRect = svgChildElement.getBoundingClientRect();
var originX = (((childRect.left - mainRect.left) + (childRect.width * 0.5)) / mainRect.width) * 100;
var originY = (((childRect.top - mainRect.top) + (childRect.height * 0.5)) / mainRect.height) * 100;
svgChildElement.style.transformOrigin = originX + "% " + originY + "%";
};
setTransformOrigin(mainSvgElement, svgChildElement);
// set scale now / or you can set in css too
svgChildElement.style.transform = "scale(1.5)";
(function() {
var mainSvgElement = document.querySelector("svg");
var svgChildElement = mainSvgElement.querySelector("path");
// mainSvgElement is SVG element itself
// svgChildElement is any path, rect, circle etc. inside SVG element
var setTransformOrigin = function(mainSvgElement, svgChildElement) {
var mainRect = mainSvgElement.getBoundingClientRect();
var childRect = svgChildElement.getBoundingClientRect();
var originX = (((childRect.left - mainRect.left) + (childRect.width * 0.5)) / mainRect.width) * 100;
var originY = (((childRect.top - mainRect.top) + (childRect.height * 0.5)) / mainRect.height) * 100;
svgChildElement.style.transformOrigin = originX + "% " + originY + "%";
};
setTransformOrigin(mainSvgElement, svgChildElement);
// set scale now / or you can set in css too
svgChildElement.addEventListener("mouseenter", function() {
svgChildElement.style.transform = "scale(1.5)";
});
svgChildElement.addEventListener("mouseleave", function() {
svgChildElement.style.transform = "scale(1)";
});
})();
svg {
width: 100%;
border: 2px solid red;
}
path {
cursor: pointer;
transition: transform 1s;
}
Bring your mouse over on the shape:
<svg class="tb-graph" viewBox="0 0 1006 684" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M574.618 66.3322C575.377 63.1066 573.378 59.87 570.137 59.1784C512.776 46.9376 452.991 52.4821 398.793 75.1494C344.594 97.8167 298.663 136.486 267.096 185.919C265.312 188.711 266.213 192.407 269.042 194.132L357.225 247.895C360.055 249.62 363.738 248.718 365.56 245.95C384.451 217.254 411.493 194.793 443.273 181.502C475.052 168.211 510.032 164.732 543.728 171.435C546.978 172.082 550.207 170.093 550.966 166.867L574.618 66.3322Z" fill="#005453" stroke="#012020" stroke-width="2" />
https://codepen.io/animatedcreativity/pen/qBKXQKZ
I cannot see what is wrong with this code. Calculate center position of window then transform-translate div there (have to use translate for what i am doing).
Just getting this working for Chrome for a start, hence the -webkit- prefix).
Very confused as to why jQuery does not apply the inline style to the .logo div. Have included my other trouble-shooting experiments, commented out.
A syntax problem? jsfiddle here.
var centerPosition = '';
function centerLogo(){
var w_width = $(window).width();
var w_height = $(window).height();
var hCenter = (w_width / 2) - 150;
var vCenter = (w_height / 2) - 150;
console.log(hCenter);
console.log(vCenter);
var centerPosition = 'translate(' + hCenter + 'px, ' + vCenter + 'px);';
console.log(centerPosition);
$('.logo').css('-webkit-transform', centerPosition);
// Try uncommenting the three examples below - they all work ...
// $('.logo').css('background', 'blue');
// centerPosition = 'blue';
// $('.logo').css('background', centerPosition);
// $('.logo').css('-webkit-transform', 'translate(10.85px, 45.56px)');
}
jQuery(document).ready(function($){
centerLogo();
});
The correcy syntax of $('.logo').css('-webkit-transform', centerPosition); does not have semi colons inside the Strings. Try changing this:
var centerPosition = 'translate(' + hCenter + 'px, ' + vCenter + 'px);';
to this:
var centerPosition = 'translate(' + hCenter + 'px, ' + vCenter + 'px)';
Should work: http://jsfiddle.net/7f7rt/6/
This Will Sure Work.
var posElem = document.getElementById('logo'); // set id to div
var newStyle = '-webkit-transform: translate(' + hCenter + 'px, ' + vCenter + 'px);' +
'transform: translate(' + hCenter + 'px, ' + vCenter + 'px);';
posElem.setAttribute('style',newStyle);
I have a box that previews a Box Shadow. The user types in the inputs for the lenghts, blur, spread and colour (hex). So far I have this for the output of the style but it obviously doesn't work.
document.getElementById('jj_preview3').style["boxShadow"] = jj_input6 + 'px' + jj_input7 + 'px' + jj_input8 + 'px' + jj_input9 + '#' + jj_input10;
jj_input6 = Horizontal Length
jj_input7 = Vertical Length
jj_input8 = Blue Radius
jj_input9 = Spread
jj_input10 = Shadow Colour
What changes do I have to make the the javascript code snippet above to make it work?
It should work if you put in spaces. You're also missing 'px' in the last string literal.
document.getElementById('jj_preview3').style['boxShadow'] = jj_input6 + 'px ' +
jj_input7 + 'px ' + jj_input8 + 'px ' + jj_input9 + 'px #' + jj_input10;
Simply for future references:
var someVariable = document.getElementById("someId")
someVariable.style.boxShadow = "5px 5px 1.2em black";
Note: The 1.2em is for the blur effect, but px could be used as well, or it can be omitted all together.