rough-notation icon indicating copy to clipboard operation
rough-notation copied to clipboard

On scroll delay?

Open ghost opened this issue 5 years ago • 5 comments

Great library for starters but is there a way to delay the annotation until you've scrolled to a section on the page? I'm using the code below ATM. Thanks

`const annotate = RoughNotation.annotate; const annotationGroup = RoughNotation.annotationGroup;

const g1 = annotate(document.querySelector('.highlight'), { type: 'highlight', color: '#FAE633', multiline: true, animationDuration: 1500, animationDelay: 3000, iterations: 1 });

const ag = annotationGroup([g1]); ag.show(); `

ghost avatar Jun 25 '20 11:06 ghost

I think the best solution would be use this with IntersectionObserver. Once the observer lets you know the content is visible you can call ag.show()

pshihn avatar Jun 25 '20 17:06 pshihn

I assembled something like this. Perhaps it helps someone else.

import { annotate } from 'rough-notation';


const observer = new IntersectionObserver(handleIntersection, { threshold: [1] });
let annotations;


document.addEventListener('DOMContentLoaded', function () {
  annotations = Array.from(document.querySelectorAll('*[data-annotate]'))
    .map((element, i) => {
      const id = i.toString();
      const annotation = annotate(element, {
        type: 'circle',
        color: '#1755d1',
        padding: 20,
        animationDuration: 1600,
      });
      element.dataset.annotateId = id;
      observer.observe(element);
      return { id, annotation };
    });
});


function handleIntersection(entries, observer) {
  entries
    .filter((entry) => entry.isIntersecting)
    .forEach((entry) => {
      const element = entry.target;
      const annotation = annotations
        .filter(({ id }) => id === element.dataset.annotateId)[0].annotation;
      annotation.show();
    });
}

The elements are found based on having the data-annotate HTML attribute. You can further customize the annotation using more attributes like this, e.g. data-annotate-type="circle", and then getting it in JS by element.dataset.annotateType.

There's global variable and all in all it's not the most beautiful JS I've ever written, but it's vanilla solution to the problem. If you want to customize when exactly the animation starts, see the Intersection Observer API docs at MDN. The key part is the threshold option.

honzajavorek avatar Oct 08 '20 10:10 honzajavorek

@pshihn Perhaps this could make it to docs in some form? I guess this might be a frequent way of using the annotations.

honzajavorek avatar Oct 08 '20 10:10 honzajavorek

Hoping this might help someone!

var exports = {};
import { annotate, annotationGroup } from 'https://unpkg.com/rough-notation?module';

// define an observer instance
var observer = new IntersectionObserver(onIntersection, {
  root: null,   // default is the viewport
  threshold: 0.5 // percentage of target's visible area. Triggers "onIntersection"
})

// callback is called on intersection change
function onIntersection(entries, opts){
  
  entries.forEach(entry =>  
    entry.target.classList.toggle('visible', entry.isIntersecting)

  )
          const getElement = document.querySelector('#intro');
          const n5 = document.querySelector('.underline-one');
          const n6 = document.querySelector('.underline-two');

          const a5 = annotate(n5, { type: 'underline', color: '#0D1312', strokeWidth: 1.5});
          const a6 = annotate(n6, { type: 'underline', color: '#0D1312', strokeWidth: 1.5});

          const ag = annotationGroup([a5, a6]);

       if (getElement.matches('.visible')){
//          console.log('element match');
                  ag.show();
         
                observer.unobserve( document.querySelector('.intro') );
            }
        }

// Use the observer to observe an element
observer.observe( document.querySelector('.intro') );

Riley-I avatar Aug 05 '23 20:08 Riley-I

Hoping this might help someone!

var exports = {};
import { annotate, annotationGroup } from 'https://unpkg.com/rough-notation?module';

// define an observer instance
var observer = new IntersectionObserver(onIntersection, {
  root: null,   // default is the viewport
  threshold: 0.5 // percentage of target's visible area. Triggers "onIntersection"
})

// callback is called on intersection change
function onIntersection(entries, opts){
  
  entries.forEach(entry =>  
    entry.target.classList.toggle('visible', entry.isIntersecting)

  )
          const getElement = document.querySelector('#intro');
          const n5 = document.querySelector('.underline-one');
          const n6 = document.querySelector('.underline-two');

          const a5 = annotate(n5, { type: 'underline', color: '#0D1312', strokeWidth: 1.5});
          const a6 = annotate(n6, { type: 'underline', color: '#0D1312', strokeWidth: 1.5});

          const ag = annotationGroup([a5, a6]);

       if (getElement.matches('.visible')){
//          console.log('element match');
                  ag.show();
         
                observer.unobserve( document.querySelector('.intro') );
            }
        }

// Use the observer to observe an element
observer.observe( document.querySelector('.intro') );

I'm trying to implement this, I am working on a site that uses fullpage.js and I want the animation to start when the user has scrolled into a sections slide. This is the code I have in place, I can't get your code to work with the working example I have:

import { annotate, annotationGroup } from "https://unpkg.com/rough-notation?module";

const n2 = document.querySelector("strong");

const a2 = annotate(n2, { type: "circle", color: "red", padding: 10, animationDuration: 1600 });

const ag = annotationGroup([a2]); ag.show();

Larraine avatar Jan 08 '24 15:01 Larraine