接着上一节的内容,本次学习主要介绍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

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

  1. SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  2. pipelinewise 学习二 创建一个简单的pipeline

    pipelinewise 提供了方便的创建简单pipeline的命令,可以简化pipeline 的创建,同时也可以帮我们学习 生成demo pipeline pipelinewise init --n ...

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

    对于前端工程师来讲,写一个html页面的基本结构是体力活,每次去拷贝一个也麻烦,sublime text 2 提供了一个很好的复用代码片段.下面介绍一下创建一个html5的代码片段的过程. 在菜单上点 ...

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

    micronaut 提供的cli 很方便,我们可以快速创建具有所需特性的应用,以下是一个简单的web server app 创建命令 mn create-app hello-world 效果 mn c ...

  5. SVG 学习<六> SVG的transform

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  6. SVG 学习<四> 基础API

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  7. SVG 学习<八> SVG的路径——path(2)贝塞尔曲线命令、光滑贝塞尔曲线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  8. SVG 学习<七> SVG的路径——path(1)直线命令、弧线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  9. SVG 学习<五> SVG动画

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

随机推荐

  1. 致网友Wonderfei的一封信(怎样选择自己主动化框架的几点拙见)

    注:本来这封信要发给Wonerfei网友的,可是由于每次仅仅能发200字,所以干脆贴到博客上,叫Wonderfei同学到这上面来看,也算是我自己的一个暂时总结吧.同一时候也希望大家给予Wonderfe ...

  2. opencv-阈值处理

    从原理:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/threshold/threshold.html 目标: ...

  3. NSIS:安装、卸载时检查程序是否正在运行

    原文 NSIS:安装.卸载时检查程序是否正在运行 如果我们要安装或升级的程序正在运行,文件肯定会替换不成功,以下代码可以提示用户结束正在运行的程序. 需要使用插件FindProcDLL.dll,下载路 ...

  4. android怎么在launcher改动内置apk的icon

    找到launcher下的IconCache中加入变量用来存储要改动apk的包名 及要改动成的icon private String[] className = {"com.google.an ...

  5. iOS6和iOS7适应代码(6) —— NSLocalizedString

    我们的应用程序都需要国际化,字符串的重要组成部分.一般来说.我们是通过一个string资源文件来达到这个目的,我们需要支持多国语言,有多少次把这个文档本地化.需要使用的代码NSLocalizedStr ...

  6. zoj2977Strange Billboard (国家压缩+罗列)

    Strange Billboard Time Limit: 2 Seconds Memory Limit: 65536 KB The marketing and public-relations de ...

  7. 持续集成Jenkins + robot framework + git

    Jenkins + robot framework + git持续集成 一.Jenkins安装插件 进入系统管理—插件管理—可选插件下安装以下插件Git Client Plugin.GIT plugi ...

  8. 离github在导入dubbo工程

    dubbo移动到github目前已经有一些时间,我们可能根本不习惯使用github.因此,我们仍然使用以前的版本号. 由于某些原因.阿里下载前关闭.在这里给大家提供一个私有地址: 链接:http:// ...

  9. GDI+学问------ 绘制可变角度的色彩渐变效果

    GDI+ 它是GDI(Windows 图形设备接口提供的早期版本)也许是版本号,它是Microsoft Windows XP作系统即兴许版本号的图形显示技术. 它已经集成到了.Net开发环境中.所以无 ...

  10. 类别sort使用排序

    2129: 船上的第二次测试第三个问题 Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 243  Solved: 74 [Submit][id=2129 ...