マウス・イベント
マウス・イベントのレッスンに戻る
<script language="JavaScript1.2">
<!--
	/*
	* Other parts required but not shown here:
	*
	* In the SVG file, the g tags for the buttons each contain the following
	* attributes:
	*
	*    onmouseover="mouse_over_b('one')" onmouseout="mouse_out_b('one')"
	*    onclick="mouse_click_b('one')"
	*
	* Where 'one' is replaced by 'two', 'three', 'four', 'five', and 'six' as
	* appropriate.
	*/
	// Variables for animation of second example.
	var anim_sequence = '';	// name of related SVG element to indicate which
													// sequence is being shown, '' to indicate no
													// animation.
	var anim_timer;					// Handle returned by vall to setInterval().
	var nframes = 30; 			// Number of frames in animation
	var current_frame = -1; // Current frame, first frame is numbered 0.
	var inside_button;			// If true, mouse is still inside button during
													// animation, if false, mouse has moved out of the
													// button.
	/*
	* This function is called to suppress javascript error messages when it is
	* known that the errors are not real problems.
	*/
	function suppress_errors ()
	{
		return true;
	}
	/*
	* Verify that the indicated SVG element exists.
	*/
	function does_element_exist (svg_name, element_name)
	{
		// First, redirect the error handler so that if the SVG plug-in has not
		// yet loaded or is not present, it doesn't cause the browser to
		// issue a JavaScript error.
		var old_error = window.onerror;
		window.onerror = suppress_errors;
		// Now attempt to get the SVG object.
		var svgobj = document.embeds[svg_name].getSVGDocument().getElementById(element_name);
		// Reset the error hanlder to the browser's default handler.
		window.onerror = old_error;
		// Return appropriate value.
		if (svgobj == null)
			return false;
		else
			return true;
	}
	/*
	* This function handles the mouseover events for the second example.
	* On each call, it makes the related element in the other SVG image
	* visible.
	* We rely on the mouseout handler to make the related SVG element
	* invisible again at the proper time.
	* The input parameter is expected to contain the name of the related
	* SVG element that will be modified in the other SVG image.
	*/
	function mouse_over_b (c_name)
	{
		var svgdoc = document.inter1_03.getSVGDocument();
		// See if the triggering element is the same as the one that started
		// the current animation. In this case we don't do anything except set
		// a flag to indicate that the related SVG element should become
		// visible again at the end of the animation.
		if (anim_sequence == c_name)
		{
			inside_button = true;
			return true;
		}
		// Now change the related SVG element's visibility.
		// Make sure SVG element is available.
		if (!does_element_exist ('inter1_03', c_name))
			return true;
		var svgobj = svgdoc.getElementById(c_name);
		if (svgobj != null)
		{
			var svgstyle = svgobj.getStyle();
			svgstyle.setProperty ('visibility', 'visible');
		}
		// Propagate the event to other handlers.
		return true;
	}
	/*
	* This function handles the mouseout events for the second example.
	* On each call, it makes the related element in the other SVG image
	* invisible again.
	* The input parameter is expected to contain the name of the related
	* SVG element that will be modified in the other SVG image.
	* This is very similar to the mouse_over_b function.
	*/
	function mouse_out_b (c_name)
	{
		var svgdoc = document.inter1_03.getSVGDocument();
		// See if the triggering element is the same as the one that started
		// the current animation. In this case we don't do anything except set
		// a flag to indicate that the related SVG element should NOT become
		// visible again at the end of the animation.
		if (anim_sequence == c_name)
		{
			inside_button = false;
			return true;
		}
		// Now change the related SVG element's visibility.
		// Make sure SVG element is available.
		if (!does_element_exist ('inter1_03', c_name))
			return true;
		var svgobj = svgdoc.getElementById(c_name);
		if (svgobj != null)
		{
			var svgstyle = svgobj.getStyle();
			svgstyle.setProperty ('visibility', 'hidden');
		}
		// Propagate the event to other handlers.
		return true;
	}
	/*
	* This function handles the onClick events for the second example.
	* On each call, it starts animating the base starburst element in the
	* other SVG image for a short period of time.
	* The input parameter is expected to contain the name of the related
	* SVG element that will be modified in the other SVG image.
	*/
	function mouse_click_b (c_name)
	{
		var svgobj;
		var svgstyle;
		var svgdoc = document.inter1_03.getSVGDocument();
		// Initially, we set the flag to indicate that the mouse is inside the
		// button element. If the user moves the mouse out of the button, the
		// flag is set to false.
		// At the end of the animation, depending on this flag's setting the
		// related SVG element may be turned visible again.
		inside_button = true;
		// See if there is an animation already in progress (either for the
		// same button or a different one). In such a case, we stop that
		// animation by calling clearInterval so that it doesn't interfere
		// with the new animation we're about to start.
		if (anim_sequence)
		{
			clearInterval (anim_timer);
			anim_sequence = '';
			svgobj = svgdoc.getElementById('gradient_star');
			if (svgobj != null)
			{
				svgstyle = svgobj.getStyle();
				svgstyle.setProperty('fill', 'none');
				svgstyle.setProperty('stroke', '#6699FF');
			}
		}
		// Make the related SVG element invisible since it was made visible by
		// the mouseover event.
		// Make sure SVG element is available.
		if (!does_element_exist ('inter1_03', c_name))
			return false;
		svgobj = svgdoc.getElementById(c_name);
		if (svgobj != null)
		{
			svgstyle = svgobj.getStyle();
			svgstyle.setProperty ('visibility', 'hidden');
		}
		// Make sure SVG element gradient_star is available.
		if (!does_element_exist ('inter1_03', 'gradient_star'))
			return false;
		// Change the appearance of the underlying starburst element to start
		// the animation.
		svgobj = svgdoc.getElementById('gradient_star');
		if (svgobj != null)
		{
			svgstyle = svgobj.getStyle();
			svgstyle.setProperty('fill', '#99CCFF');
			svgstyle.setProperty('stroke', '#0000FF');
			svgstyle.setProperty('stroke-width', '1');
		}
		// Remember the related SVG element so it can be used during the
		// handling of subsequent mouseover and mouseout events while the
		// animation is still in progress.
		anim_sequence = c_name;
		// Reset the frame number.
		current_frame = -1;
		// Start the animation by calling setInterval to repeatedly call
		// next_frame every 100 msec. We remember the timer object so it can
		// be cancelled either at the end of the sequence or if a new animation
		// is started.
		anim_timer = setInterval ('next_frame()', 100);
		// Stop the event from being propagated to other handlers.
		return false;
	}
	/*
	* This function implements the animation. At each invocation, the function
	* transforms the underlying starburst to make it gradually "morph" into
	* the same appearance as the SVG element related to the button that was
	* clicked on.
	* At the end of the animation, we cancel the timer and make the related
	* SVG element visible again if the mouse is still over the triggering
	* button.
	*/
	function next_frame ()
	{
		var svgdoc = document.inter1_03.getSVGDocument();
		// Make sure SVG element gradient_star is available.
		if (!does_element_exist ('inter1_03', 'gradient_star'))
		{
			clearInterval (anim_timer);
			return false;
		}
		// There is only one SVG element involved here so we get its style
		// object right-away.
		var svgobj = svgdoc.getElementById('gradient_star');
		var svgstyle = svgobj.getStyle();
		// Increment current frame number.
		current_frame++;
		// Stop when we go beyond the last frame.
		if (current_frame >= nframes)
		{
			clearInterval (anim_timer);
			// We reset the appearance of the underlying starburst and we remove
			// all transformations applied to it by using the transformation
			// matrix (1 0 0 1 0 0).
			svgstyle.setProperty('fill', 'none');
			svgstyle.setProperty('stroke', '#6699FF');
			svgstyle.setProperty('stroke-width', '0.25');
			svgobj.setAttribute('transform', 'matrix(1 0 0 1 0 0)');
			// Make the related SVG element visible again if needed. This is the
			// same as in the mouse_over_b function.
			if (inside_button)
			{
				var c_name = anim_sequence;
				// Make sure SVG element is available.
				if (!does_element_exist ('inter1_03', c_name))
					return false;
				svgobj = svgdoc.getElementById(c_name);
				svgstyle = svgobj.getStyle();
				svgstyle.setProperty ('visibility', 'visible');
			}
			// We're done. Reset the anim_sequence to indicate that there is
			// no ongoing animation and return.
			anim_sequence = '';
			return;
		}
		// Apply the transformation to the underlying starburst for this frame.
		// The transformation applied varies depending on which SVG button
		// was initially clicked on.
		switch (anim_sequence)
		{
			case 'one':
				// Gradually scale down the starburst to sx=0.5 sy=0.5
				var val = 1 - 0.5 * current_frame / (nframes-1);
				svgobj.setAttribute('transform', 'translate(-150 -100) scale('+val+') translate(150 100)');
				break;
			case 'two':
				// Gradually translate the starburst to tx=70
				var val = 70 * current_frame / (nframes-1);
				svgobj.setAttribute('transform', 'translate('+val+')');
				break;
			case 'three':
				// Gradually translate the starburst to ty=40
				var val = 40 * current_frame / (nframes-1);
				svgobj.setAttribute('transform', 'translate(0 '+val+')');
				break;
			case 'four':
				// Gradually rotate the starburst to -45 degrees
				var val = -45 * current_frame / (nframes-1);
				svgobj.setAttribute('transform', 'translate(-150 -100) rotate('+val+') translate(150 100)');
				break;
			case 'five':
				// Gradually rotate the starburst to +45 degrees
				var val = 45 * current_frame / (nframes-1);
				svgobj.setAttribute('transform', 'translate(-150 -100) rotate('+val+') translate(150 100)');
				break;
			case 'six':
				// Gradually skew y-axis of the starburst to 30 degrees
				var val = 30 * current_frame / (nframes-1);
				svgobj.setAttribute('transform', 'translate(0 -100) skewX('+val+') translate(0 100)');
				break;
		}
	}
// -->
</script>
マウス・イベントのレッスンに戻る