Jquery Parallax Scrolling Effect - Multi Directional

Parallax effect jumping

I don't see anything "wrong" on your code. I will bet that the cause are the 2,1MB of your image, being resized from 2500px to the window width. Take into account that the browser is trying to "paint" the image and calculate position on every scroll value...

I'd approach it with background position on css but keeping with yours, the problem seems to be focused on performance. What you do on JS is a bit inefficient, cause first you select all '*[class^="prlx"]' loop through them, and then you apply again to all of them in every loop a position recalculation by looking again for them. As you are looping through elements, you can use this element and apply the change on it. Save $this to a variable is just to not apply jQuery twice on the same element and save a little resources, but in this case may not be so important.

Here on my laptop I don't see it jumpy. Try that and using a smaller image to see if it improves a bit the performance.

    jQuery(document).ready(function() {      jQuery(window).scroll(function() {        jQuery('*[class^="prlx"]').each(function(r) {          var $this = $(this);          var pos = $this.offset().top;          var scrolled = $(window).scrollTop();          $this.css('top', +(scrolled * 0.6) + 'px');        });      });    });
*[class^="prlx"] {  position: absolute;  width: 100%;  height: 300%;  top: 0;  left: 0;  z-index: -1;  background-size: 110%;}.prlx-2 {  background-image: url('http://www.roscodigitalmedia.co.uk/rosco/wp-content/uploads/2015/12/bigstock-Artist-Photographer-Retouches-91840682.jpg');}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><div class="container-fluid homeHeader">  <div class="prlx-2">
</div></div>

Problem with parallax effect animation for imageViews in Swift

Downloaded your GitHub project...

You are getting the "thin line is part of the next image" because this part of your code in scrollViewDidScroll:

if -(scrollView.currentVerticalOffset + UIApplication.shared.topSafeAreaInset) > 0 {
// change some framing / constraint values...
} else {
// if user do not drag to dawn I disable constraints
disableUniversalImageViewConstraint(imageView: placeImageScrollView.currentImageView)
}

Doesn't reset the values in the else block. So, your original 0 values "get stuck" at > 0 (usually ends up being 0.5).


Not sure what you mean by "the animation becomes very sharp" ... although, the imageViews can get misplaced due to the way you're adding / removing constraints.

I would suggest not mixing / matching explicit frames and constraints. Take a look at this approach:

class ViewController: UIViewController {

// MARK: Properties

lazy var place: Place = Place(imageNames: ["firstLakeLemuriaImage", "secondLakeLemuriaImage", "thirdLakeLemuriaImage"])

// scrollView to display all content
private lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView(frame: screenBounds)
scrollView.contentSize = CGSize(width: screenWidth, height: placeDescriptionContentView.frame.height + screenWidth)
scrollView.frame.size.height -= UIApplication.shared.bottomSafeAreaInset
scrollView.backgroundColor = .white
scrollView.delegate = self
scrollView.tag = 1
return scrollView
}()

// scrollView to display place images
private lazy var placeImageScrollView: ImageScrollView! = {
let scrollView = ImageScrollView(frame: CGRect(x: 0, y: -UIApplication.shared.topSafeAreaInset, width: screenWidth, height: screenWidth), place: place)
scrollView.delegate = self
scrollView.tag = 2
// allow subviews to show beyond scroll view's frame
// so we can "stretch" them for the parallax effect
scrollView.clipsToBounds = false
return scrollView
}()

private lazy var placeImagePageControl: UIPageControl! = {
let pageControlWidth = 160.0
let pageControlHeight = 36.0
let leftPageControlSpacing = 58.0
let pageControl = UIPageControl(frame: CGRect(x: screenWidth - pageControlWidth - sideSpacing + leftPageControlSpacing, y: sideSpacing, width: pageControlWidth, height: pageControlHeight))
pageControl.addTarget(self, action: #selector(pageDidChange(_:)), for: .valueChanged)
pageControl.numberOfPages = 3
return pageControl
}()

private lazy var placeTitleView: UIView = {
let titleLabel = UILabel(frame: CGRect(x: sideSpacing, y: 0.0, width: screenWidth - sideSpacing * 2, height: 60.0))
titleLabel.font = UIFont.systemFont(ofSize: 31.0, weight: .bold)
titleLabel.text = "Place Title"
titleLabel.textColor = .white
titleLabel.adjustsFontSizeToFitWidth = true

let shadowView = UIView(frame: CGRect(x: 0.0, y: screenWidth - 60.0 - UIApplication.shared.topSafeAreaInset, width: screenWidth, height: 60.0))
shadowView.layer.shadowPath = UIBezierPath(roundedRect: shadowView.bounds, cornerRadius: 10.0).cgPath
shadowView.layer.shadowColor = UIColor.black.cgColor
shadowView.layer.shadowOffset = CGSize.zero
shadowView.layer.shadowOpacity = 0.3
shadowView.layer.shadowRadius = 35.0
shadowView.clipsToBounds = false
shadowView.addSubview(titleLabel)

return shadowView
}()

// contentView with description about place
private lazy var placeDescriptionContentView: UIView = {
let view = UIView(frame: CGRect(x: 0.0, y: placeImageScrollView.frame.maxY, width: screenWidth, height: 1000.0))
view.backgroundColor = .white
return view
}()

// indicates that image constraints is enable
private var isConstraintEnable = false

override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
addSubviews()
setupConstraints()
}

