Changing -webkit-mask-position through javascript - javascript

I'm working on an iPad webview project that requires a slider to move back and forth over two pictures, revealing one or the other when sliding to the left or right. Due to project restraints, I can't utilize jQuery. I currently have the left picture on top with a transparent mask over it and when the -webkit-mask-position is increased, it reveals more of the bottom picture, when decreased, more of the top (covering the bottom one).
I'm using a javascript plugin called Draggy (https://github.com/jofan/Draggy) to move the slider back and forth and want to use its onChange function call to update the position of the mask, but I can't figure out what javascript calls "-webkit-mask-position" to save my life.
Any ideas?
PS: webkitMaskPosition adds style="-webkit-mask: XX" to the element, which I COULD use (filling in the other values in the js), but it's being really buggy. I'm looking into it now.
OH MAN I GOT IT.
var maskSlider = document.getElementById('molecule');
function moveMask(x, y) {
var xx = x - 285;
var z = "-webkit-gradient(linear, left center, right center, color-stop(0.5, black), color-stop(0.5, transparent)) no-repeat scroll " + xx + "px padding padding";
maskSlider.style.webkitMask = z;
}
The -285 is to get it to line up to where the slider is on the image. I have no idea if I'm really doing this the right way, but it worked. If anyone can think of a better/ more efficient way to do this, please let me know.

I've recently worked a lot about webkit masks which are using CSS3 gradients to make transitions between images.
I preferred to append a style tag to head tag which is made dynamically by my calculations. And also I used CSS3 animation too. Something like this:
var cssStr = '<style id="myTransition">.myTransition_wipe{' +
'-webkit-mask-size: 200% 200%;' +
'-webkit-mask-repeat: no-repeat;' +
'-webkit-animation: wipe 2s;' +
'-webkit-animation-direction: normal;' +
'-webkit-animation-iteration-count: 1;' +
'-webkit-animation-fill-mode: forwards;' +
'-webkit-mask-position: offsetLeftS 0;' +
'-webkit-mask-image: -webkit-gradient(linear, left top, right top, ' +
'color-stop(0%, transparent), color-stop(20%, transparent), ' +
'color-stop(25%, transparent), color-stop(30%, transparent), ' +
'color-stop(50%, rgba(0, 0, 0, 1)), color-stop(98%, rgba(0, 0, 0, 1)), ' +
'color-stop(100%, rgba(0, 0, 0, 1)));}' +
'#-webkit-keyframes wipe {' +
'0% { -webkit-mask-position: offsetLeftS 0; }' +
'100% { -webkit-mask-position: offsetLeftD 0; }' +
'}' +
'</style>';
var compStyle = getComputedStyle(currentElement);
var width = parseInt(compStyle.getPropertyValue("width"));
var height = parseInt(compStyle.getPropertyValue("height"));
cssStr = cssStr.replace(/offsetLeftS/g, '-' + (width * 1) + 'px');
cssStr = cssStr.replace(/offsetLeftD/g, '+' + (width * 1) + 'px');
$('head').append(cssStr);
When I want to apply a transition, I remove the style tag by its ID and remove the class myTransition_wipe from element too, then append a new one to head tag and add the class name to element too.
Pay Attention: You must store the styles that element should have after the animation is finished and add them right after the animation is finished. Otherwise, when you remove class name and style tag, everything will be reset.
Good Luck

Related

How to change value of CSS variable as page scrolls gsap?

