SVG 学习(二)--- 创建组合交互式应用

接着上一节的内容,本次学习主要介绍SVG组合式应用以及js交互式应用!

1、组合式应用

绘制两棵带有投影效果的树!

<svg width="400" height="600">
        <defs>
            <pattern id="grap" patternUnits="userSpaceOnUse" x="0" y="0" width="100" height="67" viewBox="0 0 102 76">
                <image x="0" y="0" width="102" height="76" xlink:href="http://pic27.nipic.com/20130324/9148618_153134223000_2.jpg"></image>
            </pattern>
            <linearGradient id="TrunkGrad">
                <stop offset="0%" stop-color="#663300"></stop>
                <stop offset="40%" stop-color="#996600"></stop>
                <stop offset="100%" stop-color="#552200"></stop>
            </linearGradient>
            <rect x="-5" y="-50" width="10" height="50" id="Trunk"></rect>
            <path d="M-25,-50L-10,-80L-20,-80L-5,-110L-15,-110L0,-140L15,-110L5,-110L20,-80L10,-80L25,-50Z" fill="#f00" id="can">
            </path>
            <linearGradient id="shadow" x=0 y=0 x2=0 y2=100%>
                <stop offset="0%" stop-color="#000" stop-opacity=".5"></stop>
                <stop offset="20%" stop-color="#996600" stop-opacity="0"></stop>
            </linearGradient>
            <g id="tree">
                <use xlink:href="#Trunk" fill="url(#TrunkGrad)"/>
                <use xlink:href="#Trunk" fill="url(#shadow)"/>
                <use xlink:href="#can" fill="none" stroke="#663300" stroke-linejoin="round" stroke-width="4px" />
                <use xlink:href="#can" fill="#339900" stroke="none"/>
            </g>
            <g id="treeShadow">
                <use xlink:href="#Trunk" fill="#000"/>
                <use xlink:href="#can" fill="#000" stroke="none"/>
            </g>
        </defs>
        <text y=60 x=200 font-family="Arial" font-size="60px" fill="#996600" text-anchor="middle">tree</text>
        <text y=90 x=200 font-family="Arial" font-size="20px" fill="#996600" text-anchor="middle" id="treeCounter"></text>
        <text y=550 x=20 font-family="Arial" font-size="20px" fill="#996600" text-anchor="left">
            <tspan>点击一颗树或树的影子</tspan>
            <tspan>并移除掉它。。。</tspan>
        </text>
        <g transform="translate(-10,350)" stroke-width="20" stroke="url(#grap)" stroke-linejoin="round">
            <path d="M0,0Q170,-50 260,-190Q310,-250 410,-250" fill="none">
            </path>
        </g>
        <!--skewX() x轴方向向右扭曲25像素-->
        <use xlink:href="#treeShadow" transform="translate(130,250) scale(1,.6) skewX(-25)" opacity="0.4" />
        <use xlink:href="#tree" transform="translate(130,250)" />
        <use xlink:href="#treeShadow" transform="translate(260,500) scale(2,1.2) skewX(-25)" opacity="0.4" />
        <use xlink:href="#tree" transform="translate(260,500) scale(2)" />
    </svg>

说明:

scale(1,.6) :缩放 x轴缩放1倍,y轴缩放0.6倍skewX(-25) :扭曲 x轴水平方向扭曲-25像素
 <text y=550 x=20 font-family="Arial" font-size="20px" fill="#996600" text-anchor="left">
            <tspan>点击一颗树或树的影子</tspan>
            <tspan>并移除掉它。。。</tspan>
        </text>

这里的tspan 类似于我们在页面中添加span标签,用于分割汉字

 <linearGradient id="shadow" x=0 y=0 x2=0 y2=100%>
                <stop offset="0%" stop-color="#000" stop-opacity=".5"></stop>
                <stop offset="20%" stop-color="#996600" stop-opacity="0"></stop>
            </linearGradient>
stop-opacity=".5" :渐变的透明度设置上诉代码运行结果如图

2、SVG交互式应用

我们希望自己可以点击按钮的时候生成一颗随机的树,位置控制在svg画板中,而且点击生成的树还可以移除掉它!

新树的尺寸控制在50% - 150% 之间进行随机缩放!

首先我们创建一个添加树的函数:

