var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.reveal = false;
$scope.config = {
width: 100,
blurRadius: 6,
ratio: 10,
opacity: 0.6
};
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8"></script>
<script src="app.js"></script>
<script src="yt-progress.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class="container"
ng-class="{
reveal: reveal
}">
<div class="demo-wrap">
<div class="demo" ng-repeat="scale in [2, 4]">
<yt-progress config="config"
ng-attr-data-scale="{{scale}}"
ng-style="{transform: 'scale('+ scale +')'}"></yt-progress>
</div>
</div>
<div class="controls">
<div class="row">
<div class="col-sm-10">
<div class="form-group">
<label for="width">寬度</label>
<input type="range" id="width" ng-model="config.width" min="20" max="200">
</div>
</div>
<div class="col-sm-2">
<div class="number">{{config.width}}px</div>
</div>
</div>
<div class="row">
<div class="col-sm-10">
<div class="form-group">
<label for="ratio">頭/尾 比例</label>
<input type="range" id="ratio" ng-model="config.ratio" min="1" max="99">
</div>
</div>
<div class="col-sm-2">
<div class="number">{{config.ratio}}/{{100 - config.ratio}}</div>
</div>
</div>
<div class="row">
<div class="col-sm-10">
<div class="form-group">
<label for="blur-radius">模糊範圍</label>
<input type="range" id="blur-radius" ng-model="config.blurRadius" min="1" max="20">
</div>
</div>
<div class="col-sm-2">
<div class="number">{{config.blurRadius}}px</div>
</div>
</div>
<div class="row">
<div class="col-sm-10">
<div class="form-group">
<label for="opacity">透明度</label>
<input type="range" id="opacity" ng-model="config.opacity" min="0" max="1" step="0.01">
</div>
</div>
<div class="col-sm-2">
<div class="number">{{config.opacity}}</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-default" ng-class="{
active: reveal
}" ng-click="reveal = !reveal">真身模式</button>
</div>
</div>
</div>
</div>
</body>
</html>
/* Put your css in here */
.demo-wrap {
overflow: hidden;
}
.demo {
position: relative;
/* overflow: hidden; */
width: 100%;
height: 100px;
}
.demo .yt-progress {
transform-origin: 100.1% 50%;
}
.reveal .demo .yt-progress dd,
.reveal .demo .yt-progress dt {
background-color: white;
opacity: 1 !important;
}
.yt-progress {
position: absolute;
top: 50%; right: 30px;
width: 100%;
height: 2px;
background: #b91f1f;
border-radius: 1px;
transition: width 500ms ease-out, opacity 400ms linear;
}
.yt-progress dd, .yt-progress dt {
position: absolute;
top: 0;
height: 2px;
box-shadow: #b91f1f 1px 0 6px 1px;
border-radius: 100%;
opacity: .6;
}
.number {
padding: 8px;
text-align: center;
font-size: 24px;
}
<div class="yt-progress">
<dt ng-style="{
'box-shadow': '#b91f1f 1px 0 '+ config.blurRadius +'px 1px',
'right': tailRight +'px',
'clip': tailClip,
'width': tailWidth +'px',
'opacity': config.opacity
}"></dt>
<dd ng-style="{
'box-shadow': '#b91f1f 1px 0 '+ config.blurRadius +'px 1px',
'right': headRight + 'px',
'clip': headClip,
'width': headWidth +'px',
'opacity': config.opacity
}"></dd>
</div>
angular.module('plunker')
.directive('ytProgress', function () {
function clip(c) {
var clipStr = [c.top, c.right, c.bottom, c.left].map(function (v) {
return v + 'px';
}).join(',')
return 'rect(' + clipStr + ')';
}
return {
restrict: 'EA',
scope: {
config: '='
},
replace: true,
templateUrl: 'yt-progress.tmpl.html',
link: function (scope, iElm, iAttrs) {
scope.$watch('config', function (config) {
scope.headWidth = config.width * (config.ratio / 100) * 2;
scope.tailWidth = config.width * 2 - scope.headWidth;
scope.headClip = clip({
top: -config.blurRadius,
right: scope.headWidth + Number(config.blurRadius),
left: scope.headWidth / 2,
bottom: config.blurRadius * (14 / 6)
});
scope.tailClip = clip({
top: -config.blurRadius,
left: 0 - config.blurRadius,
right: scope.tailWidth / 2,
bottom: config.blurRadius * (14 / 6)
});
scope.headRight = 0;
scope.tailRight = -(scope.tailWidth - scope.headWidth) / 2;
}, true);
}
};
});