Print Reseller Scheme
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Cursor light trail for splash page . . .

Discussion in 'Website Coding & Programming Forum:' started by Hippychick, Apr 11, 2017.

  1. Hippychick

    Hippychick Member

    Having been playing around with idea of a light trail for my neon splash page (though is a tad cheesy, so is my neon sign), I thought it would be quite easy to find code for it, like I had with <script src="snowstorm.js"></script> but is proving trickier than I thought.

    Closest I found was: https://codepen.io/MAW/pen/bpQjGY but a bit too clunky as I want it to fade smoothly, and on considering how involved a smooth transition may be, thought logically about a particle trail instead using uploaded gifs (ie. circles with transparent backgrounds) and that same day I came across the L’or coffee advert as a pop-up which has this interactive function following cursor (though is more like glitter and I want mine far more subtle & simpler).

    Anyone? This is a still of sort of effect I was after: http://www.freeimages.com/premium/vector-shooting-star-with-light-trail-1193609 but may be too complex to achieve for what it is, so a series of very small gifs could give similar effect.

    I am familiar with doing animation in Flash, but using code to animate objects following the cursor over an existing image is not my area!
     
  2. Hippychick

    Hippychick Member

  3. Hippychick

    Hippychick Member

    I have gone for a particles trail that follow cursor and float up like bubbles (as it’s on splash page?!) . . . adequately subtle so not to appear too naff like a nineties animated gif, but just adds a bit of fizz as I’ve tried to inject a bit of personality generally (total revamp of personal website) into what would otherwise be just an online portfolio.

    A sleek light trail would have been really sexy, but perhaps too much effort for how subtle I wanted it.
     
  4. Levi

    Levi Moderator Staff Member

    Your first link didn't work in my firefox (latest version) and don't forget that newest versions of firefox and chrome are dropping support for npapi plugins so some things like shockwave won't be working on newer browsers.

    doesn't need 2 images if you tweak the code a little :)

    In main html
    Code:
    <img class="pointer" src="www.neon.html/myfavouritecolour.jpg">
    
    In css
    Code:
    html,
    body {  font-size: 0;
      height: 100%;
      margin: 0;
      padding: 0;
      width: 100%;
    }
    
    body {
      background: rgb (55,255,255);
    }
    
    img.pointer {
      display: none;
    }
    
    Where body is basically your website background/content, as you can see I tweaked it to be a random shade of grey.
    img.pointer is the file used to draw the 'particles'

    Important part of the code - stick in a js file like normal and stick in header usual place.
    Code:
    var image = document.querySelector('img.pointer');
    var imageCanvas = document.createElement('canvas');
    var imageCanvasContext = imageCanvas.getContext('2d');
    var lineCanvas = document.createElement('canvas');
    var lineCanvasContext = lineCanvas.getContext('2d');
    var pointLifetime = 1000;
    var points = [];
    
    if (image.complete) {
      start();
    } else {
      image.onload = start;
    }
    
    /**
     * Attaches event listeners and starts the effect.
     */
    function start() {
      document.addEventListener('mousemove', onMouseMove);
      window.addEventListener('resize', resizeCanvases);
      document.body.appendChild(imageCanvas);
      resizeCanvases();
      tick();
    }
    
    /**
     * Records the user's cursor position.
     *
     * @param {!MouseEvent} event
     */
    function onMouseMove(event) {
      points.push({
        time: Date.now(),
        x: event.clientX,
        y: event.clientY
      });
    }
    
    /**
     * Resizes both canvases to fill the window.
     */
    function resizeCanvases() {
      imageCanvas.width = lineCanvas.width = window.innerWidth;
      imageCanvas.height = lineCanvas.height = window.innerHeight;
    }
    
    /**
     * The main loop, called at ~60hz.
     */
    function tick() {
      // Remove old points
      points = points.filter(function(point) {
        var age = Date.now() - point.time;
        return age < pointLifetime;
      });
    
      drawLineCanvas();
      drawImageCanvas();
      requestAnimationFrame(tick);
    }
    
    /**
     * Draws a line using the recorded cursor positions.
     *
     * This line is used to mask the original image.
     */
    function drawLineCanvas() {
      var minimumLineWidth = 25;
      var maximumLineWidth = 100;
      var lineWidthRange = maximumLineWidth - minimumLineWidth;
      var maximumSpeed = 100;
    
      lineCanvasContext.clearRect(0, 0, lineCanvas.width, lineCanvas.height);
      lineCanvasContext.lineCap = 'round';
      lineCanvasContext.shadowBlur = 30;
      lineCanvasContext.shadowColor = '#000';
     
      for (var i = 1; i < points.length; i++) {
        var point = points[i];
        var previousPoint = points[i - 1];
    
        // Change line width based on speed
        var distance = getDistanceBetween(point, previousPoint);
        var speed = Math.max(0, Math.min(maximumSpeed, distance));
        var percentageLineWidth = (maximumSpeed - speed) / maximumSpeed;
        lineCanvasContext.lineWidth = minimumLineWidth + percentageLineWidth * lineWidthRange;
    
        // Fade points as they age
        var age = Date.now() - point.time;
        var opacity = (pointLifetime - age) / pointLifetime;
        lineCanvasContext.strokeStyle = 'rgba(0, 0, 0, ' + opacity + ')';
      
        lineCanvasContext.beginPath();
        lineCanvasContext.moveTo(previousPoint.x, previousPoint.y);
        lineCanvasContext.lineTo(point.x, point.y);
        lineCanvasContext.stroke();
      }
    }
    
    /**
     * @param {{x: number, y: number}} a
     * @param {{x: number, y: number}} b
     * @return {number} The distance between points a and b
     */
    function getDistanceBetween(a, b) {
      return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
    }
    
    /**
     * Draws the original image, masked by the line drawn in drawLineToCanvas.
     */
    function drawImageCanvas() {
      // Emulate background-size: cover
      var width = imageCanvas.width;
      var height = imageCanvas.width / image.naturalWidth * image.naturalHeight;
     
      if (height < imageCanvas.height) {
        width = imageCanvas.height / image.naturalHeight * image.naturalWidth;
        height = imageCanvas.height;
      }
    
      imageCanvasContext.clearRect(0, 0, imageCanvas.width, imageCanvas.height);
      imageCanvasContext.globalCompositeOperation = 'source-over';
      imageCanvasContext.drawImage(image, 0, 0, width, height);
      imageCanvasContext.globalCompositeOperation = 'destination-in';
      imageCanvasContext.drawImage(lineCanvas, 0, 0);
    }
    img.pointer is referenced in this part, if you change the name of img.pointer in css, make sure you change it here too

    Here's a forked version. http://codepen.io/anon/pen/OmLBQN
     
  5. Levi

    Levi Moderator Staff Member

    cont:
    In JS script the following does:
    var pointLifetime = 100; - lower the number and it will make the trail shorter/smoother etc when dragging faster
    var minimumLineWidth = 0; - line thickness, small
    var maximumLineWidth = 5; - line thickness, large
    var maximumSpeed = 5000; - faster particle creation, smoother lines etc
    lineCanvasContext.shadowBlur = 10; - adds a small 'blur' to the edge, bigger number means bigger blur

    http://codepen.io/anon/pen/RVbemr
     
  6. Hippychick

    Hippychick Member

    Wow . . . I will need to give this some proper headroom and experiment. Only reason I haven't gone down coding route is because so many are way ahead of me so I just stick to what I'm good at – but on thinking about it, that's how I have gone about everything since getting my first Mac in early nineties! A combination of curiosity and determination . . .

    . . . but there is always the issue of cross platform – and when I used a lot of Flash and was only starting to produce web stuff, I would always need to get someone with different ages (Windows O/S) of PCs to check on – but with something like a cursor trail, if it doesn't work, it doesn't matter so much provided the image is still visible, rather than a blank screen for Flash movies.

    Thanks for help again.
     
  7. Hippychick

    Hippychick Member

    One more quick question . . . I’m using Dreamweaver and HTML code, and this one: http://codepen.io/anon/pen/RVbemr is almost exactly what I was thinking of (small with ‘comet’ tail), either in a colour (red is good) or white like a flash of light over splash page image: http://www.flying-colours.me.uk but not sure how to apply using javascript.

    All people will be doing is dragging cursor across to arrow to go to homepage, so it will be very fleeting, but never worked with javascript.

    I used one I downloaded and uploaded for my webpage previously, and included a script in HTML that pointed to it, but it may take me hours to figure out how to achieve such a simple thing . . . ?!
     
  8. Levi

    Levi Moderator Staff Member

    JS can be added inline as a javascript block in the html (like google adwords) or you can add it via a 'text' file like jquery etc:
    Copy paste javascript into a text file and save as pointer-script.js, then stick it in the folder (I use a script folder) then add the below onto your site html
    <script src="http://flying-colours.me.uk/scripts/pointer-script.js" type="text/javascript"></script>

    It 'should' work but I haven't tested it.

    To change the colour, just change the jpeg to another colour :)
     
  9. Hippychick

    Hippychick Member

    That's brilliant . . . I was reading you could simply save with extension .js, but seemed too simple!

    I will try later – I owe you one! (I am reluctant to ask for favours on here, but if you don't ask . . . )
     
  10. Levi

    Levi Moderator Staff Member

    Don't count on it working lol, I'm not exactly up to date on js and canvas either...
     
  11. Hippychick

    Hippychick Member

    I'm not . . . just grateful for assistance as I've been far too involved in showcasing my Photoshop work that I haven't had time for this and my mailers go out next week!

    So will just stick with what I have on there at the mo if it doesn't as no-one will know or care that I couldn't achieve what I preferred.
     

Share This Page