/*
        document.createElementNS() 创建带有命名空间的的<use>元素
        setAttributeNS() 方法创建或改变具有命名空间的属性。
        语法:
        elementNode.setAttributeNS(name,value)
    */
    document.getElementById(‘btn‘).onclick = function(){
        var x = Math.floor(Math.random()*400);//随机数x
        var y = Math.floor(Math.random()*600);//随机数y
        var scale = Math.random()+0.5;//生成随机缩放的比例
        var translate = ‘translate(‘+x+‘,‘+y+‘)‘;
        var tree = document.createElementNS(‘http://www.w3.org/2000/svg‘,‘use‘);
        var treeSd = document.createElementNS(‘http://www.w3.org/2000/svg‘,‘use‘);
        treeSd.setAttributeNS(‘http://www.w3.org/1999/xlink‘,‘xlink:href‘,‘#treeShadow‘);
        treeSd.setAttribute(‘transform‘,translate + ‘ scale(‘+ scale +‘,‘+ scale*0.6 +‘) skewX(-25)‘);
        treeSd.setAttribute(‘opacity‘,0.4);
        document.querySelector(‘svg‘).appendChild(treeSd);//添加到svg中
        tree.setAttributeNS(‘http://www.w3.org/1999/xlink‘,‘xlink:href‘,‘#tree‘);
        tree.setAttribute(‘transform‘,translate + ‘ scale(‘+ scale +‘)‘);
        document.querySelector(‘svg‘).appendChild(tree);//添加到svg中
        updateTrees();
    }

接着我们创建一个更新树的数量的函数,以及给每棵树添加自己的移除的方法

function updateTrees(){
        //查找所有的use元素
        var list = document.querySelectorAll(‘use‘);
        var treeCount = 0;
        for(var i=0;i<list.length;i++){
            //如果是树或者树的阴影
            if(list[i].getAttribute(‘xlink:href‘) == ‘#tree‘ || list[i].getAttribute(‘xlink:href‘) == ‘#treeShadow‘){
                treeCount++;
                //点击树或者阴影移除自己
                list[i].onclick = removeTree;
            }
        }
        //更新数量
        var counter = document.getElementById(‘treeCon‘);
        counter.innerHTML = parseInt(treeCount/2) + ‘trees in the svg‘;
    }

创建树的移除的函数

function removeTree(e){
        //e.target 被点击的目标对象
        var e = e.target;
        /*
            e.correspondingUserElement 意思大概是当使用的元素有嵌套的时候使用最外层的元素作为目标对象
            具体说明可参考地址:
            https://msdn.microsoft.com/en-us/library/ff971929(v=vs.85).aspx
        */
        if(e.correspondingUserElement){
            e =  e.correspondingUserElement;
        }
        e.parentNode.removeChild(e);
        updateTrees();
    }

完整的例子如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>svg 交互测试</title>
</head>
<style>
    svg{border:1px solid #000;}
    use:nth-of-type(even):hover{
        opacity:0.9;
        cursor:crosshair;/*十字线光标*/
    }
    use:nth-of-type(odd):hover{
        opacity:0.5;
        cursor:crosshair;/*十字线光标*/
    }
</style>
<body>
    <div >
        <button type="button" id="btn">点击按钮生成树</button>
    </div>
    <svg width="400" height="600">
        <defs>
            <pattern id="grap" patternUnits="userSpaceOnUse" x="0" y="0" width="100" height="67" viewBox="0 0 102 76">
                <image x="0" y="0" width="102" height="76" xlink:href="http://pic27.nipic.com/20130324/9148618_153134223000_2.jpg"></image>
            </pattern>
            <linearGradient id="TrunkGrad">
                <stop offset="0%" stop-color="#663300"></stop>
                <stop offset="40%" stop-color="#996600"></stop>
                <stop offset="100%" stop-color="#552200"></stop>
            </linearGradient>
            <rect x="-5" y="-50" width="10" height="50" id="Trunk"></rect>
            <path d="M-25,-50L-10,-80L-20,-80L-5,-110L-15,-110L0,-140L15,-110L5,-110L20,-80L10,-80L25,-50Z" fill="#f00" id="can">
            </path>
            <linearGradient id="shadow" x=0 y=0 x2=0 y2=100%>
                <stop offset="0%" stop-color="#000" stop-opacity=".5"></stop>
                <stop offset="20%" stop-color="#996600" stop-opacity="0"></stop>
            </linearGradient>
            <g id="tree">
                <use xlink:href="#Trunk" fill="url(#TrunkGrad)"/>
                <use xlink:href="#Trunk" fill="url(#shadow)"/>
                <use xlink:href="#can" fill="none" stroke="#663300" stroke-linejoin="round" stroke-width="4px" />
                <use xlink:href="#can" fill="#339900" stroke="none"/>
            </g>
            <g id="treeShadow">
                <use xlink:href="#Trunk" fill="#000"/>
                <use xlink:href="#can" fill="#000" stroke="none"/>
            </g>
        </defs>
        <text y=60 x=200 font-family="Arial" font-size="60px" fill="#996600" text-anchor="middle">tree</text>
        <text y=90 x=200 font-family="Arial" font-size="20px" fill="#996600" text-anchor="middle" id="treeCounter"></text>
        <text y=550 x=20 font-family="Arial" font-size="20px" fill="#996600" text-anchor="left">
            <tspan>点击一颗树或树的影子</tspan>
            <tspan>并移除掉它。。。</tspan>
        </text>
        <g transform="translate(-10,350)" stroke-width="20" stroke="url(#grap)" stroke-linejoin="round">
            <path d="M0,0Q170,-50 260,-190Q310,-250 410,-250" fill="none">
            </path>
        </g>
        <!--skewX() x轴方向向右扭曲25像素-->
        <use xlink:href="#treeShadow" transform="translate(130,250) scale(1,.6) skewX(-25)" opacity="0.4" />
        <use xlink:href="#tree" transform="translate(130,250)" />
        <use xlink:href="#treeShadow" transform="translate(260,500) scale(2,1.2) skewX(-25)" opacity="0.4" />
        <use xlink:href="#tree" transform="translate(260,500) scale(2)" />
    </svg>
    <p id="treeCon"></p>
</body>
<script>
    /*
        document.createElementNS() 创建带有命名空间的的<use>元素
        setAttributeNS() 方法创建或改变具有命名空间的属性。
        语法:
        elementNode.setAttributeNS(name,value)
    */
    document.getElementById(‘btn‘).onclick = function(){
        var x = Math.floor(Math.random()*400);//随机数x
        var y = Math.floor(Math.random()*600);//随机数y
        var scale = Math.random()+0.5;//生成随机缩放的比例
        var translate = ‘translate(‘+x+‘,‘+y+‘)‘;
        var tree = document.createElementNS(‘http://www.w3.org/2000/svg‘,‘use‘);
        var treeSd = document.createElementNS(‘http://www.w3.org/2000/svg‘,‘use‘);
        treeSd.setAttributeNS(‘http://www.w3.org/1999/xlink‘,‘xlink:href‘,‘#treeShadow‘);
        treeSd.setAttribute(‘transform‘,translate + ‘ scale(‘+ scale +‘,‘+ scale*0.6 +‘) skewX(-25)‘);
        treeSd.setAttribute(‘opacity‘,0.4);
        document.querySelector(‘svg‘).appendChild(treeSd);//添加到svg中
        tree.setAttributeNS(‘http://www.w3.org/1999/xlink‘,‘xlink:href‘,‘#tree‘);
        tree.setAttribute(‘transform‘,translate + ‘ scale(‘+ scale +‘)‘);
        document.querySelector(‘svg‘).appendChild(tree);//添加到svg中
        updateTrees();
    }
    function updateTrees(){
        //查找所有的use元素
        var list = document.querySelectorAll(‘use‘);
        var treeCount = 0;
        for(var i=0;i<list.length;i++){
            //如果是树或者树的阴影
            if(list[i].getAttribute(‘xlink:href‘) == ‘#tree‘ || list[i].getAttribute(‘xlink:href‘) == ‘#treeShadow‘){
                treeCount++;
                //点击树或者阴影移除自己
                list[i].onclick = removeTree;
            }
        }
        //更新数量
        var counter = document.getElementById(‘treeCon‘);
        counter.innerHTML = parseInt(treeCount/2) + ‘trees in the svg‘;
    }
    function removeTree(e){
        //e.target 被点击的目标对象
        var e = e.target;
        /*
            e.correspondingUserElement 意思大概是当使用的元素有嵌套的时候使用最外层的元素作为目标对象
            具体说明可参考地址:
            https://msdn.microsoft.com/en-us/library/ff971929(v=vs.85).aspx
        */
        if(e.correspondingUserElement){
            e =  e.correspondingUserElement;
        }
        e.parentNode.removeChild(e);
        updateTrees();
    }
</script>

说明:

use:nth-of-type(even):hover{
        opacity:0.9;
        cursor:crosshair;/*十字线光标*/
    }
    use:nth-of-type(odd):hover{
        opacity:0.5;
        cursor:crosshair;/*十字线光标*/
    }

这里是css3 新的选择方法

use:nth-of-type(even):选择奇数的use元素
use:nth-of-type(odd):选择偶数的use元素

当点击按钮的时候可以生成同样带有的投影效果的树,位置不一,大小不一!



鼠标移动到树或者影子的上面的时候出现十字光标,点击可以移除树或者影子

例子中我们看到,svg是可以通过dom操作元素,并添加事件处理函数的!这点比canvas在事件处理方面更灵活!

SVG的介绍大概先介绍这些,具体详细的API可以参考下面的地址:

https://developer.mozilla.org/zh-CN/docs/Web/SVG
时间: 2024-08-15 16:08:43

SVG 学习(二)--- 创建组合交互式应用的相关文章

sublime text 2学习(二):创建可复用的代码片段

对于前端工程师来讲,写一个html页面的基本结构是体力活,每次去拷贝一个也麻烦,sublime text 2 提供了一个很好的复用代码片段.下面介绍一下创建一个html5的代码片段的过程. 在菜单上点击Tools -> New Snippet,会新建一个xml文件页签: <snippet> <content><![CDATA[ Hello, ${1:this} is a ${2:snippet}. ]]></content> <!-- Optio

SVG 学习&lt;二&gt;进阶

SVG分组--g标签 g标签在svg标签内使用,功能用来对图形,文字,线段进行分组. HTML代码 <svg class="svg"> <g class="g_1"> <rect x="20" y="20"/><rect x="240" y="20" /> </g> <g class="g_2">

micronaut 学习 二 创建一个简单的服务

micronaut 提供的cli 很方便,我们可以快速创建具有所需特性的应用,以下是一个简单的web server app 创建命令 mn create-app hello-world 效果 mn create-app hello-world | Generating Java project... | Application created at /Users/dalong/mylearning/micronaut-project/hello-world 启动服务 ./gradlew run

SVG 学习&lt;五&gt; SVG动画

先上个动画图 说道SVG动画不得不提到两个属性:stroke-dasharray(这个前面有提到,做虚线的)stroke-dashoffset (这个是关键). 先说说stroke-dasharray 之前提过 可以把线条做成虚线状,值可以为一个数值 也可以是一个数组.详见:SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 最后一段.在动画里 stroke-dasharray 用来绘制路径或者虚线环绕效果. stroke-dashoffset : 官方解释 svg的

SVG学习笔录(一)

SVG可缩放矢量图形(Scalable Vector Graphics)这项技术,现在越来越让大家熟知,在h5的移动端应用使用也越来越广泛了, 下面让我分享给大家svg学习的经验. HTML体系中,最常用的绘制矢量图的技术是SVG和HTML5新增加的canvas元素.这两种技术都支持绘制矢量图和光栅图. 一.什么是svg? Graphics)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式.SVG是W3C在2000年8月制定的一种新的二维矢量图形格式,也是规范中的网络矢量图形标

puppet基础学习(二)

puppet基础学习(二) 六.ResourceOrdering(资源定序) 使用变化参数before , require , notify , subscribe catalog是对一个给定的系统的所有资源及关系的编译,在编译catalog时,除非我们指定资源的执行顺序,不然puppet是以其自己的顺序管理,大多数时候puppet指定适当的方式,例如puppet管理用户gigabyte应该存在和文件夹/home/gigabyte/bin应该存在并属于用户gigabyte时,puppet会自动指

[Python 学习] 二、在Linux平台上使用Python

这一节,主要介绍在Linux平台上如何使用Python 1. Python安装. 现在大部分的发行版本都是自带Python的,所以可以不用安装.如果要安装的话,可以使用对应的系统安装指令. Fedora系统:先以root登入,运行 yum install python Ubuntu系统:在root组的用户, 运行 sudo apt-get install python 2. 使用的Python的脚本 Linux是一个以文件为单位的系统,那么我们使用的Python是哪一个文件呢? 这个可以通过指令

javascript设计模式学习之十——组合模式

一.组合模式定义及使用场景 组合模式将对象组合成树形结构,用以表示“部分—整体”的层次结构,除了用来表示树形结构之外,组合模式还可以利用对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性. 实现组合模式的关键: 在java等静态语言中,需要单个对象和组合对象都实现同样的抽象接口,这可以通过抽象类或者接口来实现. 在javascript中,对象的多态性是与生俱来的,没有编译器去检查对象的类型,因此实现组合模式的要点是保证组合兑现个单个对象用友同样的方法,这通常需要使用“鸭子类型”的思想

OpenCV for Python 学习 (二 事件与回调函数)

今天主要看了OpenCV中的事件以及回调函数,这么说可能不准确,主要是下面这两个函数(OpenCV中还有很多这些函数,可以在 http://docs.opencv.org/trunk/modules/highgui/doc/user_interface.html 找到,就不一一列举了),然后自己做了一个简单的绘图程序 函数如下: cv2.setMouseCallback(windowName, onMouse[, param]) cv2.createTrackbar(trackbarName,