override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}

// MARK: Methods

private func addSubviews() {
view.addSubview(scrollView)
scrollView.addSubview(placeImageScrollView)
view.addSubview(placeImagePageControl)
scrollView.addSubview(placeTitleView)
scrollView.addSubview(placeDescriptionContentView)
}

private func setupConstraints() {

placeImageScrollView.translatesAutoresizingMaskIntoConstraints = false
placeImageScrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
placeImageScrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
placeImageScrollView.heightAnchor.constraint(equalToConstant: screenWidth).isActive = true
placeImageScrollView.widthAnchor.constraint(equalTo: placeImageScrollView.heightAnchor).isActive = true

}

// MARK: Objc methods

@objc private func pageDidChange(_ sender: UIPageControl) {
placeImageScrollView.setContentOffset(CGPoint(x: CGFloat(sender.currentPage) * screenWidth, y: 0), animated: true)
placeImagePageControl.currentPage = sender.currentPage
// change current imageView
placeImageScrollView.currentImageView = placeImageScrollView.imageViewsArray[placeImagePageControl.currentPage]
}
}

// MARK: UIScrollViewDelegate

extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.tag == 1 {
// if user the user is dragging the page down
if -(scrollView.currentVerticalOffset + UIApplication.shared.topSafeAreaInset) > 0 {

// calculate the *original* imageView frame
let n = CGFloat(placeImagePageControl.currentPage)
var r = CGRect(x: n * screenWidth, y: 0.0, width: screenWidth, height: screenWidth)

// we want the bottom of the imageView to "stick" to the top of the placeDescriptionContentView
// convert placeDescriptionContentView.frame to view coordinate space
let ff = scrollView.convert(placeDescriptionContentView.frame, to: view)

// we want to change the *original* imageView size by 1/2 of the difference
let v = (screenWidth - ff.origin.y) * 0.5
r = r.insetBy(dx: v, dy: v)
// move it back to the top
r.origin.y = 0
// set the new frame
placeImageScrollView.currentImageView.frame = r

} else {

// reset the imageView's frame
let n = CGFloat(placeImagePageControl.currentPage)
let r = CGRect(x: n * screenWidth, y: 0.0, width: screenWidth, height: screenWidth)
placeImageScrollView.currentImageView.frame = r
}
} else {

// user is scrolling the images left/right
let currentPage = Int(round(scrollView.contentOffset.x / scrollView.frame.width))
placeImagePageControl.currentPage = currentPage > 2 ? 2 : currentPage
placeImageScrollView.currentImageView = placeImageScrollView.imageViewsArray[placeImagePageControl.currentPage]

}
}
}

final class ImageScrollView: UIScrollView {
var currentImageView: UIImageView!
// array for added imageViews
var imageViewsArray: [UIImageView] = []

init(frame: CGRect, place: Place) {
super.init(frame: frame)
setupImageScrollView(place: place)
}

required init?(coder: NSCoder) {
super.init(coder: coder)
}

private func setupImageScrollView(place: Place) {
contentSize = CGSize(width: screenWidth * 3, height: frame.height)
showsHorizontalScrollIndicator = false
backgroundColor = .white
isPagingEnabled = true

// add imageViews for scrollView
for index in 0...2 {
let image = UIImage.getImageFromBundle(fileName: place.imageNames[index], fileType: "jpg")
let imageView = UIImageView(frame: CGRect(x: screenWidth * CGFloat(index), y: 0.0, width: screenWidth, height: screenWidth))
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.image = image
addSubview(imageView)
imageViewsArray.append(imageView)
index == 0 ? currentImageView = imageView : nil
}
}
}


Related Topics



Leave a reply



Submit