# sleepy dog

This example is based lightly on Brad Frarrel's Dog SVG Animation (opens new window). In this case we have adapted his creation using gySVG animation and change some graphycs elements.

Please, touch the dog with the mouse to wake him up.

edit in codepen.io (opens new window)

Now we will explain step by step how to create this animated SVG.

# Import gySVG

The first step, if we haven't already done so, is to import the gySVG library. In our case, we've chosen to include the code within a script type=module and we'll use the import expression.

see: load gySVG

# Create the SVG

To create the graph we are going to use gySVG() and we are going to configure the viewBox and define a width.

see: SVG Element, .viewBox, .attachTo

# SVG background color

The style used need a grey background:

# Internal style

For add style to several elements, we define a <style></style> into the SVG:

# The dog

We put several elements to define the dog image.

# Sleep state

We need severals items for the dream state, including the eyelids, hiding the tongue, etc.

# Sleep animation

We add a soft eyelids animation for sleep state with an animate element:

# Weak up

We capture the click event with .addEventListener() and open the eyelips, remove its animations and show the tongle with an animation created with animatedTransfor. We add a pointer cursor style.

# Eye movement

Finally, we add the eye movement to the click position. In this case we will use the .animateTo() method.

# The complete code

If we put all these steps together this is the example's code:

import gySVG from 'https://cdn.graphery.online/0.1.5/svg/module/index.js';

const svg = gySVG ().viewBox (0, 0, 478, 370).width ('50%')
  .style.backgroundColor ('#c0c0c0')
  .style.cursor ('pointer');

svg.add ('style').content (`
  .skin      { fill : #F4E9D7; }
  .brown     { fill : #635244; }
  .pink      { fill : #F4CEEC; }
  .white     { fill : #FFFFFF; }
  .darkbrown { fill : #2A1E13; }
  .hidden    { display: none; }
`);

const defs = svg.add ('defs');
defs.add ('clipPath').id ('eye_left').add ('circle').cx (142).cy (160).r (38);
defs.add ('clipPath').id ('eye_right').add ('circle').cx (325).cy (160).r (38);

svg.add ('circle').classList.add ('skin').cx (237).cy (185).r (185);
svg.add ('circle').classList.add ('brown').cx (142).cy (155).r (60);
svg.add ('circle').classList.add ('white').cx (142).cy (162).r (36);
svg.add ('circle').classList.add ('brown').cx (325).cy (155).r (60);
svg.add ('circle').classList.add ('white').cx (325).cy (162).r (36);
svg.add ('path').classList.add ('brown')
  .d (
    'M340,255c5,24-1,42-19,53c-18,11-48,15-82,14c-34-1-64-4-82-14 c-18-10-24-28-19-52c13-49,58-86,101-85C281,168,327,206,340,255z');
svg.add ('path').classList.add ('darkbrown')
  .d (
    'M211,185c-1-6,0-11,5-15c5-3,12-4,21-4c9,0,16,1,21,4c4,3,6,8,5,15 c-3,13-15,24-26,24C226,210,214,199,211,185z');
svg.add ('path').classList.add ('brown')
  .d ('M131,54c-11,29-36-12-51,20c-12,33-32,44-62,49c-54,0,41-86,60-100 C99,9,132,23,131,54z');
svg.add ('path').classList.add ('brown')
  .d ('M397,23c19,13,114,100,60,100c-29-4-49-15-62-49c-14-33-39,8-51-20 C344,23,377,9,397,23z');

const tongue = svg.add ('path').classList.add ('pink', 'hidden')
  .d ('M238,266h0c12,0,22-12,22-26v0c-9-5-16-8-21-8c-5,0-13,3-22,9 v-0C216,253,225,265,238,266z');
tongue.add ('animateTransform').attributeName ('transform').type ('translate').values ('0,0; 0,-5; 0,0;')
  .dur ('0.6s').repeatCount ('indefinite');

const gLeft          = svg.add ('g').clip_path ('url(#eye_left)');
const eyeLeft        = gLeft.add ('circle').cx (143).cy (162).r (20);
const lidLeft        = gLeft.add ('rect').x (50).y (92).classList.add ('darkbrown').width (190).height (80);
const lidLeftAnimate = lidLeft.add ('animate').attributeName ('height').values ('70;80;80;70')
  .dur ('6s').repeatCount ('indefinite');

const gRight          = svg.add ('g').clip_path ('url(#eye_right)');
const eyeRight        = gRight.add ('circle').cx (325).cy (162).r (20);
const lidRight        = gRight.add ('rect').x (230).y (92).classList.add ('darkbrown').width (190).height (80);
const lidRightAnimate = lidRight.add ('animate').attributeName ('height').values ('70;80;80;70')
  .dur ('6s').repeatCount ('indefinite');

svg.attachTo ('#example');

function cursorPoint (evt) {
  const pt = svg.createSVGPoint ();
  pt.x     = evt.clientX;
  pt.y     = evt.clientY;
  return pt.matrixTransform (svg.getScreenCTM ().inverse ());
}

let timeout = null;
svg.addEventListener ('click', (evt) => {
  clearTimeout (timeout);
  const loc = cursorPoint (evt);
  eyeLeft.animateTo ({
    cx : (143 + (10 * (loc.x <= 143 ? -(1 - (loc.x / 143)) : (loc.x - 143) / 355))),
    cy : (162 + (10 * (loc.y <= 162 ? -(1 - (loc.y / 162)) : (loc.y - 162) / 228)))
  });
  eyeRight.animateTo ({
    cx : (325 + (10 * (loc.x <= 325 ? -(1 - (loc.x / 325)) : (loc.x - 325) / 173))),
    cy : (162 + (10 * (loc.y <= 162 ? -(1 - (loc.y / 162)) : (loc.y - 162) / 228)))
  });
  lidLeftAnimate.remove ();
  lidRightAnimate.remove ();
  lidLeft.height (0);
  lidRight.height (0);
  tongue.classList.remove ('hidden');
  timeout = setTimeout (() => {
    eyeLeft.animateTo ({cx : 143, cy : 162}, 600);
    eyeRight.animateTo ({cx : 325, cy : 162}, 600);
    lidLeftAnimate.attachTo (lidLeft);
    lidRightAnimate.attachTo (lidRight);
    tongue.classList.add ('hidden');
  }, 4000);
});