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
SVG 学习(二)--- 创建组合交互式应用的更多相关文章
- SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- pipelinewise 学习二 创建一个简单的pipeline
pipelinewise 提供了方便的创建简单pipeline的命令,可以简化pipeline 的创建,同时也可以帮我们学习 生成demo pipeline pipelinewise init --n ...
- sublime text 2学习(二):创建可复用的代码片段
对于前端工程师来讲,写一个html页面的基本结构是体力活,每次去拷贝一个也麻烦,sublime text 2 提供了一个很好的复用代码片段.下面介绍一下创建一个html5的代码片段的过程. 在菜单上点 ...
- micronaut 学习 二 创建一个简单的服务
micronaut 提供的cli 很方便,我们可以快速创建具有所需特性的应用,以下是一个简单的web server app 创建命令 mn create-app hello-world 效果 mn c ...
- SVG 学习<六> SVG的transform
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- SVG 学习<四> 基础API
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- SVG 学习<八> SVG的路径——path(2)贝塞尔曲线命令、光滑贝塞尔曲线命令
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- SVG 学习<七> SVG的路径——path(1)直线命令、弧线命令
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
- SVG 学习<五> SVG动画
目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...
随机推荐
- UVa 10190 - Divide, But Not Quite Conquer!
称号:给你第一个任期的等比数列和倒数公比,最后一个条目假定1这一系列的输出,否则输出Boring!. 分析:数学.递减的.所以公比的倒数一定要大于1.即m > 1. 然后在附加一个条件n &g ...
- JavaScript权威指南科13章 webj浏览器avascript
13.1 clientjavascript window对象是所有clientjavascript特点和api主要的接入点.它代表了一个浏览器窗口,通过window对象引用它. window 方法 a ...
- 采用shell脚本统计代码的行数
刚毕业那会儿有一次去台湾公司面试,我问多行代码怎么写.我从来没有想过这个问题,粗略计算,.惊叹:大概几十万行不行. 最近整理资料,看着eclipse左边全面上市,我觉得这个东西.代码共同拥有的行倒底总 ...
- CIC and Fir 滤波器的级联
在FDATool中 CIC 和 Fir 级联滤波器的设计 1 设计CIC滤波器的幅频特性曲线如下 2.设计FIR 滤波器的幅频特性曲线如下 3.总的特性曲线如下 4.把通带部分放大后的图,比较平坦
- The JSON request was too large to be deserialized
The JSON request was too large to be deserialized 这个问题出现的场景并不是很多,当你向服务端异步(ajax)post数据非常大的情况下(比如做权限管理 ...
- win9x_win2k下对物理磁盘的操作
void CReadSectorDlg::OnReadButton() { UpdateData (TRUE) ; CFile m_Sector_file ; char * buffer ; if ( ...
- Loadrunner11.00破解方法
1.下载 从http://www.jb51.net/softs/71240.html上面下载到loadrunner 11.0 2.安装loadrunner 11.0 下载之后,我是直接解压到硬盘,再安 ...
- Set <STL>
set是维护集合的容器 #include <cstdio> #include <set> using namespace std; int main() { //声明 set& ...
- Oracle内存管理(五)
[深度分析--eygle]学习笔记 1.4. 2其他内存组件 Large Pool-大池是SGA的一个可选组件,通经常使用于共享server模式(MTS). 并行计算或 RMAN的备份恢复等操作. J ...
- BZOJ 1004 HNOI2008 Cards Burnside引理
标题效果:特定n张卡m换人,编号寻求等价类 数据保证这m换人加上置换群置换后本身构成 BZOJ坑爹0.0 条件不那么重要出来尼玛怎么做 Burnside引理--昨晚为了做这题硬啃了一晚上白书0.0 都 ...