I have a css variable named --color. I want to change the value of this css variable as the page scrolls down. The scrolling of the page should "scrub" the value.
Example: --color starts out at rgb(255, 255, 255). As the page scrolls down, the value gets closer to and eventually reaches rgb(0, 0, 0) upon scrolling down all the way. When scrolling back up, the value should slowly advance back to rgb(255, 255, 255), reaching it by the time the page is scrolled up completely.
I have been trying to achieve this with GSAP but have yet to find any success, although I believe it must be possible with the library.
Sure, here you go:
gsap.to("body", {
"--color": "black",
scrollTrigger: {
start: 0,
end: "max",
scrub: true
}
});
https://codepen.io/GreenSock/pen/WNOzWaM?editors=0110
By the way, there are dedicated GSAP forums at https://greensock.com/forums
unfortunately I am not familiar with GSAP, but
here is the link that describes how to get the computed styles and the property value of that style with JS.
You need to listen to scroll event and change the value of the css variable inside of the listener, like so:
document.addEventListener('scroll', function(e) {
var root = document.querySelector(':root');
var newColor = // do your color calculations here;
root.style.setProperty('--color', newColor);
}
here are some useful links.
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/setProperty
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/getPropertyValue
https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
Here is an average calculation for your rgb() color that might be fine enough to go from light to dark and back. It is far to be perfect.
const body = document.querySelector("body ");
const bodyHeight = document.querySelector("body").offsetHeight;
body.innerHTML = '<p style="position:sticky;top:0;">Body Height: ' + bodyHeight + 'px <br>Window Height: ' + window.innerHeight + 'px</p>';
const root = document.querySelector(":root");
window.addEventListener("scroll", (event) => {
let scroll = this.scrollY;
let ratio = (scroll / (bodyHeight - window.innerHeight ) ) ;
let rgbvalue = 255 - ratio * 255;
root.style.setProperty( "--color", "rgba(" + rgbvalue + "," + rgbvalue + "," + rgbvalue + ")"
);
console.log(rgbvalue);
});
body {
background: var(--color, rgb(255, 255, 255));/* use defaul trgb(255, 255, 255) untill var is set from js */
height: 300vh;
}
<div></div>
It's helpful when you provide a code snippet to show what has already been attempted. Helps with specificity of the answer.
To give a general answer to your question, you can use ScrollTrigger to define the point at which the color changes. Define the markers where it should start changing and use properties such as coloronEnter, onLeave, onEnterBack to your callback to change the color.

Photoswipe: move image container vertically upwards

As the title would suggest, I'm trying to shift the position of the image container vertically upwards (this is in order to give more room for my captions on mobile displays).
It seems that the image container div (class="pswp__img") sits within another div with class="pswp__zoom-wrap". This second div determines the position of the image via the CSS style "transform: translate3d(..)". I have tried parsing through the photoswipe.js script, however my somewhat limited knowledge of JS has me stuck.
Can anyone point me to where in the photoswipe.js script the vertical offset in "transform: translate3d(..)" is set?
Link to github repo containing JS files of interest (photoswipe.js & photoswipe-ui-default.js are the two files to look at):
https://github.com/dimsemenov/PhotoSwipe/tree/master/dist
Below are chunks from "photoswipe.js" which are involved with setting translate3d that I've found so far:
_applyZoomTransform = function(styleObj,x,y,zoom) {
styleObj[_transformKey] = _translatePrefix + x + 'px, ' + y + 'px' + _translateSufix + ' scale(' + zoom + ')';
_translatePrefix = 'translate' + (allow3dTransform ? '3d(' : '(');
_translateSufix = _features.perspective ? ', 0px)' : ')';

Jquery UI Slider range styling (left, and right as well)

Jquery UI slider gives access to class ui-slider-range to do custom css on the selected range. Is there an easy way to add custom css (in my case background color) to what is left and right of the selected range?
Changing the slider background color changes both left and right, I however want a trio effect essentially of 3 separate background colors for the 3 divided regions created by the range min/max selectors;
You could use jQuery to add a background-image style property to your .ui-slider. You'll have to calculate the position of the sliders as a percentage.
For example, check out the CSS
.ui-slider {
background-image: -webkit-linear-gradient(left, red 50%, blue 50%);
}
Your jQuery would update the style for that specific slider whenever the user moves the slider. Check out this jsFiddle.
var myMin = 0, myMax = 500;
$("#slider-range").slider({
range: true,
min: myMin,
max: myMax,
values: [75, 300],
slide: function (event, ui) {
// Update amount text
$("#amount").val("$" + ui.values[0] + " - $" + ui.values[1]);
// Update left/right color
var left = 100 * (ui.values[0] - myMin) / (myMax - myMin);
var right = 100 * (ui.values[1] - myMin) / (myMax - myMin);
$(this).css('background-image', '-webkit-linear-gradient(left, red ' + left + '%, blue ' + right + '%)');
}
});
Note, you'll have to find a way to initially color the left/right side. Also, there are a few browser-specific background-image properties, see this answer.

Parallax background image for top-bottom and not right-left

I wrote a script that changes the BG position as you scroll down, its works good for left and right positions but i cant seem to reach the syntax that will allow me to parallax the background-position top or bottom - instead of right and left.
here is my code:
function parallax(){
var scrolled = $(window).scrollTop();
$('section.intro .custombg').css('background-position',(scrolled * -0.2) + 'px');}
$(window).scroll(function(e){
parallax();
});
}
The css attribute background-position has two values, #horizontal #vertical.
See: http://www.w3.org/wiki/CSS/Properties/background-position
Consider something like:
function parallax(){
var scrolledTop = $(window).scrollTop();
var scrolledLeft = $(window).scrollLeft();
$('section.intro .custombg').css('background-position',(scrolledLeft * -0.2) + 'px ' + (scrolledTop * -0.2) + 'px');}
$(window).scroll(function(e){
parallax();
});
}
Also, this seems like it will add the scroll event every time the parallax method is called. To correct this, you could try:
function parallax(top, left) {
$('section.intro .custombg').css('background-position',(left * -0.2) + 'px ' + (top * -0.2) + 'px');}
} // end function
$(document).ready(function() {
$(window).scroll(function(e) {
parallax($(window).scrollTop(), $(window).scrollLeft()); // call the method
});
});
This is all wrong, you are setting up an event handler each time you use $(window).scroll(). You only need to do that once. Try this.
var scrolledTop,
scrolledLeft,
background_position,
$custom_bg;
function parallax(){
scrolledTop = window.scrollY,
scrolledLeft = window.scrollX,
background_position = (scrolledLeft * -0.2) + 'px ' + (scrolledTop * -0.2) + 'px');
console.log('background_position', background_position);
$custom_bg.css('background-position', background_position);
}
$(function() {
$custom_bg = $('section.intro .custombg');
$(window).on('scroll', parallax);
});
try
function parallax(){
var scrolled = $(window).scrollTop();
$('section.intro .custombg').css('background-position','center ' + (scrolled * -0.2) + 'px');}
$(window).scroll(function(e){
parallax();
});
}
If you're looking to do more with parallax and change other properties as, I'd highly recommend the Skrollr library (https://github.com/Prinzhorn/skrollr).
You can vary almost any CSS property as you scroll, giving you more options than just background position or something else. It might be more than you're looking for, but it's pretty lightweight and has mobile support, too (which you could have trouble accounting for without a well-developed library). Hope it helps!
For example, if you wanted to shift the background-position of a background image, you could simply do the following:
initialize skrollr (in this case without options, but there are parameters you can set)
<script type="text/javascript">
var s = skrollr.init();
</script>
Then, you're able to use simple data-tags to tell Skrollr which elements you want to make fancy and which you don't. In your case, you could do something vaguely like the following:
(whatever element you want to use parallax on)
<div data-0="background-color:rgb(0,0,255);transform[bounce]:rotate(0deg);" data-500="background-color:rgb(255,0,0);transform[bounce]:rotate(360deg);">
WOOOT
</div>
However, you'd swap background-color out for background-position
<div data-0="background-position: 0px 0px" data-700="background-position: 0px 100px"> </div>
or
<div data-0="background-position: top center" data-700="background-position: bottom center"> </div>
You can use any of the accepted CSS background-position keywords.
Useful:
https://github.com/Prinzhorn/skrollr

Magnify image using only one image

I'm trying to achieve a very simple objective which is to magnify an image. After some searching on the net, it seems like most of the js scripts out there required two image ( one for thumbnail size and another one for zoom-ed size). I'm wondering if I am only having one image, is it still possible to achieve the zoom effect?
I wish to achieve something like this link jQuery ImageZoom with only one image, of course, in a free edition.
I've recently wrote Magnifier.js, if you don't provide the large image the thumbnail will be used instead
You can use one image to zoom with Magic Zoom - you just reference the same large image in both the src and the href and you use width and height to force the img smaller to the size you want.
For example:
<img src="your-big-image.jpg" width="300" height="150">
This approach is fine, though it isn't recommended because it creates a delay while the large image downloads.
You can use the trial version of Magic Zoom free of charge if you don't mind the message shown in the corner.
there is not any complex codes to be written for this purpose
you only need consider these steps
1.create magnifier glass element and set the image that you want to be magnified as background image then set scale(1.5) or 2 for that(you should consider that your glass element can be say 50px in 50px while your background image is 500px in 500px that is help us do the trick)
2.when your mouse pointer come in picture box the magnifier glass should pursue the pointer thats where jquery come in
3.you should get offset of the pointer then change the background-position of
the magnifier glass at same time.
jquery code would be something like this
$(".mpboxpic").mouseenter(function () {
$("#zoombox").css({ "background": "url('" + $(this).attr("src") + "') no-repeat" })
//با این کد تصویر پس زمینه دارای سایز یکسانی خواهد شد
$("#zoombox").css({ "background-size": $(this).width() + "px " + $(this).height() + "px" })
}).mouseleave(function () {
$("#zoombox").hide()
var tg = $("#zoombox").css("background-image")
px = 0;
py = 0;
})
$(".mpboxpic").mousemove(function (p) {
if (px==0) {
$("#zoombox").fadeIn(200)
}
//با کد های زیر مرکز دایره دقیقا در زیر موس قرار میگیرد
px = p.pageX-$("#zoombox").height()/2
py = p.pageY - $("#zoombox").width() / 2
$("#zoombox").css({ "top": py + "px", "left": px + "px", "position": "absolute" });
var my = p.pageY - ($(this).offset().top + $("#zoombox").height() / 4)
var mx = p.pageX - ($(this).offset().left + $("#zoombox").width() / 4)
var coord = "-" + mx + "px " + " -" + my + "px"
$("#zoombox").css({"background-position":coord})
})
and css
#zoombox{
display:none;
position:absolute;
border:5px solid rgba(248, 243, 243, 0.72);
top:25%;
left:25%;
z-index:5;
height:50px;
width:50px;
border-radius:100px;
pointer-events:none;
transform:scale(2);
}
that mpboxpic is your main picture and zoombox is your html tag as magnifier glass
<div id="zoombox">
</div>

Categories