我正在努力填补像进度条一样的弧线,因为我在使用CSS时效果不佳。
我偶然发现了这个:https://codepen.io/enslavedeagle/pen/AXzaKE
#arc,
#arc::before {
display: block;
box-sizing: border-box;
border-radius: 100%;
width: 100px;
height: 100px;
position: absolute;
background-color: transparent;
padding: 0;
margin: 0;
}
#arc {
border: solid #00BBEE 12px;
clip: rect(0px, 100px, 50px, 0px);
margin: 25px;
}
#arc::before {
content: '';
border: solid black 12px;
top: -12px;
left: -12px;
clip: rect(0px, 100px, 50px, 0px);
transform: rotate(-150deg);
/* define the fill length, using the rotation above.
from -180deg (0% fill) to 0deg (100% fill) */
/* if you have a better solution to make thing like this
work, please let me know! :) */
}
并尝试自定义为我想要的但是直到现在还没有成功:在这里:https://codepen.io/anon/pen/qpNrEP
任何人都可以提供一些帮助吗?也可以替代解决方案来实现这一目标。
我很欣赏
亲切的问候,
答案 0 :(得分:1)
您可以在另一个上面使用带有两个弧的SVG,然后使用stroke-dash-array
。
svg {
height: 90vh;
margin: auto;
display: block;
}
path {
stroke-linecap: round;
stroke-width: 2;
}
path.grey {
stroke: lightgrey;
}
path.purple {
stroke: purple;
stroke-dasharray: calc(40 * 3.142 * 1.85);
stroke-dashoffset: 20;
/* adjust last number for variance */
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 100 100">
<path class="grey" d="M40,90
A40,40 0 1,1 60,90"
style="fill:none;"/>
<path class="purple" d="M40,90
A40,40 0 1,1 60,90"
style="fill:none;"/>
</svg>
答案 1 :(得分:1)
使用 SVG 是创建这样的弧的最佳方式。 这是加载器所有迭代的解决方案:
.progress-wrapper {
height: 100vh;
display: flex;
align-items: center;
justify-content: space-around;
}
path {
stroke-linecap: round;
stroke-width: 6;
}
.grey {
stroke: #e5e5e5;
}
.red {
stroke: #e33800;
stroke-dasharray: 248;
stroke-dashoffset: 240;
/* adjust last number for variance */
}
.red-02 {
stroke-dashoffset: 220;
}
.red-03 {
stroke-dashoffset: 200;
}
.red-04 {
stroke-dashoffset: 180;
}
.red-05 {
stroke-dashoffset: 160;
}
.red-06 {
stroke-dashoffset: 140;
}
.red-07 {
stroke-dashoffset: 120;
}
.red-08 {
stroke-dashoffset: 100;
}
.red-09 {
stroke-dashoffset: 50;
}
.red-10 {
stroke-dashoffset: 0;
}
<div class="progress-wrapper">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red red-02" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red red-03" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red red-04" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red red-05" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red red-06" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red red-07" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red red-08" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red red-09" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
<path class="grey" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
<path class="red red-10" d="M55,90
A55,55 0 1,1 140,90"
style="fill:none;"/>
</svg>
</div>
答案 2 :(得分:0)
这是一个使用SVG创建循环进度条的Angular模块。看起来正是您正在寻找的。 p>
回购: https://github.com/crisbeto/angular-svg-round-progressbar
演示: http://crisbeto.github.io/angular-svg-round-progressbar/
答案 3 :(得分:0)
我刚刚在Angular 2中创建了一个plnker,我认为这正是你想要的。
它用变量管理第二个弧的填充:
this.percentPath=(233-(V*2.33)); //233 is the maximun number stroke-dashoffset needs to disapear the second path
然后,在组件中我调用一个函数,该函数从min = 0和max = 100的滑块中获取值:
private static final String TAG = "EmailPassword";
private TextView mStatusTextView;
private TextView mDetailTextView;
private EditText mEmailField;
private EditText mPasswordField;
// [START declare_auth]
private FirebaseAuth mAuth;
// [END declare_auth]
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.auth_email_password);
// Views
mStatusTextView = findViewById(R.id.status);
mDetailTextView = findViewById(R.id.detail);
mEmailField = findViewById(R.id.field_email);
mPasswordField = findViewById(R.id.field_password);
// Buttons
findViewById(R.id.email_sign_in_button).setOnClickListener(this);
findViewById(R.id.email_create_account_button).setOnClickListener(this);
findViewById(R.id.sign_out_button).setOnClickListener(this);
findViewById(R.id.verify_email_button).setOnClickListener(this);
// [START initialize_auth]
mAuth = FirebaseAuth.getInstance();
// [END initialize_auth]
}
// [START on_start_check_user]
@Override
public void onStart() {
super.onStart();
// Check if user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
updateUI(currentUser);
}
// [END on_start_check_user]
private void createAccount(String email, String password) {
Log.d(TAG, "createAccount:" + email);
if (!validateForm()) {
return;
}
showProgressDialog();
// [START create_user_with_email]
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "createUserWithEmail:success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "createUserWithEmail:failure", task.getException());
Toast.makeText(EmailAuthActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
// [START_EXCLUDE]
hideProgressDialog();
// [END_EXCLUDE]
}
});
// [END create_user_with_email]
}
private void signIn(String email, String password) {
Log.d(TAG, "signIn:" + email);
if (!validateForm()) {
return;
}
showProgressDialog();
// [START sign_in_with_email]
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithEmail:success");
FirebaseUser user = mAuth.getCurrentUser();
updateUI(user);
} else {
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithEmail:failure", task.getException());
Toast.makeText(EmailAuthActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
updateUI(null);
}
// [START_EXCLUDE]
if (!task.isSuccessful()) {
mStatusTextView.setText(R.string.auth_failed);
}
hideProgressDialog();
// [END_EXCLUDE]
}
});
// [END sign_in_with_email]
}
private void signOut() {
mAuth.signOut();
updateUI(null);
}
private void sendEmailVerification() {
// Disable button
findViewById(R.id.verify_email_button).setEnabled(false);
// Send verification email
// [START send_email_verification]
final FirebaseUser user = mAuth.getCurrentUser();
user.sendEmailVerification()
.addOnCompleteListener(this, new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
// [START_EXCLUDE]
// Re-enable button
findViewById(R.id.verify_email_button).setEnabled(true);
if (task.isSuccessful()) {
Toast.makeText(EmailAuthActivity.this,
"Verification email sent to " + user.getEmail(),
Toast.LENGTH_SHORT).show();
} else {
Log.e(TAG, "sendEmailVerification", task.getException());
Toast.makeText(EmailAuthActivity.this,
"Failed to send verification email.",
Toast.LENGTH_SHORT).show();
}
// [END_EXCLUDE]
}
});
// [END send_email_verification]
}
private boolean validateForm() {
boolean valid = true;
String email = mEmailField.getText().toString();
if (TextUtils.isEmpty(email)) {
mEmailField.setError("Required.");
valid = false;
} else {
mEmailField.setError(null);
}
String password = mPasswordField.getText().toString();
if (TextUtils.isEmpty(password)) {
mPasswordField.setError("Required.");
valid = false;
} else {
mPasswordField.setError(null);
}
return valid;
}
private void updateUI(FirebaseUser user) {
hideProgressDialog();
if (user != null) {
mStatusTextView.setText(getString(R.string.emailpassword_status_fmt,
user.getEmail(), user.isEmailVerified()));
mDetailTextView.setText(getString(R.string.firebase_status_fmt, user.getUid()));
findViewById(R.id.email_password_buttons).setVisibility(View.GONE);
findViewById(R.id.email_password_fields).setVisibility(View.GONE);
findViewById(R.id.signed_in_buttons).setVisibility(View.VISIBLE);
findViewById(R.id.verify_email_button).setEnabled(!user.isEmailVerified());
} else {
mStatusTextView.setText(R.string.signed_out);
mDetailTextView.setText(null);
findViewById(R.id.email_password_buttons).setVisibility(View.VISIBLE);
findViewById(R.id.email_password_fields).setVisibility(View.VISIBLE);
findViewById(R.id.signed_in_buttons).setVisibility(View.GONE);
}
}
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.email_create_account_button) {
createAccount(mEmailField.getText().toString(), mPasswordField.getText().toString());
} else if (i == R.id.email_sign_in_button) {
signIn(mEmailField.getText().toString(), mPasswordField.getText().toString());
} else if (i == R.id.sign_out_button) {
signOut();
} else if (i == R.id.verify_email_button) {
sendEmailVerification();
}
}
看看吧!
答案 4 :(得分:0)
找不到答案后,我自己在这里做了一些工作,并制作了一个Codepen,您可以使用它制作与您所描述的输入完全相同的进度条:圆的度数为100%,圆弧的半径和要填充的百分比。 Progress bar example (image)
HTML:
let url = "https://.....someAudioFile.mp3"
let source
const getRecordingData = url => {
let request = new XMLHttpRequest()
request.open('GET', url, true)
request.responseType = 'arraybuffer'
request.send()
request.onload = function() {
let audioCtx = new (window.AudioContext || window.webkitAudioContext)()
audioCtx.decodeAudioData(
request.response,
function onSuccess(decodedBuffer) {
// Decoding was successful
source = audioCtx.createBufferSource()
source.buffer = decodedBuffer
source.connect(audioCtx.destination)
source.loop = false
source.start(0)
},
function onFailure(e) {
console.log('Error with decoding audio data' + e.err)
}
)
}
}
getRecordingData(url)
CSS:
<section class="stat" id="sectionId">
<svg viewbox="0 0 100 100">
<path class="bar" d="
M 10, 50
a 40,40 0 1,0 80,0
a 40,40 0 1,0 -80,0
"/>
<path class="progress" d="
M 10, 50
a 40,40 0 1,0 80,0
a 40,40 0 1,0 -80,0
"/>
</svg>
<script type="text/javascript">
_.makeProgressBar("01", 240, 40, 86);
</script>
</section>
JS:
.stat {
width: 200px;
}
svg {
display: block;
transform-origin: center center;
transform: rotate( 90deg );
}
path {
stroke-linecap: round;
stroke-width: 6px ;
fill:none;
}